8#include "tpcclibConfig.h"
21static char *info[] = {
22 "Simulation of PET tissue time-radioactivity concentration curve (TTAC)",
23 "in [O-15]H2O PET studies from decay corrected arterial blood TAC based on",
24 "the one-tissue compartment model.",
26 "Usage: @P [options] bloodfile f p E Vb fA simfile",
28 "Perfusion (f) must be given in units mL/(min*100 mL), partition coefficient",
29 "(p) in units mL/mL, and vascular volume (Vb) and the arterial fraction of it",
30 "(fA) as percentages.",
31 "By default, blood flow (perfusion) and tissue concentratios are",
32 "assumed to represented per PET volume (including vascular volume).",
33 "Extraction coefficient, E=1-exp(-PS/f), can usually be set to 1.0.",
34 "Blood sample times must be in seconds, unless specified in the file.",
35 "For accurate results, blood input TAC should be noiseless and have very",
36 "short sampling intervals. Simulated curves can thereafter be interpolated",
37 "to represent PET frames using program fr4sim.",
41 " TACs of sub-compartments are written (-sub)",
42 " or not written (-nosub, default) into the output file.",
44 " Simulated TACs are added to an existing tissue data file.",
45 " By default, existing file is overwritten.",
47 " Blood flow (perfusion) is assumed to be given per perfusable tissue",
48 " volume excluding vascular volume. TAC will still be simulated per",
49 " regional PET volume including vascular volume.",
51 " Enter a name (1-6 chars without spaces) for the simulated TAC",
53 " Save the simulated venous blood TAC",
56 "Simulated TACs are written in ASCII format with columns:",
57 " 1) Sample time (s)",
58 " 2) Total tissue activity concentration (Cpet)",
59 " 3) Activity concentration in tissue, (1-Vb)*Ct (optional)",
60 " 4) Arterial contribution to tissue activity, Vb*fA*Cab (optional)",
61 " 5) Venous contribution to tissue activity, Vb*(1-fA)*Cvb (optional)",
63 "See also: fit_h2o, sim_mbf, sim_3tcm, avgbolus, tacadd, simframe, tacunit",
65 "Keywords: TAC, simulation, modelling, perfusion, radiowater",
84int main(
int argc,
char **argv)
86 int ai, help=0, version=0, verbose=1;
88 int save_only_total=1;
89 int flow_per_tissue=0;
90 int add_to_previous=0;
92 char bfile[FILENAME_MAX], tfile[FILENAME_MAX], vfile[FILENAME_MAX];
94 double Flow, pH2O, E, Vb, fA, Va, Vv;
102 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
103 bfile[0]=tfile[0]=vfile[0]=voiname[0]=(char)0;
104 Flow=pH2O=E=Vb=fA=Va=Vv=-1.0;
107 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
108 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
110 if(strncasecmp(cptr,
"NOSUB", 5)==0) {
111 save_only_total=1;
continue;
112 }
else if(strncasecmp(cptr,
"SUB", 3)==0) {
113 save_only_total=0;
continue;
114 }
else if(strcasecmp(cptr,
"FPT")==0) {
115 flow_per_tissue=1;
continue;
116 }
else if(strcasecmp(cptr,
"ADD")==0) {
117 add_to_previous=1;
continue;
118 }
else if(strncasecmp(cptr,
"VOINAME=", 8)==0) {
121 fprintf(stderr,
"Error: invalid VOI name '%s'.\n", cptr+8);
return(1);}
123 }
else if(strncasecmp(cptr,
"VENA=", 5)==0) {
124 ret=
strlcpy(vfile, cptr+5, FILENAME_MAX);
125 if(ret<1 || ret>=FILENAME_MAX) {
126 fprintf(stderr,
"Error: invalid VOI name '%s'.\n", cptr+5);
return(1);}
129 fprintf(stderr,
"Error: invalid option '%s'\n", argv[ai]);
134 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
140 if(ai<argc) {
strlcpy(bfile, argv[ai], FILENAME_MAX); ai++;}
143 if(!(Flow>=0.0)) {fprintf(stderr,
"invalid f (%s).\n", argv[ai]);
return(1);}
148 if(!(pH2O>=0.0)) {fprintf(stderr,
"invalid pH2O (%s).\n", argv[ai]);
return(1);}
153 if(!(E>=0.0) || E>1.0) {fprintf(stderr,
"invalid E (%s).\n", argv[ai]);
return(1);}
158 if(!(Vb>=0.0) || Vb>1.0) {fprintf(stderr,
"invalid Vb (%s).\n", argv[ai]);
return(1);}
163 if(!(fA>=0.0) || fA>1.0) {fprintf(stderr,
"invalid fA (%s).\n", argv[ai]);
return(1);}
166 if(ai<argc) {
strlcpy(tfile, argv[ai], FILENAME_MAX); ai++;}
167 if(ai<argc) {fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
return(1);}
170 if(!tfile[0]) {
tpcPrintUsage(argv[0], info, stdout);
return(1);}
173 Va=fA*Vb; Vv=(1.0-fA)*Vb;
174 if(E<=0. || E>1. || Va<0. || Va>=1. || Vv<0. || Vv>=1. || Va+Vv>=1.) {
175 fprintf(stderr,
"Erroneous parameter values.\n");
182 printf(
"bfile := %s\n", bfile);
183 printf(
"tfile := %s\n", tfile);
184 printf(
"save_only_total := %d\n", save_only_total);
185 printf(
"flow_per_tissue := %d\n", flow_per_tissue);
186 printf(
"add_to_previous := %d\n", add_to_previous);
187 if(vfile[0]) printf(
"vfile := %s\n", vfile);
188 if(voiname[0]) printf(
"voiname := %s\n", voiname);
189 printf(
"Flow := %g\n", Flow);
190 printf(
"pH2O := %g\n", pH2O);
191 printf(
"E := %g\n", E);
192 printf(
"Vb := %g\n", Vb);
193 printf(
"fA := %g\n", fA);
194 printf(
"Va := %g\n", Va);
195 printf(
"Vv := %g\n", Vv);
202 if(verbose>1) printf(
"reading blood TAC in %s\n", bfile);
204 fprintf(stderr,
"Error in reading '%s': %s\n", bfile,
dfterrmsg);
208 fprintf(stderr,
"Error: too few samples in '%s'.\n", bfile);
212 fprintf(stderr,
"Warning: few samples in '%s'.\n", bfile);
215 fprintf(stderr,
"Error: blood data contains more than one curve.\n");
220 if(verbose>=0) printf(
"assuming that blood time unit is sec\n");
226 fprintf(stderr,
"Error: cannot convert blood data sample times to sec.\n");
237 if(verbose>1) printf(
"allocating memory for simulated TACs\n");
240 fprintf(stderr,
"Error in allocating memory for simulated data.\n");
246 for(fi=0; fi<dft.
frameNr; fi++) {
247 dft.
x[fi]=blood.
x[fi]; dft.
x1[fi]=blood.
x1[fi]; dft.
x2[fi]=blood.
x2[fi];
255 for(ri=0; ri<dft.
voiNr; ri++) {
259 if(strlen(voiname)==0) {
262 strcpy(dft.
voi[0].
name, voiname);
271 for(ri=1; ri<dft.
voiNr; ri++)
278 if(verbose>1) printf(
"simulating tissue data\n");
279 K1=Flow*E;
if(flow_per_tissue==0) K1/=(1.0-Va-Vv);
281 if(verbose>1) printf(
"K1 := %g\nk2 := %g\n", K1, k2);
283 dft.
voi[1].
y, NULL, NULL, NULL);
285 fprintf(stderr,
"Error %d in simulating tissue data.\n", ret);
288 if(verbose>2) printf(
"simulating PET curves\n");
289 for(fi=0; fi<dft.
frameNr; fi++) {
290 dft.
voi[2].
y[fi]=blood.
voi[0].
y[fi];
291 dft.
voi[3].
y[fi]=(1.0-E)*blood.
voi[0].
y[fi] + (E/pH2O)*dft.
voi[1].
y[fi];
299 if(verbose>0) printf(
"saving vena data in %s\n", vfile);
305 if(ret!=0 ||
dftWrite(&temp, vfile)!=0) {
306 fprintf(stderr,
"Error: cannot save vena data in %s\n", vfile);
307 if(verbose>1) fprintf(stderr,
"Error: %s\n",
dfterrmsg);
315 for(fi=0; fi<dft.
frameNr; fi++) {
316 dft.
voi[1].
y[fi]*=(1.0-Va-Vv);
317 dft.
voi[2].
y[fi]*=Va;
318 dft.
voi[3].
y[fi]*=Vv;
323 "# Flow := %g\n# pH2O :=%g\n# E := %g\n# Va := %g\n# Vv := %g\n",
324 Flow, pH2O, E, Va, Vv);
334 if(verbose>1) printf(
"saving PET curves\n");
336 if(save_only_total) dft.
voiNr=1;
344 if(add_to_previous!=0 && access(tfile, 0)!=-1) {
345 if(verbose>0) printf(
"adding to existing file\n");
350 fprintf(stderr,
"Error in reading '%s': %s\n", tfile,
dfterrmsg);
353 if(verbose>2) printf(
"existing %d TACs with %d frames\n",
356 for(ri=0; ri<dft.
voiNr; ri++) {
357 ret=
dftAdd(&prevdft, &dft, ri);
359 fprintf(stderr,
"Error: cannot add simulated TAC in %s\n", tfile);
372 fprintf(stderr,
"Error in writing '%s': %s\n", tfile,
dfterrmsg);
376 if(verbose>=0) fprintf(stdout,
"simulated TAC(s) written in %s\n", tfile);
double atof_dpi(char *str)
int dftdup(DFT *dft1, DFT *dft2)
void dftSetComments(DFT *dft)
int dftCopyvoi(DFT *data, int from, int to)
int dftSetmem(DFT *data, int frameNr, int voiNr)
int dftAdd(DFT *data1, DFT *data2, int voi)
int dftCopymainhdr(DFT *dft1, DFT *dft2)
int dftRead(char *filename, DFT *data)
int dftWrite(DFT *data, char *filename)
int dftTimeunitConversion(DFT *dft, int tunit)
char * filenameGetExtension(char *s)
Get the last extension of a filename.
Header file for libtpccurveio.
#define DFT_FORMAT_STANDARD
#define DFT_DECAY_CORRECTED
#define DFT_FORMAT_UNKNOWN
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
int rnameSplit(char *rname, char *name1, char *name2, char *name3, int max_name_len)
#define MAX_REGIONNAME_LEN
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)
#define MAX_REGIONSUBNAME_LEN
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
Header file for libtpcmodel.
int simC3s(double *t, double *ca, int nr, double k1, double k2, double k3, double k4, double k5, double k6, double *ct, double *cta, double *ctb, double *ctc)
char comments[_DFT_COMMENT_LEN+1]
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]