8#include "tpcclibConfig.h"
23static char *info[] = {
24 "Simulation of PET tissue time-radioactivity concentration curves (TAC) from",
25 "reference tissue TAC based on a selected reference tissue input compartment",
27 "Available reference tissue input models, and model parameters:",
28 " FRTM; (Full) reference tissue model; R1, k2, k3, BP [1]",
29 " SRTM: Simplified reference tissue model; R1, k2, BP [2]",
30 " RRTM: Reduced reference tissue model; R1, k2, k3 (k4=0)",
31 " TRTM: Transport-limited reference tissue model; R1, k2, k3 [3]",
33 "Usage: @P [options] parfile [reffile simfile]",
36 " -model=<FRTM|SRTM|RRTM|TRTM>",
37 " Select the model used to simulate the TACs; by default the model is",
38 " read from the parameter file.",
40 " TACs of sub-compartments (Cf and Cb) are also written (-sub) into",
41 " simfile, or not written (-nosub, default); effective only with FRTM.",
44 "To create a template parameter file, do not enter names for reference TAC",
45 "and simulated TACs, but give the model with option -model.",
48 "1. Cunningham VJ, Hume SP, Price GR, Ahier RG, Cremer JE, Jones AKP.",
49 " Compartmental analysis of diprenorphine binding to opiate receptors",
50 " in the rat in vivo and its comparison with equilibrium data in vitro.",
51 " J Cereb Blood Flow Metab 1991;11:1-9.",
52 "2. Lammertsma AA, Hume SP. Simplified reference tissue model for PET",
53 " receptor studies. NeuroImage 1996;4:153-158.",
54 "3. Herholz K, Lercher M, Wienhard K, Bauer B, Lenz O, Heiss W-D.",
55 " PET measurement of cerebral acetylcholine esterase activity without",
56 " blood sampling. Eur J Nucl Med 2001;28:472-477.",
58 "See also: sim_3tcm, fit_frtm, fit_srtm, fit_rrtm, fit_trtm, tacadd, simframe",
60 "Keywords: TAC, simulation, reference tissue, reference input",
85int main(
int argc,
char **argv)
87 int ai, help=0, version=0, verbose=1;
88 char reffile[FILENAME_MAX], simfile[FILENAME_MAX], parfile[FILENAME_MAX];
90 unsigned int model=0, parNr=0;
91 int save_only_total=1;
99 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
101 reffile[0]=simfile[0]=parfile[0]=(char)0;
103 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
105 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(!*cptr)
continue;
106 if(strncasecmp(cptr,
"MODEL=", 6)==0 && strlen(cptr)>7) {
111 if(model==0 && strcasecmp(cptr,
"RTCM")==0) model=
modelCodeIndex(
"FRTM");
112 if(model!=0)
continue;
113 fprintf(stderr,
"Error: invalid model selection.\n");
return(1);
114 }
else if(strncasecmp(cptr,
"SUB", 3)==0) {
115 save_only_total=0;
continue;
116 }
else if(strncasecmp(cptr,
"NOSUB", 3)==0) {
117 save_only_total=1;
continue;
119 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
128 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
133 for(; ai<argc; ai++) {
135 strlcpy(parfile, argv[ai], FILENAME_MAX);
continue;
136 }
else if(!reffile[0]) {
137 strlcpy(reffile, argv[ai], FILENAME_MAX);
continue;
138 }
else if(!simfile[0]) {
139 strlcpy(simfile, argv[ai], FILENAME_MAX);
continue;
141 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
147 fprintf(stderr,
"Error: missing parameter file; use option --help\n");
150 if(reffile[0] && !simfile[0]) {
151 fprintf(stderr,
"Error: missing filename for simulated TACs.\n");
158 if(model!=0) printf(
"model := %s\n",
modelCode(model));
159 printf(
"parfile := %s\n", parfile);
160 printf(
"reffile := %s\n", reffile);
161 printf(
"simfile := %s\n", simfile);
162 printf(
"save_only_total := %d\n", save_only_total);
171 if(model==0 || parNr==0) {
172 fprintf(stderr,
"Error: unknown simulation model; use option -model.\n");
177 fprintf(stderr,
"Error: cannot allocate memory for parameters.\n");
181 for(
int i=0; i<par.
tacNr; i++) {
182 sprintf(par.
r[i].
name,
"tac%d", 1+i);
196 for(
int i=1; i<par.
tacNr; i++) {
197 par.
r[i].
p[2]=2.0*par.
r[i-1].
p[2];
198 par.
r[i].
p[3]=2.0*par.
r[i-1].
p[3];
200 }
else if(!strcmp(
modelCode(model),
"SRTM")) {
203 for(
int i=1; i<par.
tacNr; i++) {
204 par.
r[i].
p[2]=2.0*par.
r[i-1].
p[2];
206 }
else if(!strcmp(
modelCode(model),
"RRTM") ||
211 for(
int i=1; i<par.
tacNr; i++) {
212 par.
r[i].
p[2]=2.0*par.
r[i-1].
p[2];
215 if(verbose>1) printf(
"writing %s\n", parfile);
216 FILE *fp; fp=fopen(parfile,
"w");
218 fprintf(stderr,
"Error: cannot open file for writing (%s)\n", parfile);
230 if(verbose>1) fprintf(stdout,
"reading %s\n", parfile);
231 if(
parRead(&par, parfile, &status)) {
232 fprintf(stderr,
"Error: %s (%s)\n",
errorMsg(status.
error), parfile);
238 if(model!=0)
for(
int i=0; i<par.
tacNr; i++) par.
r[i].
model=model;
240 for(
int i=0; i<par.
tacNr; i++) {
245 fprintf(stderr,
"Error: invalid parameters for selected model.\n");
262 fprintf(stderr,
"Error: invalid model for this simulation.\n");
267 fprintf(stderr,
"Error: required parameters not available.\n");
275 if(verbose>1) fprintf(stdout,
"reading %s\n", reffile);
276 ret=
tacRead(&tac, reffile, &status);
278 fprintf(stderr,
"Error: %s (%s)\n",
errorMsg(status.
error), reffile);
283 printf(
"tacNr := %d\n", tac.
tacNr);
284 printf(
"sampleNr := %d\n", tac.
sampleNr);
290 "Warning: reference file contains %d TACs; using the first.\n", tac.
tacNr);
294 fprintf(stderr,
"Error: too few samples in reference TAC.\n");
298 fprintf(stderr,
"Warning: too few samples for reliable simulation.\n");
304 n=par.
tacNr;
if(!save_only_total) n*=3;
306 printf(
"allocating memory for %d samples and %d TACs\n", tac.
sampleNr, n);
309 fprintf(stderr,
"Error: %s\n",
errorMsg(ret));
319 for(
int j=0; j<sim.
sampleNr; j++) sim.
x[j]=tac.
x[j];
324 if(verbose>1) printf(
"simulating\n");
327 double *py=tac.
c[0].
y;
328 double *pf, *pb, *pt;
329 double R1, k2, k3, k4, BP;
331 for(i=0; i<par.
tacNr; i++) {
332 if(verbose>2) printf(
"simulating %s\n", sim.
c[i].
name);
338 if(fabs(BP)>1.0E-50) k4=k3/BP;
else if(fabs(k4)>1.0E-50) BP=k3/k4;
339 if(verbose>3) {printf(
"R1 := %g\n", R1); printf(
"k2 := %g\n", k2);}
341 pt=sim.
c[n].
y; pf=pb=NULL;
344 if(verbose>3) {printf(
"k3 := %g\n", k3); printf(
"k4 := %g\n", k4);}
345 if(!save_only_total) {
346 strcpy(sim.
c[n+1].
name, par.
r[i].
name); strcat(sim.
c[n+1].
name,
"_free");
348 strcpy(sim.
c[n+2].
name, par.
r[i].
name); strcat(sim.
c[n+2].
name,
"_bound");
352 if(save_only_total) n++;
else n+=3;
354 if(verbose>3) {printf(
"BP := %g\n", BP);}
358 if(verbose>3) {printf(
"k3 := %g\n", k3);}
362 if(verbose>3) {printf(
"k3 := %g\n", k3);}
367 fprintf(stderr,
"Error: invalid data for simulation.\n");
368 if(verbose>1) printf(
"sim_return_code := %d\n", ret);
391 if(verbose>1) printf(
"writing %s\n", simfile);
392 FILE *fp; fp=fopen(simfile,
"w");
394 fprintf(stderr,
"Error: cannot open file for writing (%s)\n", simfile);
400 fprintf(stderr,
"Error (%d): %s\n", ret,
errorMsg(status.
error));
403 if(verbose>=0) printf(
"%s saved.\n", simfile);
int iftPut(IFT *ift, const char *key, const char *value, char comment, TPCSTATUS *status)
int iftFindKey(IFT *ift, const char *key, int start_index)
char * modelCode(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 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 simTRTM(double *t, double *cr, const int nr, const double R1, const double k2, const double k3, double *ct)
int simRTCM(double *t, double *cr, const int nr, const double R1, const double k2, const double k3, const double k4, double *ct, double *cta, double *ctb)
int simSRTM(double *t, double *cr, const int nr, const double R1, const double k2, const double BP, double *ct)
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)
IFT h
Optional (but often useful) header information.
char name[MAX_PARNAME_LEN+1]
char name[MAX_TACNAME_LEN+1]
char name[MAX_TACNAME_LEN+1]
IFT h
Optional (but often useful) header information.
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
int tacAllocate(TAC *tac, int sampleNr, int tacNr)
int tacRead(TAC *d, const char *fname, TPCSTATUS *status)
char * tacFormattxt(tacformat c)
int tacWrite(TAC *tac, FILE *fp, tacformat format, int extra, 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).
char * unitName(int unit_code)
Header file for library libtpcift.
Header file for libtpcpar.
@ PAR_FORMAT_CSV_UK
UK CSV.
@ PAR_FORMAT_TSV_UK
UK TSV (point as decimal separator).
Header file for library libtpctac.
@ TAC_FORMAT_UNKNOWN
Unknown format.