10#include "tpcclibConfig.h"
25static char *info[] = {
26 "Simulation of radiowater PET time-radioactivity concentration curves (TACs)",
27 "for myocardial muscle and LV cavity based on MBF model by Iida et al (1, 2)",
28 "as represented in ref 3.",
30 "Usage: @P [options] bloodfile MBF PTF Va Beta simfile",
33 " -pH2O=<Partition coefficient for water>",
34 " Enter the partition coefficient of water; 0.9464 by default.",
36 " TAC of perfusbale tissue (Ct) is written (-sub)",
37 " or not written (-nosub, default) into the simfile.",
40 "MBF must be given in units mL/(mL*min), and PTF and Va as fractions.",
41 "TACs of regional muscle, LV cavity, and optionally perfusable tissue are ",
42 "written in the given simfile, overwriting any previous contents.",
44 "For accurate results, blood input TAC should be noiseless and have very",
45 "short sampling intervals. Simulated curves can thereafter",
46 "be interpolated to represent PET frames using program simframe.",
49 " @P s3456ab.bld 1.24 0.6 0.3 0.8 s3456sim.tac",
52 "1. Iida H, Rhodes CG, de Silva R, Yamamoto Y, Araujo LI, Maseri A, Jones T.",
53 " Myocardial tissue fraction - correction for partial volume effects and",
54 " measure of tissue viability. J Nucl Med 1991; 32:2169-2175.",
55 "2. Iida H, Rhodes CG, de Silva R, Araujo LI, Bloomfield P, Lammertsma AA,",
56 " Jones T. Use of the left ventricular time-activity curve as a noninvasive",
57 " input function in dynamic oxygen-15-water positron emission tomography.",
58 " J Nucl Med 1992; 33:1669-1677.",
59 "3. Oikonen V. Model equations for myocardial perfusion studies with [15O]H2O",
60 " PET. https://www.turkupetcentre.net/reports/tpcmod0005.pdf",
62 "See also: fitmbf, b2t_h2o, sim_3tcm, tacadd, simframe, simimyoc",
64 "Keywords: simulation, myocardium, perfusion, radiowater",
83int main(
int argc,
char **argv)
85 int ai, help=0, version=0, verbose=1;
86 char blofile[FILENAME_MAX], simfile[FILENAME_MAX];
87 double PTF=-1.0, MBF=-1.0, Beta=-1.0, Va=-1.0, pc=0.9464;
97 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
98 blofile[0]=simfile[0]=(char)0;
100 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
102 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(!*cptr)
continue;
103 if(strncasecmp(cptr,
"P=", 2)==0) {
104 pc=
atofVerified(cptr+2);
if(pc>0.0 && pc<=1.0)
continue;
105 }
else if(strncasecmp(cptr,
"PH2O=", 5)==0) {
106 pc=
atofVerified(cptr+5);
if(pc>0.0 && pc<=1.0)
continue;
107 }
else if(strncasecmp(cptr,
"NOSUB", 5)==0) {
109 }
else if(strncasecmp(cptr,
"SUB", 3)==0) {
112 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
121 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
126 if(ai<argc) {
strlcpy(blofile, argv[ai++], FILENAME_MAX);}
129 if(MBF<0.0 || MBF>20.0) {
130 fprintf(stderr,
"Error: invalid MBF (%g).\n", MBF);
return(1);}
134 if(PTF<=0.0 || PTF>1.0) {
135 fprintf(stderr,
"Error: invalid PTF (%g).\n", PTF);
return(1);}
139 if(Va<0.0 || Va>1.0) {
140 fprintf(stderr,
"Error: invalid Va (%g).\n", Va);
return(1);}
144 if(Beta<=0.0 || Beta>1.0) {
145 fprintf(stderr,
"Error: invalid Beta (%g).\n", Beta);
return(1);}
147 if(ai<argc) {
strlcpy(simfile, argv[ai++], FILENAME_MAX);}
150 fprintf(stderr,
"Error: too many arguments: '%s'.\n", argv[ai]);
155 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
161 printf(
"blofile := %s\n", blofile);
162 printf(
"simfile := %s\n", simfile);
163 printf(
"MBF := %g\n", MBF);
164 printf(
"PTF := %g\n", PTF);
165 printf(
"Va := %g\n", Va);
166 printf(
"Beta := %g\n", Beta);
167 printf(
"pH2O := %g\n", pc);
174 if(verbose>1) fprintf(stdout,
"reading %s\n", blofile);
176 ret=
tacRead(&input, blofile, &status);
178 fprintf(stderr,
"Error: %s (%s)\n",
errorMsg(status.
error), blofile);
183 printf(
"tacNr := %d\n", input.
tacNr);
184 printf(
"sampleNr := %d\n", input.
sampleNr);
190 "Warning: input file contains %d TACs; using the first.\n", input.
tacNr);
194 fprintf(stderr,
"Error: too few samples in input TAC.\n");
198 fprintf(stderr,
"Warning: too few samples for reliable simulation.\n");
203 if(verbose>1) printf(
"Note: assuming that times are in seconds.\n");
206 if(verbose>1) printf(
"Note: assuming that times are in minutes.\n");
223 printf(
"allocating memory for %d samples and %d TACs\n", input.
sampleNr, n);
226 fprintf(stderr,
"Error: %s\n",
errorMsg(ret));
236 for(
int j=0; j<sim.
sampleNr; j++) sim.
x[j]=input.
x[j];
237 strcpy(sim.
c[0].
name,
"muscle");
238 strcpy(sim.
c[1].
name,
"lvcav");
239 strcpy(sim.
c[2].
name,
"Ct");
245 if(verbose>1) printf(
"simulating\n");
248 fprintf(stderr,
"Error: cannot simulate TTAC.\n");
249 if(verbose>1) printf(
"ret := %d\n", ret);
258 sim.
c[0].
y[i] = PTF*sim.
c[2].
y[i] + Va*input.
c[0].
y[i];
260 sim.
c[1].
y[i] = Beta*input.
c[0].
y[i] + (1.0-Beta)*sim.
c[2].
y[i];
276 if(verbose>1) printf(
"writing %s\n", simfile);
277 if(save_ct==0) sim.
tacNr=2;
278 FILE *fp; fp=fopen(simfile,
"w");
280 fprintf(stderr,
"Error: cannot open file for writing (%s)\n", simfile);
286 fprintf(stderr,
"Error (%d): %s\n", ret,
errorMsg(status.
error));
289 if(verbose>=0) printf(
"%s saved.\n", simfile);
double atofVerified(const char *s)
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)
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_TACNAME_LEN+1]
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)
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_UNKNOWN
Unknown unit.
char * unitName(int unit_code)
Header file for library libtpcift.
Header file for libtpcpar.
Header file for library libtpctac.
@ TAC_FORMAT_UNKNOWN
Unknown format.