8#include "tpcclibConfig.h"
22static char *info[] = {
23 "Simulates the [O-15]H2O BTAC from [O-15]O2 BTAC applying a dedicated",
24 "[O-15]O2 metabolite model (1, 2, 3).",
26 "Usage: @P [Options] otacfile parameterfile wtacfile",
31 "Model parameters for k3 model (k1, k1+k3, delay) or k4 model (k1, k3,",
32 "k3/k4, delay) can be given in a RES or IFT file made by program fit_o2bl.",
33 "Parameters and data units are assumed to be in seconds, in case units",
34 "are not given in the files.",
38 "1. Huang S-C et al. Modelling approach for separating blood time-activity",
39 " curves in positron emission tomographic studies.",
40 " Phys Med Biol. 1991;36(6):749-761.",
41 "2. Iida H et al. Modelling approach to eliminate the need to separate",
42 " arterial plasma in oxygen-15 inhalation positron emission tomography.",
43 " J Nucl Med. 1993;34:1333-1340.",
44 "3. Kudomi N et al. A physiologic model for recirculation water correction",
45 " in CMRO2 assessment with 15O2 inhalation PET.",
46 " J Cereb Blood Flow Metab. 2009;29(2):355-364.",
48 "See also: fit_o2bl, o2metab, o2_p2w, fit_mo2, b2t_mo2, taccalc, tac2svg",
50 "Keywords: input, oxygen, blood, metabolite correction",
69int main(
int argc,
char **argv)
71 int ai, help=0, version=0, verbose=1;
73 char oxyfile[FILENAME_MAX], parfile[FILENAME_MAX], watfile[FILENAME_MAX];
74 double k1, k2, k3, k4, delay, k3k4, k1k3;
83 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
85 parfile[0]=oxyfile[0]=watfile[0]=(char)0;
86 k1=k2=k3=k4=k3k4=k1k3=nan(
""); delay=0.0;
88 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
91 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
96 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
101 for(; ai<argc; ai++) {
102 if(!oxyfile[0]) {
strlcpy(oxyfile, argv[ai], FILENAME_MAX);
continue;}
103 if(!parfile[0]) {
strlcpy(parfile, argv[ai], FILENAME_MAX);
continue;}
104 if(!watfile[0]) {
strlcpy(watfile, argv[ai], FILENAME_MAX);
continue;}
105 fprintf(stderr,
"Error: too many arguments: '%s'.\n", argv[ai]);
111 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
117 printf(
"oxyfile := %s\n", oxyfile);
118 printf(
"parfile := %s\n", parfile);
119 printf(
"watfile := %s\n", watfile);
123 if(verbose>1) printf(
"reading parameters in %s\n", parfile);
125 if(
resRead(parfile, &res, verbose-2)==0) {
126 if(verbose>2) printf(
"result format\n");
127 ret=
res2ift(&res, &ift, verbose-3);
130 fprintf(stderr,
"Error in converting results.\n");
135 }
else if(
iftRead(&ift, parfile, 1, 0)==0) {
136 if(verbose>2) printf(
"ift format\n");
138 fprintf(stderr,
"Error: cannot read '%s'\n", parfile);
143 int i, n;
char key[12];
double v;
int u;
char buf1[128], buf2[128];
145 strcpy(key,
"k1"); i=
iftGet(&ift, key, 0);
147 fprintf(stderr,
"Error: k1 not found in '%s'.\n", parfile);
151 n=sscanf(ift.
item[i].
value,
"%128s %128s", buf1, buf2);
153 fprintf(stderr,
"Error: valid k1 not found in '%s'.\n", parfile);
157 if(n>1) {u=
petCunitId(buf2);
if(u==CUNIT_PER_MIN) v/=60.0;}
158 k1=v;
if(verbose>2) printf(
"k1 := %g\n", k1);
160 strcpy(key,
"delay"); i=
iftGet(&ift, key, 0);
161 if(i<0) {strcpy(key,
"delayt"); i=
iftGet(&ift, key, 0);}
162 if(i<0) {strcpy(key,
"timedelay"); i=
iftGet(&ift, key, 0);}
164 n=sscanf(ift.
item[i].
value,
"%128s %128s", buf1, buf2);
166 fprintf(stderr,
"Error: valid delay not found in '%s'.\n", parfile);
170 if(n>1) {u=
petTunitId(buf2);
if(u==TUNIT_MIN) v*=60.0;}
171 delay=v;
if(verbose>2) printf(
"delay := %g\n", k1);
174 strcpy(key,
"k3"); i=
iftGet(&ift, key, 0);
176 n=sscanf(ift.
item[i].
value,
"%128s %128s", buf1, buf2);
178 if(n>1) {u=
petCunitId(buf2);
if(u==CUNIT_PER_MIN) v/=60.0;}
179 k3=v;
if(verbose>2) printf(
"k3 := %g\n", k3);
183 strcpy(key,
"k3/k4"); i=
iftGet(&ift, key, 0);
185 n=sscanf(ift.
item[i].
value,
"%128s %128s", buf1, buf2);
187 k3k4=v;
if(verbose>2) printf(
"k3/k4 := %g\n", k3k4);
191 strcpy(key,
"k1+k3"); i=
iftGet(&ift, key, 0);
193 n=sscanf(ift.
item[i].
value,
"%128s %128s", buf1, buf2);
195 if(n>1) {u=
petCunitId(buf2);
if(u==CUNIT_PER_MIN) v/=60.0;}
196 k1k3=v;
if(verbose>2) printf(
"k1+k3 := %g\n", k1k3);
201 if(isnan(k3) && isnan(k1k3)) {
202 fprintf(stderr,
"Error: missing k3 or k1+k3 in '%s'.\n", parfile);
208 fprintf(stderr,
"Error: missing k3/k4 in '%s'.\n", parfile);
212 if(k3k4<=1.0E-100) k4=0.0;
else k4=k3/k3k4;
214 if(isnan(k3)) {k3=k1k3-k1; k4=0.0;}
216 printf(
"k2 := %g\n", k2);
217 printf(
"k3 := %g\n", k3);
218 printf(
"k4 := %g\n", k4);
220 if(k1<0.0 || k3<0.0 || k4<0.0) {
221 fprintf(stderr,
"Error: invalid parameter value(s) in '%s'.\n", parfile);
231 if(verbose>1) printf(
"reading %s\n", oxyfile);
233 fprintf(stderr,
"Error in reading '%s': %s\n", oxyfile,
dfterrmsg);
238 fprintf(stderr,
"Warning: input file contains extra column(s).\n");
241 fprintf(stderr,
"Error: blood data not valid.\n");
248 fprintf(stderr,
"Warning: assuming that BTAC sample times are in minutes.\n");
259 if(
dftdup(&blood, &sim)) {
260 fprintf(stderr,
"Error: cannot allocate memory for simulated TACs.\n");
269 if(verbose>1) printf(
"simulating\n");
271 blood.
voi[0].
y2, blood.
voi[0].
y3, NULL, NULL);
273 fprintf(stderr,
"Error in simulation of metabolism (%d).\n", ret);
277 for(
int i=0; i<blood.
frameNr; i++) blood.
x1[i]=blood.
x[i]+delay;
282 fprintf(stderr,
"Error in simulation of delay (%d).\n", ret);
286 if(verbose>1) printf(
"writing O15-water TAC in %s\n", watfile);
291 fprintf(stderr,
"Error in writing '%s': %s\n", watfile,
dfterrmsg);
294 if(verbose==1) printf(
"O15-water BTAC written in %s\n", watfile);
int atof_with_check(char *double_as_string, double *result_value)
int dftdup(DFT *dft1, DFT *dft2)
int dftRead(char *filename, DFT *data)
int dftWrite(DFT *data, char *filename)
void dftSec2min(DFT *dft)
void dftMin2sec(DFT *dft)
int iftRead(IFT *ift, char *filename, int is_key_required, int verbose)
int iftGet(IFT *ift, char *key, int verbose)
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.
int resRead(char *filename, RES *res, int verbose)
int res2ift(RES *res, IFT *ift, int verbose)
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
int petCunitId(const char *unit)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
int tpcHtmlUsage(const char *program, char *text[], const char *path)
int petTunitId(const char *timeunit)
void tpcPrintBuild(const char *program, FILE *fp)
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 voiname[MAX_REGIONSUBNAME_LEN+1]
char name[MAX_REGIONNAME_LEN+1]
char hemisphere[MAX_REGIONSUBNAME_LEN+1]
char place[MAX_REGIONSUBNAME_LEN+1]