8#include "tpcclibConfig.h"
27#define DEFAULT_LC 1.00
29#ifndef DEFAULT_DENSITY
30#define DEFAULT_DENSITY 1.00
35static char *info[] = {
36 "Calculates of Fractional Uptake Rate (FUR) or FUR-based Metabolic Rate (MR)",
37 "image from static or dynamic PET image in ECAT 6.3 or 7.2, NIfTI, or",
38 "Analyze 7.5 format. Information on FUR in:",
39 "https://www.turkupetcentre.net/petanalysis/model_fur.html",
41 "Usage: @P [Options] inputfile image starttime endtime furimage",
43 "FUR calculation start and stop time must be entered in minutes;",
44 "set both to zero to use the whole time range from image data.",
48 " Concentration of native substrate in arterial plasma (mM),",
49 " for example plasma glucose in [18F]FDG studies.",
50 " With this option the metabolic rate (umol/(min*100 g)) is calculated.",
52 " Lumped Constant in MR calculation; default is 1.0.",
54 " Tissue density in MR calculation; default is 1.0 g/ml.",
57 "Example 1. Calculation of FUR image from a dynamic image from 45 to 60 min:",
58 " @P ua2918ap.kbq ua2918dy1.v 45 60 ua2918fur.v",
60 "Example 2. Calculation of glucose uptake image, when tissue density is 1.04,",
61 "plasma glucose concentration is 5.2 mM, lumped constant is 0.52, from",
62 "a static (one frame) image:",
63 " @P -density=1.04 -Ca=5.2 -LC=0.52 a864ap.kbq a864dy1.v 0 0 a864mrglu.v",
65 "The unit of pixel values in the FUR image is",
66 "(mL plasma)/(min*(mL tissue)) by default, and umol/(min*100 g) in metabolic",
69 "See also: imgki, imginteg, imgcalc, ecattime, img2tif, regfur",
71 "Keywords: image, modelling, FUR, retention index, irreversible uptake",
90int main(
int argc,
char **argv)
92 int ai, help=0, version=0, verbose=1;
94 char inpfile[FILENAME_MAX], petfile[FILENAME_MAX], outfile[FILENAME_MAX];
95 char tmp[1024], *cptr;
98 double startTime=-1.0, endTime=-1.0;
99 double LC=-1.0, Ca=-1.0, density=-1.0;
105 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
106 inpfile[0]=petfile[0]=outfile[0]=(char)0;
110 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
112 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
113 if(strncasecmp(cptr,
"CA=", 3)==0) {
114 Ca=
atof_dpi(cptr+3);
if(Ca>0.0)
continue;
115 }
else if(strncasecmp(cptr,
"LC=", 3)==0) {
116 LC=
atof_dpi(cptr+3);
if(LC>0.0)
continue;
117 }
else if(strncasecmp(cptr,
"D=", 2)==0) {
118 density=
atof_dpi(cptr+2);
if(density>0.0)
continue;
119 }
else if(strncasecmp(cptr,
"DENSITY=", 8)==0) {
120 density=
atof_dpi(cptr+8);
if(density>0.0)
continue;
122 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
127 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
132 for(; ai<argc; ai++) {
134 strcpy(inpfile, argv[ai]);
continue;
135 }
else if(!petfile[0]) {
136 strcpy(petfile, argv[ai]);
continue;
137 }
else if(startTime<0.0) {
138 startTime=
atof_dpi(argv[ai]);
if(startTime<0.0) startTime=0.0;
140 }
else if(endTime<0.0) {
141 endTime=
atof_dpi(argv[ai]);
if(endTime<0.0) endTime=0.0;
143 }
else if(!outfile[0]) {
144 strcpy(outfile, argv[ai]);
continue;
146 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
152 fprintf(stderr,
"Error: missing result file name.\n");
159 fprintf(stderr,
"Warning: LC not set, using default %g\n", LC);
162 density=DEFAULT_DENSITY;
163 fprintf(stderr,
"Warning: tissue density not set, using default %g\n",
167 if(LC>0.0) fprintf(stderr,
"Warning: LC was set but is not used.\n");
169 fprintf(stderr,
"Warning: tissue density was set but is not used.\n");
172 if(endTime<startTime) {
173 fprintf(stderr,
"Error: invalid time range.\n");
176 if(startTime==endTime && startTime>0.5) {
177 startTime-=0.5; endTime+=0.5;
183 printf(
"inpfile := %s\n", inpfile);
184 printf(
"petfile := %s\n", petfile);
185 printf(
"outfile := %s\n", outfile);
187 printf(
"startTime := %g min\n", startTime);
188 printf(
"endTime := %g min\n", endTime);
191 printf(
"Ca := %g\n", Ca);
192 printf(
"LC := %g\n", LC);
193 printf(
"density := %g\n", density);
202 if(verbose>0) fprintf(stdout,
"reading image %s\n", petfile);
205 fprintf(stderr,
"Error: %s\n", img.
statmsg);
if(verbose>1)
imgInfo(&img);
209 if(verbose>0) fprintf(stderr,
"Warning: missing pixel values.\n");
212 fprintf(stderr,
"Error: %s is not an image.\n", petfile);
217 fprintf(stderr,
"Error: %s does not contain frame times.\n", petfile);
223 if(verbose>1) fprintf(stdout,
"checking frame overlap in %s\n", petfile);
226 fprintf(stderr,
"Error: image %s has overlapping frame times.\n", petfile);
236 if(img.
unit==IMGUNIT_UNKNOWN) {
237 img.
unit=IMGUNIT_KBQ_PER_ML;
238 fprintf(stderr,
"Warning: image calibration unit assumed to be %s.\n",
245 startTime=img.
start[0]/60.0;
246 endTime=img.
end[img.
dimt-1]/60.0;
248 printf(
"startTime := %g min\n", startTime);
249 printf(
"endTime := %g min\n", endTime);
256 if(verbose>1) fprintf(stdout,
"calculating average image\n");
260 fprintf(stderr,
"Error: %s.\n", tmp);
263 if(verbose>1) fprintf(stdout,
"%s.\n", tmp);
272 if(verbose>1) printf(
"Reading input file %s\n", inpfile);
274 fprintf(stderr,
"Error in reading '%s': %s\n", inpfile,
dfterrmsg);
278 fprintf(stderr,
"Warning: only first TAC is used as input.\n");
282 fprintf(stderr,
"Error: missing values in %s\n", inpfile);
287 if(ret) fprintf(stderr,
"Warning: check that input times are in minutes.\n");
293 if(ret==0) {
if(verbose>0) fprintf(stdout,
"%s\n", tmp);
294 }
else if(ret<0) {fprintf(stderr,
"Warning: %s\n", tmp);
296 fprintf(stderr,
"Error: %s.\n", tmp);
303 if(verbose>1) printf(
"calculating input AUC\n");
304 ret=
dftTimeIntegral(&input, 0.0, 0.5*(startTime+endTime), &auc, 0, tmp,
307 fprintf(stderr,
"Error: %s.\n", tmp);
308 if(verbose>1) printf(
"error_code := %d\n", ret);
312 printf(
"AUC[%g-%g] := %g\n", auc.
x1[0], auc.
x2[0], auc.
voi[0].
y[0]);
323 fprintf(stderr,
"Error: cannot calculate of FUR.\n");
327 out.
unit=IMGUNIT_PER_MIN;
338 MRf=100.*Ca/(density*LC);
340 fprintf(stdout,
"converting FUR to metabolic rate with factor %g\n", MRf);
343 fprintf(stderr,
"Error: cannot calculate metabolic rate.\n");
346 out.
unit=IMGUNIT_UMOL_PER_MIN_PER_100G;
354 fprintf(stderr,
"Error: %s\n", tmp);
357 if(verbose>0) printf(
"%s\n", tmp);
360 fprintf(stderr,
"Error: %s\n", out.
statmsg);
364 if(Ca<=0.0) fprintf(stdout,
"FUR image %s saved.\n", outfile);
365 else fprintf(stdout,
"MR image %s saved.\n", outfile);
int backupExistingFile(char *filename, char *backup_ext, char *status)
double atof_dpi(char *str)
int dft_nr_of_NA(DFT *dft)
int dftTimeIntegral(DFT *dft, double t1, double t2, DFT *idft, int calc_mode, char *status, int verbose)
int dftRead(char *filename, DFT *data)
int dftTimeunitConversion(DFT *dft, int tunit)
int imgExistentTimes(IMG *img)
unsigned long long imgNaNs(IMG *img, int fix)
void imgEmpty(IMG *image)
int imgArithmConst(IMG *img, float operand, char operation, float ulimit, int verbose)
int imgRead(const char *fname, IMG *img)
int imgWrite(const char *fname, IMG *img)
int imgDeleteFrameOverlap(IMG *img)
char * imgUnit(int dunit)
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)
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.
int imgTimeIntegral(IMG *img, float t1, float t2, IMG *iimg, int calc_mode, char *status, int verbose)
int cunit_check_dft_vs_img(DFT *dft, IMG *img, char *errmsg, int verbose)