9#include "tpcclibConfig.h"
24static char *info[] = {
25 "Subtracts the contribution of vascular radioactivity from regional",
26 "PET TTACs. Vascular volume fraction Vb can be given as a value that is",
27 "common to all regions, or as regional Vb values in a TAC file, calculated",
28 "from a [O-15]CO study.",
30 "Usage: @P ttacfile btacfile Vb outputfile",
34 " Negative TAC values are set to 0.",
36 " Equation Ct=Cpet-Vb*Cb is applied by default or with option -pv;",
37 " with option -tv equation Ct=(Cpet-Vb*Cb)/(1-Vb) is applied.",
39 " Simulate the contribution of vascular radioactivity instead of",
40 " correcting for it, calculating Cpet from Ct using equations above.",
44 " @P uo372.tac uo372ab.bld 0.045 uo372cbv.tac",
46 " @P uo372.dft uo372ab.kbq uo372vb.dft uo372cbv.dft",
48 "Vb values that are >=1.0 are assumed to be percentages.",
49 "Blood TAC can be given in a separate BTAC file, or as a region id inside",
52 "See also: imgcbv, p2blood, interpol, taccalc, tacformat",
54 "Keywords: TAC, modelling, vascular fraction, simulation",
73int main(
int argc,
char **argv)
75 int ai, help=0, version=0, verbose=1;
77 int leave_negat=1, pet_volume=1, add_vb=0;
78 char infile[FILENAME_MAX], blfile[FILENAME_MAX], outfile[FILENAME_MAX],
79 *cptr, vbfile[FILENAME_MAX], tmp[256];
81 double vb=-1.0, t1, t2;
87 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
88 infile[0]=outfile[0]=blfile[0]=vbfile[0]=(char)0;
91 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
92 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
94 if(strncasecmp(cptr,
"NONEGATIVES", 1)==0) {
95 leave_negat=0;
continue;
96 }
else if(strncasecmp(cptr,
"PV", 1)==0) {
97 pet_volume=1;
continue;
98 }
else if(strncasecmp(cptr,
"TV", 1)==0) {
99 pet_volume=0;
continue;
100 }
else if(strncasecmp(cptr,
"SIMULATE", 3)==0) {
103 fprintf(stderr,
"Error: unknown option '%s'.\n", argv[ai]);
108 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
113 for(; ai<argc; ai++) {
114 if(!infile[0]) {
strlcpy(infile, argv[ai], FILENAME_MAX);
continue;}
115 else if(!blfile[0]) {
strlcpy(blfile, argv[ai], FILENAME_MAX);
continue;}
116 else if(!vbfile[0] && vb<0.0) {
117 if(access(argv[ai], 0)==0) {
118 strlcpy(vbfile, argv[ai], FILENAME_MAX);
continue;
121 if(ret==0) {
if(vb>=1.0) vb/=100.;
if(vb>=0.0)
continue;}
122 fprintf(stderr,
"Error: invalid Vb: '%s'.\n", argv[ai]);
125 else if(!outfile[0]) {
strlcpy(outfile, argv[ai], FILENAME_MAX);
continue;}
126 fprintf(stderr,
"Error: too many arguments: '%s'.\n", argv[ai]);
132 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
139 printf(
"infile := %s\n", infile);
140 printf(
"blfile := %s\n", blfile);
141 printf(
"vbfile := %s\n", vbfile);
142 printf(
"pet_volume := %d\n", pet_volume);
143 printf(
"vb := %g\n", vb);
144 printf(
"leave_negat := %d\n", leave_negat);
145 printf(
"add_vb := %d\n", add_vb);
149 printf(
"\napplying formula:\n");
151 if(pet_volume==0) printf(
"Ct=(Cpet-Vb*Cb)/(1-Vb)\n");
152 else printf(
"Ct=Cpet-Vb*Cb\n");
154 if(pet_volume==0) printf(
"Cpet=(1-Vb)*Ct+Vb*Cb\n");
155 else printf(
"Cpet=Ct+Vb*Cb\n");
163 if(verbose>1) printf(
"reading %s\n", infile);
165 fprintf(stderr,
"Error in reading '%s': %s\n", infile,
dfterrmsg);
172 if(verbose>1) printf(
"reading %s\n", blfile);
173 ret=
dftReadinput(&blood, &dft, blfile, &ri, &t1, &t2, 0, tmp, verbose-3);
175 fprintf(stderr,
"Error in reading '%s': %s\n", blfile, tmp);
178 if(verbose>2) printf(
"blood_filetype := %d\n", ri);
181 fprintf(stderr,
"Warning: blood TAC is clearly shorter than tissue TAC.\n");
188 if(verbose>1) printf(
"reading %s\n", vbfile);
190 fprintf(stderr,
"Error in reading '%s': %s\n", vbfile,
dfterrmsg);
194 fprintf(stderr,
"Error: Vb file contains more than one sample time.\n");
202 for(ri=0; ri<dft.
voiNr; ri++) {
211 fprintf(stderr,
"Error: Vb file does not contain the same regions.\n");
215 for(ri=ret=0; ri<tdft.
voiNr; ri++)
if(tdft.
voi[ri].
y[0]>=1.0) ret=1;
217 for(ri=0; ri<tdft.
voiNr; ri++) tdft.
voi[ri].
y[0]/=100.;
218 for(ri=ret=0; ri<tdft.
voiNr; ri++)
if(tdft.
voi[ri].
y[0]>=1.0) ret=1;
220 fprintf(stderr,
"Error: invalid contents in Vb file.\n");
223 fprintf(stderr,
"Warning: Vb values were converted to fractions.\n");
232 if(verbose>1) printf(
"subtracting blood\n");
233 for(ri=0; ri<dft.
voiNr; ri++) {
235 vb=tdft.
voi[ri].
y[0];
236 if(verbose>2) printf(
"Vb=%g for %s\n", vb, dft.
voi[ri].
name);
238 for(fi=0; fi<dft.
frameNr; fi++) {
240 if(!isnan(dft.
voi[ri].
y2[fi])) {
241 dft.
voi[ri].
y2[fi]-=vb*blood.
voi[0].
y[fi];
242 if(pet_volume==0) dft.
voi[ri].
y2[fi]/=(1.0-vb);
243 if(leave_negat==0 && dft.
voi[ri].
y2[fi]<0.0) dft.
voi[ri].
y2[fi]=0.0;
248 if(verbose>1) printf(
"adding blood\n");
249 for(ri=0; ri<dft.
voiNr; ri++) {
251 vb=tdft.
voi[ri].
y[0];
252 if(verbose>2) printf(
"Vb=%g for %s\n", vb, dft.
voi[ri].
name);
254 for(fi=0; fi<dft.
frameNr; fi++) {
256 if(!isnan(dft.
voi[ri].
y2[fi])) {
257 if(pet_volume==0) dft.
voi[ri].
y2[fi]*=(1.0-vb);
258 dft.
voi[ri].
y2[fi]+=vb*blood.
voi[0].
y[fi];
259 if(leave_negat==0 && dft.
voi[ri].
y2[fi]<0.0) dft.
voi[ri].
y2[fi]=0.0;
270 if(verbose>1) printf(
"writing %s\n", outfile);
271 for(ri=0; ri<dft.
voiNr; ri++)
for(fi=0; fi<dft.
frameNr; fi++)
275 fprintf(stderr,
"Error (%d) in writing '%s': %s\n", ret, outfile,
dfterrmsg);
279 if(verbose>0) printf(
" %s written.\n", outfile);
int atof_with_check(char *double_as_string, double *result_value)
int dftRead(char *filename, DFT *data)
int dftWrite(DFT *data, char *filename)
Header file for libtpccurveio.
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.
char voiname[MAX_REGIONSUBNAME_LEN+1]
char name[MAX_REGIONNAME_LEN+1]
char hemisphere[MAX_REGIONSUBNAME_LEN+1]
char place[MAX_REGIONSUBNAME_LEN+1]