10#include "tpcclibConfig.h"
23static char *info[] = {
24 "Deprecated, use sim_3tcm instead.",
26 "Simulation of PET tissue time-radioactivity concentration curve (TAC)",
27 "from arterial plasma (Ca) and blood (Cb) TACs, based on three-tissue",
28 "compartmental model, where the compartments are in series (default):",
30 " ____ K1 ____ k3 ____ k5 ____ ",
31 " | Ca | ----> | C1 | ----> | C2 | ----> | C3 | ",
32 " |____| <---- |____| <---- |____| <---- |____| ",
35 " dC1(t)/dt = K1*Ca(T) - (k2+k3)*C1(T) + k4*C2(T) ",
36 " dC2(t)/dt = k3*C1(T) - (k4+k5)*C2(T) + k6*C3(T) ",
37 " dC3(t)/dt = k5*C2(T) - k6*C3(T) ",
38 " Ct(T) = C1(T) + C2(T) + C3(T) ",
39 " Cvb(T) = Cab(T) - dCt(t)/dt / f ",
40 " Cpet(T)= Vb*fA*Cab(T) + Vb*(1-fA)*Cvb(T) + (1-Vb)*Ct(T) ",
42 ", or, optionally, three-tissue compartmental model, where the 2nd and 3rd",
43 "tissue compartments are parallel, often used to represent specific and",
44 "non-specific binding:",
46 " ____ K1 ____ k3 ____ ",
47 " | Ca | ----> | C1 | ----> | C2 | ",
48 " |____| <---- |____| <---- |____| ",
57 " dC1(t)/dt = K1*Ca(T) - (k2+k3+k5)*C1(T) + k4*C2(T) + k6*C3(T) ",
58 " dC2(t)/dt = k3*C1(T) - k4*C2(T) ",
59 " dC3(t)/dt = k5*C1(T) - k6*C3(T) ",
60 " Ct(T) = C1(T) + C2(T) + C3(T) ",
61 " Cvb(T) = Cab(T) - dCt(t)/dt / f ",
62 " Cpet(T)= Vb*fA*Cab(T) + Vb*(1-fA)*Cvb(T) + (1-Vb)*Ct(T) ",
64 "Usage: @P [options] plasmafile bloodfile K1 k2 k3 k4 k5 k6 f Vb fA simfile",
68 " Model with parallel compartments C2 and C3 is applied.",
70 " Model with compartments C1, C2, and C3 in series is applied (default).",
72 " TACs of sub-compartments (C1, C2 and C3) are written (-sub, default)",
73 " or not written (-nosub) into the simfile.",
76 "Enter blood flow (f) in units (ml/(min*ml)); set f=0 to assume that f>>K1",
77 "and Cvb=Cab. Enter the vascular volume fraction (Vb) and its arterial",
78 "fraction (fA) as percentages.",
79 "If the times in input files are in seconds, the units of rate constants",
80 "(k's) and blood flow (f) must also be specified as 1/sec.",
81 "For accurate results, plasma TAC should have very short sampling intervals.",
82 "To reduce the model, k5 or k3 can be set to 0.",
85 " @P -nosub plasma.dat blood.dat 0.3 0.2 0.1 0.2 0 0 0.6 5 30 sim.dat",
87 "Simulated TACs are written in ASCII format with columns:",
89 " 2) Total tissue activity concentration (Cpet)",
90 " 3) Activity concentration in 1st tissue compartment, (1-Vb)*C1",
91 " 4) Activity concentration in 2nd tissue compartment, (1-Vb)*C2",
92 " 5) Activity concentration in 3rd tissue compartment, (1-Vb)*C3",
93 " 6) Arterial contribution to tissue activity, Vb*fA*Cab",
94 " 7) Venous contribution to tissue activity, Vb*(1-fA)*Cvb",
99 "See also: sim_3tcm, p2t_3c, p2t_di, tacadd, tacren, simframe, dft2img",
101 "Keywords: TAC, simulation, modelling, compartmental model",
120int main(
int argc,
char **argv)
122 int ai, help=0, version=0, verbose=1;
125 int save_only_total=0;
128 double k1, k2, k3, k4, k5, k6, f, Vb, fA;
129 double *t, *ca, *cab, *cpet, *ct1, *ct2, *ct3, *ctab, *ctvb;
130 char pfile[FILENAME_MAX], bfile[FILENAME_MAX], sfile[FILENAME_MAX];
131 char tmp[FILENAME_MAX+128], *cptr;
138 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
140 pfile[0]=bfile[0]=sfile[0]=(char)0;
141 k1=k2=k3=k4=k5=k6=f=Vb=fA=-1.0;
143 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
146 if(strncasecmp(cptr,
"NOSUB", 5)==0) {
147 save_only_total=1;
continue;
148 }
else if(strncasecmp(cptr,
"SUB", 3)==0) {
149 save_only_total=0;
continue;
150 }
else if(strncasecmp(cptr,
"PARALLEL", 5)==0) {
151 parallel=1;
continue;
152 }
else if(strncasecmp(cptr,
"SERIES", 3)==0) {
153 parallel=0;
continue;
155 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
160 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
165 for(; ai<argc; ai++) {
167 strcpy(pfile, argv[ai]);
continue;
168 }
else if(!bfile[0]) {
169 strcpy(bfile, argv[ai]);
continue;
171 k1=
atof_dpi(argv[ai]);
if(k1>0.0)
continue;
173 k2=
atof_dpi(argv[ai]);
if(k2>=0.0)
continue;
175 k3=
atof_dpi(argv[ai]);
if(k3>=0.0)
continue;
177 k4=
atof_dpi(argv[ai]);
if(k4>=0.0)
continue;
179 k5=
atof_dpi(argv[ai]);
if(k5>=0.0)
continue;
181 k6=
atof_dpi(argv[ai]);
if(k6>=0.0)
continue;
183 f=
atof_dpi(argv[ai]);
if(f>=0.0)
continue;
185 Vb=0.01*
atof_dpi(argv[ai]);
if(Vb<0.0) Vb=0.0;
continue;
187 fA=0.01*
atof_dpi(argv[ai]);
if(fA<1.0E-012) fA=0.0;
continue;
188 }
else if(!sfile[0]) {
189 strcpy(sfile, argv[ai]);
continue;
191 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
197 if(!sfile[0]) {
tpcPrintUsage(argv[0], info, stdout);
return(1);}
198 if(k1<=0.0) {fprintf(stderr,
"Error: k1 must be > 0.\n");
return(1);}
200 fprintf(stderr,
"Error: f cannot be lower than K1!\n");
return(1);}
201 if(Vb>=1.0 || fA<=0.0 || fA>1.0) {
202 fprintf(stderr,
"Error: invalid value of Vb!\n");
return(1);}
203 if(fA<=0.0 || fA>1.0) {
204 fprintf(stderr,
"Error: invalid value of fA!\n");
return(1);}
205 if(k1>1.0E+08 || k2>1.0E+08 || k3>1.0E+08 || k4>1.0E+08 ||
206 k5>1.0E+08 || k6>1.0E+08) {
207 fprintf(stderr,
"Error: too high rate constant.\n");
return(1);
212 printf(
"pfile := %s\n", pfile);
213 printf(
"bfile := %s\n", bfile);
214 printf(
"sfile := %s\n", sfile);
215 printf(
"parameters := %g %g %g %g %g %g\n", k1, k2, k3, k4, k5, k6);
216 printf(
"f := %g\n", f);
217 printf(
"Vb := %g\n", Vb);
218 printf(
"fA := %g\n", fA);
219 printf(
"save_only_total := %d\n", save_only_total);
220 printf(
"parallel := %d\n", parallel);
227 if(verbose>1) printf(
"reading plasma\n");
229 fprintf(stderr,
"Error in reading '%s': %s\n", pfile,
dfterrmsg);
234 fprintf(stderr,
"Error: too few samples in plasma data.\n");
238 fprintf(stderr,
"Error: plasma data contains more than one curve.\n");
241 if(plasma.
timeunit==TUNIT_UNKNOWN) {
243 if(verbose>=0) printf(
"assuming that time unit is min\n");
249 if(verbose) printf(
"reading blood\n");
251 fprintf(stderr,
"Error in reading '%s': %s\n", bfile,
dfterrmsg);
255 fprintf(stderr,
"Error: too few samples in blood data.\n");
259 fprintf(stderr,
"Error: blood data contains more than one curve.\n");
264 fprintf(stderr,
"Warning: blood TAC is much shorter than plasma TAC.\n");
268 fprintf(stderr,
"Error: cannot allocate memory for blood TAC.\n");
278 fprintf(stderr,
"Error: cannot interpolate blood data.\n");
287 if(verbose>1) printf(
"allocating memory\n");
292 "Error (%d): cannot allocate memory for simulated TACs.\n", ret);
298 for(fi=0; fi<sim.
frameNr; fi++) {
299 sim.
x[fi]=plasma.
x[fi];
300 sim.
x1[fi]=plasma.
x1[fi]; sim.
x2[fi]=plasma.
x2[fi];
303 for(ri=0; ri<sim.
voiNr; ri++) {
322 sim.
voi[ri].
size=100.0*(1.0-fA)*Vb;
332 if(verbose>1) printf(
"simulating\n");
333 t=sim.
x; ca=plasma.
voi[0].
y; cab=plasma.
voi[1].
y;
335 ctab=sim.
voi[4].
y; ctvb=sim.
voi[5].
y;
337 ret=
simC3vs(t, ca, cab, sim.
frameNr, k1, k2, k3, k4, k5, k6, f, Vb, fA,
338 cpet, ct1, ct2, ct3, ctab, ctvb);
340 ret=
simC3vp(t, ca, cab, sim.
frameNr, k1, k2, k3, k4, k5, k6, f, Vb, fA,
341 cpet, ct1, ct2, ct3, ctab, ctvb);
344 fprintf(stderr,
"Error (%d) in simulation.\n", ret);
352 if(verbose>1) printf(
"saving PET curves\n");
354 if(save_only_total) sim.
voiNr=1;
357 sprintf(tmp,
"# plasmafile := %s\n", pfile); strcat(sim.
comments, tmp);
358 sprintf(tmp,
"# bloodfile := %s\n", bfile); strcat(sim.
comments, tmp);
359 strcpy(tmp,
"# model := ");
360 if(parallel==0) strcat(tmp,
"C3VS\n");
else strcat(tmp,
"C3VP\n");
362 sprintf(tmp,
"# K1 := %g\n", k1); strcat(sim.
comments, tmp);
363 sprintf(tmp,
"# k2 := %g\n", k2); strcat(sim.
comments, tmp);
364 sprintf(tmp,
"# k3 := %g\n", k3); strcat(sim.
comments, tmp);
365 sprintf(tmp,
"# k4 := %g\n", k4); strcat(sim.
comments, tmp);
366 sprintf(tmp,
"# k5 := %g\n", k5); strcat(sim.
comments, tmp);
367 sprintf(tmp,
"# k6 := %g\n", k6); strcat(sim.
comments, tmp);
368 sprintf(tmp,
"# f := %g\n", f); strcat(sim.
comments, tmp);
369 sprintf(tmp,
"# Vb := %g [%%]\n", 100.0*Vb); strcat(sim.
comments, tmp);
370 sprintf(tmp,
"# fA := %g [%%]\n", 100.0*fA); strcat(sim.
comments, tmp);
379 fprintf(stderr,
"Error in writing '%s': %s\n", sfile,
dfterrmsg);
382 if(verbose>0) fprintf(stdout,
"simulated TAC(s) written in %s\n", sfile);
double atof_dpi(char *str)
int dftAddmem(DFT *dft, int voiNr)
void dftSetComments(DFT *dft)
int dftSetmem(DFT *data, int frameNr, int voiNr)
int dftCopymainhdr(DFT *dft1, DFT *dft2)
int dftRead(char *filename, DFT *data)
int dftWrite(DFT *data, char *filename)
char * filenameGetExtension(char *s)
Get the last extension of a filename.
int interpolate(double *x, double *y, int nr, double *newx, double *newy, double *newyi, double *newyii, int newnr)
Linear interpolation and integration.
Header file for libtpccurveio.
#define DFT_FORMAT_STANDARD
#define DFT_FORMAT_UNKNOWN
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.
int simC3vp(double *t, double *ca, double *cb, int nr, double k1, double k2, double k3, double k4, double k5, double k6, double f, double vb, double fa, double *cpet, double *cta, double *ctb, double *ctc, double *ctab, double *ctvb)
int simC3vs(double *t, double *ca, double *cb, int nr, double k1, double k2, double k3, double k4, double k5, double k6, double f, double vb, double fa, double *cpet, double *cta, double *ctb, double *ctc, double *ctab, double *ctvb)
char comments[_DFT_COMMENT_LEN+1]
char voiname[MAX_REGIONSUBNAME_LEN+1]
char name[MAX_REGIONNAME_LEN+1]
char hemisphere[MAX_REGIONSUBNAME_LEN+1]
char place[MAX_REGIONSUBNAME_LEN+1]