TPCCLIB
Loading...
Searching...
No Matches
p2t_3c.c
Go to the documentation of this file.
1
8/*****************************************************************************/
9#include "tpcclibConfig.h"
10/*****************************************************************************/
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <math.h>
15/*****************************************************************************/
16#include "libtpcmisc.h"
17#include "libtpcmodel.h"
18#include "libtpccurveio.h"
19/*****************************************************************************/
20
21/*****************************************************************************/
22static char *info[] = {
23 "Deprecated, use sim_3tcm instead.",
24 " ",
25 "Simulation of PET tissue time-radioactivity concentration curve (TAC)",
26 "from arterial plasma (Ca) TAC based on three-tissue compartmental model,",
27 "where the compartments are in series (default):"
28 " ",
29 " ____ K1 ____ k3 ____ k5 ____ ",
30 " | Ca | ----> | C1 | ----> | C2 | ----> | C3 | ",
31 " |____| <---- |____| <---- |____| <---- |____| ",
32 " k2 k4 k6 ",
33 " ",
34 " dC1(t)/dt = K1*Ca(T) - (k2+k3)*C1(T) + k4*C2(T) ",
35 " dC2(t)/dt = k3*C1(T) - (k4+k5)*C2(T) + k6*C3(T) ",
36 " dC3(t)/dt = k5*C2(T) - k6*C3(T) ",
37 " Ct(T) = C1(T) + C2(T) + C3(T) ",
38 " ",
39 ", or, optionally, three-tissue compartmental model, where the 2nd and 3rd",
40 "tissue compartments are parallel, often used to represent specific and",
41 "non-specific binding:",
42 " ",
43 " ____ K1 ____ k3 ____ ",
44 " | Ca | ----> | C1 | ----> | C2 | ",
45 " |____| <---- |____| <---- |____| ",
46 " k2 k4 ",
47 " | ^ ",
48 " k5 | | k6 ",
49 " v | ",
50 " ____ ",
51 " | C3 | ",
52 " |____| ",
53 " ",
54 " dC1(t)/dt = K1*Ca(T) - (k2+k3+k5)*C1(T) + k4*C2(T) + k6*C3(T) ",
55 " dC2(t)/dt = k3*C1(T) - k4*C2(T) ",
56 " dC3(t)/dt = k5*C1(T) - k6*C3(T) ",
57 " Ct(T) = C1(T) + C2(T) + C3(T) ",
58 " ",
59 "Usage: @P [options] plasmafile K1 k2 k3 k4 k5 k6 simfile",
60 " ",
61 "Options:",
62 " -paral[lel]",
63 " Model with parallel compartments C2 and C3 is applied.",
64 " -ser[ies]",
65 " Model with compartments C1, C2, and C3 in series is applied (default).",
66 " -sub | -nosub",
67 " TACs of sub-compartments (C1, C2 and C3) are written (-sub, default)",
68 " or not written (-nosub) into the simfile.",
69 " -stdoptions", // List standard options like --help, -v, etc
70 " ",
71 "Example:",
72 " @P -nosub plasma.dat 0.3 0.2 0.1 0.2 0 0 sim.dat",
73 " ",
74 "See also: sim_3tcm, p2t_v3c, p2t_di, tacadd, tacren, simframe, dft2img",
75 " ",
76 "Keywords: TAC, simulation, modelling, compartmental model",
77 0};
78/*****************************************************************************/
79
80/*****************************************************************************/
81/* Turn on the globbing of the command line, since it is disabled by default in
82 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
83 In Unix&Linux wildcard command line processing is enabled by default. */
84/*
85#undef _CRT_glob
86#define _CRT_glob -1
87*/
88int _dowildcard = -1;
89/*****************************************************************************/
90
91/*****************************************************************************/
95int main(int argc, char **argv)
96{
97 int ai, help=0, version=0, verbose=1;
98 int ret;
99 int fi, ri;
100 int save_only_total=0;
101 int parallel=0;
102 DFT plasma, sim;
103 double k1, k2, k3, k4, k5, k6, *t, *ca, *ct, *ct1, *ct2, *ct3;
104 char pfile[FILENAME_MAX], sfile[FILENAME_MAX], *cptr;
105 char tmp[FILENAME_MAX+128];
106
107
108
109 /*
110 * Get arguments
111 */
112 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
113 dftInit(&plasma); dftInit(&sim);
114 pfile[0]=sfile[0]=(char)0;
115 k1=k2=k3=k4=k5=k6=-1.0;
116 /* Options */
117 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
118 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
119 cptr=argv[ai]+1; if(!*cptr) continue;
120 if(strncasecmp(cptr, "NOSUB", 5)==0) {
121 save_only_total=1; continue;
122 } else if(strncasecmp(cptr, "SUB", 3)==0) {
123 save_only_total=0; continue;
124 } else if(strncasecmp(cptr, "PARALLEL", 5)==0) {
125 parallel=1; continue;
126 } else if(strncasecmp(cptr, "SERIES", 3)==0) {
127 parallel=0; continue;
128 }
129 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
130 return(1);
131 } else break;
132
133 /* Print help or version? */
134 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
135 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
136 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
137
138 /* Process other arguments, starting from the first non-option */
139 for(; ai<argc; ai++) {
140 if(!pfile[0]) {
141 strlcpy(pfile, argv[ai], FILENAME_MAX); continue;
142 } else if(k1<0.0) {
143 k1=atof_dpi(argv[ai]); if(k1>=0.0) continue;
144 } else if(k2<0.0) {
145 k2=atof_dpi(argv[ai]); if(k2>=0.0) continue;
146 } else if(k3<0.0) {
147 k3=atof_dpi(argv[ai]); if(k3>=0.0) continue;
148 } else if(k4<0.0) {
149 k4=atof_dpi(argv[ai]); if(k4>=0.0) continue;
150 } else if(k5<0.0) {
151 k5=atof_dpi(argv[ai]); if(k5>=0.0) continue;
152 } else if(k6<0.0) {
153 k6=atof_dpi(argv[ai]); if(k6>=0.0) continue;
154 } else if(!sfile[0]) {
155 strlcpy(sfile, argv[ai], FILENAME_MAX); continue;
156 } else {
157 fprintf(stderr, "Error: invalid argument '%s'.\n", argv[ai]);
158 return(1);
159 }
160 }
161
162 /* Is something missing? */
163 if(!sfile[0]) {tpcPrintUsage(argv[0], info, stdout); return(1);}
164 if(k1<=0.0) {fprintf(stderr, "Error: k1 must be > 0.\n"); return(1);}
165 if(k1>1.0E+08 || k2>1.0E+08 || k3>1.0E+08 || k4>1.0E+08 ||
166 k5>1.0E+08 || k6>1.0E+08) {
167 fprintf(stderr, "Error: too high rate constant.\n"); return(1);
168 }
169
170 /* In verbose mode print arguments and options */
171 if(verbose>1) {
172 printf("pfile := %s\n", pfile);
173 printf("sfile := %s\n", sfile);
174 printf("parameters := %g %g %g %g %g %g\n", k1, k2, k3, k4, k5, k6);
175 printf("save_only_total := %d\n", save_only_total);
176 printf("parallel := %d\n", parallel);
177 }
178
179
180 /*
181 * Read TAC data
182 */
183 if(verbose>1) printf("reading %s\n", pfile);
184 if(dftRead(pfile, &plasma)) {
185 fprintf(stderr, "Error in reading '%s': %s\n", pfile, dfterrmsg);
186 dftEmpty(&plasma);
187 return(2);
188 }
189 if(plasma.frameNr<3) {
190 fprintf(stderr, "Error: too few samples in plasma data.\n");
191 dftEmpty(&plasma); return(2);
192 }
193 if(plasma.voiNr>1) {
194 fprintf(stderr, "Error: plasma data contains more than one curve.\n");
195 dftEmpty(&plasma); return(2);
196 }
197
198 /*
199 * Allocate memory for simulated tissue data.
200 */
201 if(verbose>1) printf("allocating memory\n");
202 /* allocate */
203 ret=dftSetmem(&sim, plasma.frameNr, 4);
204 if(ret) {
205 fprintf(stderr,
206 "Error (%d): cannot allocate memory for simulated TACs.\n", ret);
207 dftEmpty(&plasma); return(3);
208 }
209 sim.frameNr=plasma.frameNr; sim.voiNr=4;
210 /* Copy times & header info */
211 dftCopymainhdr(&plasma, &sim);
212 for(fi=0; fi<sim.frameNr; fi++) {
213 sim.x[fi]=plasma.x[fi];
214 sim.x1[fi]=plasma.x1[fi]; sim.x2[fi]=plasma.x2[fi];
215 }
216 /* column headers */
217 for(ri=0; ri<sim.voiNr; ri++) {
218 sim.voi[ri].sw=0; sim.voi[ri].size=100.0;
219 switch(ri) {
220 case 0: strcpy(sim.voi[ri].voiname, "Ct"); break;
221 case 1: strcpy(sim.voi[ri].voiname, "C1"); break;
222 case 2: strcpy(sim.voi[ri].voiname, "C2"); break;
223 case 3: strcpy(sim.voi[ri].voiname, "C3"); break;
224 }
225 strcpy(sim.voi[ri].hemisphere, ""); strcpy(sim.voi[ri].place, "");
226 strcpy(sim.voi[ri].name, sim.voi[ri].voiname);
227 }
228
229
230 /*
231 * Simulate TACs
232 */
233 if(verbose>1) printf("simulating\n");
234 t=sim.x; ca=plasma.voi[0].y; ct=sim.voi[0].y;
235 ct1=sim.voi[1].y; ct2=sim.voi[2].y; ct3=sim.voi[3].y;
236 if(parallel==0)
237 ret=simC3s(t, ca, sim.frameNr, k1, k2, k3, k4, k5, k6, ct, ct1, ct2, ct3);
238 else
239 ret=simC3p(t, ca, sim.frameNr, k1, k2, k3, k4, k5, k6, ct, ct1, ct2, ct3);
240 dftEmpty(&plasma);
241 if(ret!=0) {
242 fprintf(stderr, "Error (%d) in simulation.\n", ret);
243 dftEmpty(&sim); return(8);
244 }
245
246
247 /*
248 * Save simulated TACs
249 */
250 if(verbose>1) printf("saving PET curves\n");
252 if(save_only_total) sim.voiNr=1;
253 /* Set comments */
254 dftSetComments(&sim);
255 sprintf(tmp, "# plasmafile := %s\n", pfile); strcat(sim.comments, tmp);
256 strcpy(tmp, "# model := ");
257 if(parallel==0) strcat(tmp, "C3S\n"); else strcat(tmp, "C3P\n");
258 strcat(sim.comments, tmp);
259 sprintf(tmp, "# K1 := %g\n", k1); strcat(sim.comments, tmp);
260 sprintf(tmp, "# k2 := %g\n", k2); strcat(sim.comments, tmp);
261 sprintf(tmp, "# k3 := %g\n", k3); strcat(sim.comments, tmp);
262 sprintf(tmp, "# k4 := %g\n", k4); strcat(sim.comments, tmp);
263 sprintf(tmp, "# k5 := %g\n", k5); strcat(sim.comments, tmp);
264 sprintf(tmp, "# k6 := %g\n", k6); strcat(sim.comments, tmp);
265 /* Set file format to PMOD, if extension is .tac */
266 if(!strcasecmp(filenameGetExtension(sfile), ".tac"))
268 /* Some format has to be set anyway, and simple format would lose information */
271 /* Write file */
272 if(dftWrite(&sim, sfile)) {
273 fprintf(stderr, "Error in writing '%s': %s\n", sfile, dfterrmsg);
274 dftEmpty(&sim); return(11);
275 }
276 if(verbose>0) fprintf(stdout, "simulated TAC(s) written in %s\n", sfile);
277 dftEmpty(&sim);
278
279 return(0);
280}
281/*****************************************************************************/
282
283/*****************************************************************************/
double atof_dpi(char *str)
Definition decpoint.c:59
void dftInit(DFT *data)
Definition dft.c:38
char dfterrmsg[64]
Definition dft.c:6
void dftSetComments(DFT *dft)
Definition dft.c:1326
int dftSetmem(DFT *data, int frameNr, int voiNr)
Definition dft.c:57
void dftEmpty(DFT *data)
Definition dft.c:20
int dftCopymainhdr(DFT *dft1, DFT *dft2)
Definition dft.c:561
int dftRead(char *filename, DFT *data)
Definition dftio.c:22
int DFT_NR_OF_DECIMALS
Definition dftio.c:13
int dftWrite(DFT *data, char *filename)
Definition dftio.c:594
char * filenameGetExtension(char *s)
Get the last extension of a filename.
Definition filename.c:139
Header file for libtpccurveio.
#define DFT_FORMAT_PMOD
#define DFT_FORMAT_STANDARD
#define DFT_FORMAT_PLAIN
#define DFT_FORMAT_UNKNOWN
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
Definition proginfo.c:40
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition strext.c:245
int tpcHtmlUsage(const char *program, char *text[], const char *path)
Definition proginfo.c:213
void tpcPrintBuild(const char *program, FILE *fp)
Definition proginfo.c:383
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
Definition proginfo.c:158
Header file for libtpcmodel.
int simC3p(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)
Definition simulate.c:136
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)
Definition simulate.c:27
int _type
Voi * voi
double * x1
char comments[_DFT_COMMENT_LEN+1]
int voiNr
double * x2
int frameNr
double * x
double size
char voiname[MAX_REGIONSUBNAME_LEN+1]
char sw
double * y
char name[MAX_REGIONNAME_LEN+1]
char hemisphere[MAX_REGIONSUBNAME_LEN+1]
char place[MAX_REGIONSUBNAME_LEN+1]