8#include "tpcclibConfig.h"
25static char *info[] = {
26 "Simulation of PET tissue time-radioactivity concentration curves (TACs)",
27 "from arterial blood (Ca) TACs, based on compartmental model for radiowater.",
28 "Model has two parameters, perfusion (blood flow, f) and partition",
29 "coefficient of water (p).",
30 "Delay (deltat) and dispersion (tau) of arterial input function (AIF),",
31 "perfusable tissue fraction (PTF), and arterial volume fraction (Va) can be",
32 "included in the simulation.",
34 " dAIF(t)/dt = (1/tau)*Ca(T-deltat) - (1/tau)*AIF(T-deltat) ",
35 " dCt(t)/dt = f*AIF(T) - (f/p)*Ct(T) ",
36 " Cpet(T)= PTF*Ct(T) + Va*AIF(T) ",
38 "Usage: @P [options] parfile [bloodfile simfile]",
43 "To create a template parameter file, do not enter names for input and",
45 "If parameter file does not contain units, then per min and per mL units",
46 "are assumed for f, p, PTF and Va, and seconds for deltat and tau.",
47 "For accurate results, blood TAC should have very short sampling intervals.",
49 "See also: b2t_h2o, sim_3tcm, fit_h2o, fit_wrlv, tacadd, simframe",
51 "Keywords: TAC, simulation, compartmental model, perfusion, radiowater",
70int main(
int argc,
char **argv)
72 int ai, help=0, version=0, verbose=1;
73 char blofile[FILENAME_MAX], simfile[FILENAME_MAX], parfile[FILENAME_MAX];
81 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
82 blofile[0]=simfile[0]=parfile[0]=(char)0;
85 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
87 char *cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(!*cptr)
continue;
88 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
97 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
102 if(ai<argc)
strlcpy(parfile, argv[ai++], FILENAME_MAX);
103 if(ai<argc)
strlcpy(blofile, argv[ai++], FILENAME_MAX);
104 if(ai<argc)
strlcpy(simfile, argv[ai++], FILENAME_MAX);
106 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
112 fprintf(stderr,
"Error: missing parameter file; use option --help\n");
115 if(blofile[0] && !simfile[0]) {
116 fprintf(stderr,
"Error: missing file name.\n");
120 fprintf(stderr,
"Error: missing file names.\n");
127 printf(
"parfile := %s\n", parfile);
128 printf(
"blofile := %s\n", blofile);
129 printf(
"simfile := %s\n", simfile);
143 fprintf(stderr,
"Error: cannot allocate memory for parameters.\n");
153 for(
int i=0; i<par.
tacNr; i++) {
154 sprintf(par.
r[i].
name,
"tac%d", 1+i);
186 if(verbose>1) printf(
"writing %s\n", parfile);
187 FILE *fp; fp=fopen(parfile,
"w");
189 fprintf(stderr,
"Error: cannot open file for writing (%s)\n", parfile);
195 fprintf(stderr,
"Error: cannot write %s\n", parfile);
198 if(verbose>=0) {printf(
"%s saved.\n", parfile); fflush(stdout);}
206 if(verbose>1) fprintf(stdout,
"reading %s\n", parfile);
207 if(
parRead(&par, parfile, &status)) {
208 fprintf(stderr,
"Error: %s (%s)\n",
errorMsg(status.
error), parfile);
214 for(
int i=0; i<par.
tacNr; i++) {
217 fprintf(stderr,
"Error: parameter file has invalid model '%s'.\n",
modelDesc(par.
r[i].
model));
222 fprintf(stderr,
"Error: invalid parameters for selected model.\n");
227 int i_deltaT=-1, i_tau=-1, i_f=-1, i_p=-1, i_PTF=-1, i_Va=-1;
238 fprintf(stderr,
"Error: required parameters not available.\n");
242 printf(
"parameter indices:\n");
243 printf(
" f=p[%d]\n", i_f);
244 printf(
" p=p[%d]\n", i_p);
245 printf(
" PTF=p[%d]\n", i_PTF);
246 printf(
" Va=p[%d]\n", i_Va);
247 printf(
" deltaT=p[%d]\n", i_deltaT);
248 printf(
" tau=p[%d]\n", i_tau);
256 if(verbose>1) fprintf(stdout,
"reading input TAC\n");
260 fprintf(stderr,
"Error: %s (input files)\n",
errorMsg(status.
error));
265 printf(
"tacNr := %d\n", input.
tacNr);
266 printf(
"sampleNr := %d\n", input.
sampleNr);
272 fprintf(stderr,
"Error: too few samples in input TAC.\n");
276 fprintf(stderr,
"Warning: too few samples for reliable simulation.\n"); fflush(stderr);
287 if(verbose>1) fprintf(stdout,
"allocating space for simulated TACs\n");
300 for(
int j=0; j<sim.
sampleNr; j++) sim.
x[j]=input.
x[j];
306 if(verbose>1) {printf(
"simulating...\n"); fflush(stdout);}
307 for(
int ri=0; ri<sim.
tacNr; ri++) {
308 if(verbose>2) {printf(
" %s\n", sim.
c[ri].
name); fflush(stdout);}
312 double deltaT=par.
r[ri].
p[i_deltaT];
314 if(verbose>4) printf(
" deltaT := %g s\n", deltaT);
316 double tau=par.
r[ri].
p[i_tau];
318 if(verbose>4) printf(
" tau := %g s\n", tau);
323 fprintf(stderr,
"Error: cannot add dispersion for '%s'.\n", sim.
c[ri].
name);
326 for(
int i=0; i<sim.
sampleNr; i++) buf2[i]=input.
x[i]+deltaT;
327 if(
liInterpolate(buf2, buf1, sim.
sampleNr, sim.
x, ca, NULL, NULL, sim.
sampleNr, 3, 1, 0)!=0) {
328 fprintf(stderr,
"Error: cannot add delay time for '%s'.\n", sim.
c[ri].
name);
333 double f=par.
r[ri].
p[i_f];
335 if(isfinite(cf)) f*=cf;
else f/=60.0;
336 if(verbose>4) printf(
" f := %g mL/(s*mL)\n", f);
338 fprintf(stderr,
"Error: invalid f for '%s'.\n", sim.
c[ri].
name);
342 double p=par.
r[ri].
p[i_p];
344 if(verbose>4) printf(
" p := %g mL/mL\n", p);
345 double k2=f/p;
if(!(k2>=0.0)) {
346 fprintf(stderr,
"Error: invalid k2=f/p for '%s'.\n", sim.
c[ri].
name);
351 fprintf(stderr,
"Error: cannot simulate '%s'.\n", sim.
c[ri].
name);
356 double PTF=par.
r[ri].
p[i_PTF];
358 if(verbose>4) printf(
" PTF := %g mL/mL\n", PTF);
360 fprintf(stderr,
"Error: invalid PTF for '%s'.\n", sim.
c[ri].
name);
363 for(
int i=0; i<sim.
sampleNr; i++) sim.
c[ri].
y[i]*=PTF;
366 double Va=par.
r[ri].
p[i_Va];
368 if(verbose>4) printf(
" Va := %g mL/mL\n", Va);
370 fprintf(stderr,
"Error: invalid Va for '%s'.\n", sim.
c[ri].
name);
373 for(
int i=0; i<sim.
sampleNr; i++) sim.
c[ri].
y[i]+=Va*ca[i];
383 if(verbose>1) printf(
"writing %s\n", simfile);
384 FILE *fp; fp=fopen(simfile,
"w");
386 fprintf(stderr,
"Error: cannot open file for writing (%s)\n", simfile);
392 fprintf(stderr,
"Error (%d): %s\n", ret,
errorMsg(status.
error));
395 if(verbose>=0) {printf(
"%s saved.\n", simfile); fflush(stdout);}
void doubleCopy(double *t, double *s, const unsigned int n)
int fileExist(const char *filename)
int liInterpolate(double *x, double *y, const int nr, double *newx, double *newy, double *newyi, double *newyii, const int newnr, const int se, const int ee, const int verbose)
Linear interpolation and/or integration with trapezoidal method.
char * modelCode(const unsigned int i)
char * modelDesc(const unsigned int i)
unsigned int modelParNr(const unsigned int code)
unsigned int modelCodeIndex(const char *s)
int parAllocate(PAR *par, int parNr, int tacNr)
int parWrite(PAR *par, FILE *fp, parformat format, int extra, TPCSTATUS *status)
int parRead(PAR *par, const char *fname, TPCSTATUS *status)
int parFindParameter(PAR *d, const char *par_name)
int tacAllocateWithPAR(TAC *tac, PAR *par, int sampleNr, TPCSTATUS *status)
Allocate TAC based on data in PAR.
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)
int simC1(double *t, double *ca, const int nr, const double k1, const double k2, double *ct)
int simDispersion(double *x, double *y, const int n, const double tau1, const double tau2, double *tmp)
void statusInit(TPCSTATUS *s)
char * errorMsg(tpcerror e)
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
char name[MAX_PARNAME_LEN+1]
char name[MAX_TACNAME_LEN+1]
char name[MAX_TACNAME_LEN+1]
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
char * tacFormattxt(tacformat c)
int tacWrite(TAC *tac, FILE *fp, tacformat format, int extra, TPCSTATUS *status)
int tacXUnitConvert(TAC *tac, const int u, TPCSTATUS *status)
Header file for libtpccm.
Header file for library libtpcextensions.
@ WEIGHTING_OFF
Not weighted or weights not available (weights for all included samples are 1.0).
@ UNIT_ML_PER_ML_MIN
mL/(mL*min)
@ UNIT_ML_PER_ML_SEC
mL/(mL*sec)
double unitConversionFactor(const int u1, const int u2)
char * unitName(int unit_code)
Header file for libtpcfileutil.
Header file for library libtpcift.
Header file for libtpcpar.
@ PAR_FORMAT_TSV_UK
UK TSV (point as decimal separator).
Header file for library libtpctac.
@ TAC_FORMAT_PMOD
PMOD TAC format.
Header file for libtpctacmod.