TPCCLIB
Loading...
Searching...
No Matches
fitk5.c
Go to the documentation of this file.
1
7/*****************************************************************************/
8#include "tpcclibConfig.h"
9/*****************************************************************************/
10#include <stdio.h>
11#include <stdlib.h>
12#include <math.h>
13#include <unistd.h>
14#include <string.h>
15#include <time.h>
16/*****************************************************************************/
17#include "libtpcmisc.h"
18#include "libtpcmodel.h"
19#include "libtpccurveio.h"
20#include "libtpcsvg.h"
21#include "libtpcmodext.h"
22/*****************************************************************************/
23
24/*****************************************************************************/
25const int parNr=6;
26DFT input, dft;
27double *petmeas, *petsim;
28double fVb=-1.0;
29double pmin[MAX_PARAMETERS], pmax[MAX_PARAMETERS];
30double fk1k2=-1.0, fk3k4=-1.0;
31int fitframeNr;
32double wss_wo_penalty=0.0;
34enum parameter {
35 CM_K1, CM_K1K2, CM_K3, CM_K3K4, CM_K5, CM_VB, CM_KI, CM_WSS, CM_AIC
36};
37/*****************************************************************************/
38/* Local functions */
39double func_sk5(int parNr, double *p, void*);
40double func_pk5(int parNr, double *p, void*);
41int resK1k2Median(char *filename, double *median, double *mean, char *msg);
42/*****************************************************************************/
43
44/*****************************************************************************/
45static char *info[] = {
46 "Non-linear fitting of irreversible three-tissue compartment model to plasma",
47 "input, blood, and tissue time-activity curves (PTAC, BTAC, and TTAC) to",
48 "estimate parameters K1, K1/k2, k3, k3/k4, k5, and Vb.",
49 " ",
50 "Model with two of tissue compartments in parallel:",
51 " _____ ____ ____ ",
52 " | | K1 | | k3 | | ",
53 " | Ca | ----> | | ----> | C2 | ",
54 " |_____| | | <---- |____| ",
55 " _____ | C1 | k4 ____ ",
56 " | | | | | | ",
57 " | Cv | <---- | | ----> | C3 | ",
58 " |_____| k2 |____| k5 |____| ",
59 " ",
60 "Model with compartments in series:",
61 " _____ ____ ____ ____ ",
62 " | | K1 | | k3 | | k5 | | ",
63 " | Ca | ----> | | ----> | C2 | ----> | C3 | ",
64 " |_____| | | <---- |____| |____| ",
65 " _____ | C1 | k4 ",
66 " | | | | ",
67 " | Cv | <---- | | ",
68 " |_____| k2 |____| ",
69 " ",
70 "Sample times must be in minutes.",
71 " ",
72 "Usage: @P [Options] ptacfile btacfile ttacfile endtime resultfile",
73 " ",
74 "Options:",
75 " -lim[=<filename>]",
76 " Specify the constraints for model parameters;",
77 " This file with default values can be created by giving this",
78 " option as the only command-line argument to this program.",
79 " Without file name the default values are printed on screen.",
80 " -SD[=<y|N>]",
81 " Standard deviations are estimated and saved in results (y),",
82 " or not calculated (N, default).",
83 " Program runs a lot faster if SD and CL are not calculated.",
84 " -CL[=<y|N>]",
85 " 95% Confidence limits are estimated and saved in results (y), or",
86 " not calculated (N, default).",
87 " -model=<parallel|series>",
88 " Specify the model that is fitted to data; compartments in parallel",
89 " (default) or in series.",
90 " -Vb=<Vb(%)>",
91 " Enter a fixed Vb; fitted by default.",
92 " -fk1k2=<<value> || <result filename>>",
93 " K1/k2 is constrained to the given value in all regions; if result",
94 " file name is entered, then K1/k2 is constrained to the median of",
95 " regional K1/k2 values in the result file.",
96/* Not tested, thus commented out
97 Also, it might be more useful to use this option to fix k3/k4, at least
98 in parallel model...
99 " -r=<Reference region id or filename>",
100 " Optional reference region is used to constrain K1/k2 in other regions;",
101 " with option -rmod=3 also k3 and k4 are fitted to reference region data,",
102 " thus any large brain region (for example cortex) could be used here.",
103 " -rmod=<2|3>",
104 " Specify the model (2- or 3-compartments) that is fitted to reference",
105 " region data; by default 2-CM (1-tissue compartment model).",
106*/
107 " -fit=<Filename>",
108 " Fitted regional TACs are written in DFT format.",
109 " -svg=<Filename>",
110 " Fitted and measured TACs are plotted in specified SVG file.",
111 " -stdoptions", // List standard options like --help, -v, etc
112 " ",
113 "Example 1: estimate K1, K1/k2, k3, k3/k4, k5 and Vb",
114 " @P -svg=ua929fit.svg ua929ap.bld ua929ab.bld ua929.tac 90 ua929.res",
115 " ",
116 "Example 2: estimate K1, k3, k3/k4, and k5; Vb is constrained to 1.5%, and",
117 "K1/k2 is constrained to the regional median",
118 " @P -Vb=1.5 ua929ap.kbq ua929ab.kbq ua929.tac 90 tmp.res",
119 " @P -Vb=1.5 -fk1k2=tmp.res ua929ap.kbq ua929ab.kbq ua929.tac 90 ua929.res",
120 " ",
121 "See also: logan, fitk2, fitk3, fitk4, p2t_v3c, tacweigh, rescoll",
122 " ",
123 "Keywords: TAC, modelling, Ki, k5, irreversible uptake, 3TCM",
124 0};
125/*****************************************************************************/
126
127/*****************************************************************************/
128/* Turn on the globbing of the command line, since it is disabled by default in
129 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
130 In Unix&Linux wildcard command line processing is enabled by default. */
131/*
132#undef _CRT_glob
133#define _CRT_glob -1
134*/
135int _dowildcard = -1;
136/*****************************************************************************/
137
138/*****************************************************************************
139 *
140 * Main
141 *
142 *****************************************************************************/
143int main(int argc, char *argv[])
144{
145 int ai, help=0, version=0, verbose=1;
146 int ri, fi, pi, m, n, ret;
147 int model=1; // 0=series, 1=parallel
148 int ref=-1, refAdded=0, inputtype;
149 char dfile[FILENAME_MAX], pfile[FILENAME_MAX], bfile[FILENAME_MAX],
150 rfile[FILENAME_MAX], ffile[FILENAME_MAX], svgfile[FILENAME_MAX],
151 limfile[FILENAME_MAX];
152 char *cptr, tmp[FILENAME_MAX], refname[FILENAME_MAX];
153 double fitdur, K1, k2, k3, k4, k5, f;
154 RES res;
155 IFT ift;
156 int doBootstrap=0, doSD=0, doCL=0;
157 double *sd, *cl1, *cl2;
158 double def_pmin[MAX_PARAMETERS], def_pmax[MAX_PARAMETERS];
159 int tgoNr=0, neighNr=0, iterNr=0, fittedparNr=0;
160 double (*func)(int, double*, void*);
161
162
163 //drandSeed(195); // tgo() does it
164
165 /* Set parameter initial values and constraints */
166 /* K1 */ def_pmin[CM_K1]=0.0; def_pmax[CM_K1]=5.0;
167 /* K1/k2 */ def_pmin[CM_K1K2]=0.00001; def_pmax[CM_K1K2]=10.0;
168 /* k3 */ def_pmin[CM_K3]=0.0; def_pmax[CM_K3]=2.0;
169 /* k3/k4 */ def_pmin[CM_K3K4]=0.00001; def_pmax[CM_K3K4]=2.0;
170 /* k5 */ def_pmin[CM_K5]=0.0; def_pmax[CM_K5]=2.0;
171 /* Vb */ def_pmin[CM_VB]=0.0; def_pmax[CM_VB]=0.50;
172
173
174 /*
175 * Get arguments
176 */
177 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
178 dfile[0]=pfile[0]=bfile[0]=rfile[0]=ffile[0]=refname[0]=svgfile[0]=(char)0;
179 limfile[0]=(char)0;
180 fitdur=fVb=-1.0;
181 iftInit(&ift); resInit(&res);
182 dftInit(&dft); dftInit(&input);
183 /* Get options first, because it affects what arguments are read */
184 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
185 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
186 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
187 if(strncasecmp(cptr, "CL", 2)==0) {
188 if(strlen(cptr)==2) {doCL=1; continue;}
189 cptr+=2; if(*cptr=='=') {
190 cptr++;
191 if(*cptr=='Y' || *cptr=='y') {doCL=1; continue;}
192 if(*cptr=='N' || *cptr=='n') {doCL=0; continue;}
193 }
194 } else if(strncasecmp(cptr, "SD", 2)==0) {
195 if(strlen(cptr)==2) {doSD=1; continue;}
196 cptr+=2; if(*cptr=='=') {
197 cptr++;
198 if(*cptr=='Y' || *cptr=='y') {doSD=1; continue;}
199 if(*cptr=='N' || *cptr=='n') {doSD=0; continue;}
200 }
201 } else if(strncasecmp(cptr, "LIM=", 4)==0 && strlen(cptr)>4) {
202 strlcpy(limfile, cptr+4, FILENAME_MAX); continue;
203 } else if(strcasecmp(cptr, "LIM")==0) {
204 strcpy(limfile, "stdout"); continue;
205 } else if(strncasecmp(cptr, "R=", 2)==0 && strlen(cptr)>2) {
206 strlcpy(refname, cptr+2, FILENAME_MAX); continue;
207 } else if(strncasecmp(cptr, "MODEL=", 6)==0) {
208 cptr+=6;
209 if(strncasecmp(cptr, "PARALLEL", 1)==0) {model=1; continue;}
210 if(strncasecmp(cptr, "SERIES", 1)==0) {model=0; continue;}
211 } else if(strncasecmp(cptr, "FK1K2=", 6)==0 && strlen(cptr)>6) {
212 /* Try to read specified K1/k2 from option */
213 fk1k2=atof_dpi(cptr+6); def_pmin[CM_K1K2]=def_pmax[CM_K1K2]=fk1k2;
214 if(fk1k2>0.0) continue;
215 /* If not successful, then try to read median K1/k2 from specified
216 result file */
217 if(resK1k2Median(cptr+6, &fk1k2, NULL, tmp)==0) {
218 def_pmin[CM_K1K2]=def_pmax[CM_K1K2]=fk1k2; continue;
219 }
220 if(verbose>1) fprintf(stderr, "Error: %s\n", tmp);
221 } else if(strncasecmp(cptr, "FK3K4=", 6)==0 && strlen(cptr)>6) {
222 /* Try to read specified K3/k4 from option */
223 fk3k4=atof_dpi(cptr+6); def_pmin[CM_K3K4]=def_pmax[CM_K3K4]=fk3k4;
224 if(fk3k4>0.0) continue;
225 } else if(strncasecmp(cptr, "Vb=", 3)==0 && strlen(cptr)>3) {
226 fVb=0.01*atof_dpi(cptr+3);
227 if(fVb>=0.0 && fVb<1.0) {
228 if(fVb<0.01) fprintf(stderr, "Warning: Vb was set to %g%%\n", 100.*fVb);
229 def_pmin[CM_VB]=def_pmax[CM_VB]=fVb;
230 continue;
231 }
232 fVb=-1.0;
233 } else if(strncasecmp(cptr, "FIT=", 4)==0) {
234 strlcpy(ffile, cptr+4, FILENAME_MAX); if(strlen(ffile)>0) continue;
235 } else if(strncasecmp(cptr, "SVG=", 4)==0) {
236 strlcpy(svgfile, cptr+4, FILENAME_MAX); if(strlen(svgfile)>0) continue;
237 }
238 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
239 return(1);
240 } else break;
241
242 /* Print help or version? */
243 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
244 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
245 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
246
247 /* Process other arguments, starting from the first non-option */
248 for(; ai<argc; ai++) {
249 if(!pfile[0]) {
250 strlcpy(pfile, argv[ai], FILENAME_MAX); continue;
251 } else if(!bfile[0]) {
252 strlcpy(bfile, argv[ai], FILENAME_MAX); continue;
253 } else if(!dfile[0]) {
254 strlcpy(dfile, argv[ai], FILENAME_MAX); continue;
255 } else if(fitdur<0) {
256 if(!atof_with_check(argv[ai], &fitdur) && fitdur>=0.0) continue;
257 fprintf(stderr, "Error: invalid fit time '%s'.\n", argv[ai]);
258 return(1);
259 } else if(!rfile[0]) {
260 strlcpy(rfile, argv[ai], FILENAME_MAX); continue;
261 }
262 /* we should never get this far */
263 fprintf(stderr, "Error: too many arguments: '%s'.\n", argv[ai]);
264 return(1);
265 }
266 if(doSD || doCL) doBootstrap=1; else doBootstrap=0;
267
268 /* In verbose mode print arguments and options */
269 if(verbose>1) {
270 printf("pfile := %s\n", pfile);
271 //printf("bfile := %s\n", bfile); Later!
272 printf("dfile := %s\n", dfile);
273 printf("rfile := %s\n", rfile);
274 printf("ffile := %s\n", ffile);
275 printf("svgfile := %s\n", svgfile);
276 printf("limfile := %s\n", limfile);
277 printf("refname := %s\n", refname);
278 printf("model := %d\n", model);
279 printf("fitdur := %g\n", fitdur);
280 //if(fVb>=0.0) printf("fVb := %g\n", fVb); Later!
281 //if(fk1k2>0.0) printf("fk1k2 := %g\n", fk1k2); Later!
282 //if(fk3k4>0.0) printf("fk3k4 := %g\n", fk3k4); Later!
283 printf("doBootstrap := %d\n", doBootstrap);
284 printf("doSD := %d\n", doSD);
285 printf("doCL := %d\n", doCL);
286 }
287
288
289 /* If only file name for parameter constraints was given, then write one
290 with default contents, and exit */
291 if(limfile[0] && !pfile[0]) {
292 /* Check that initial value file does not exist */
293 if(strcasecmp(limfile, "stdout")!=0 && access(limfile, 0) != -1) {
294 fprintf(stderr, "Error: parameter constraint file %s exists.\n", limfile);
295 return(9);
296 }
297 if(verbose>1 && strcasecmp(limfile, "stdout")!=0)
298 printf("writing parameter constraints file\n");
299 /* Create parameter file */
300 iftPutDouble(&ift, "K1_lower", def_pmin[CM_K1], NULL, 0);
301 iftPutDouble(&ift, "K1_upper", def_pmax[CM_K1], NULL, 0);
302 iftPutDouble(&ift, "K1k2_lower", def_pmin[CM_K1K2], NULL, 0);
303 iftPutDouble(&ift, "K1k2_upper", def_pmax[CM_K1K2], NULL, 0);
304 iftPutDouble(&ift, "k3_lower", def_pmin[CM_K3], NULL, 0);
305 iftPutDouble(&ift, "k3_upper", def_pmax[CM_K3], NULL, 0);
306 iftPutDouble(&ift, "k3k4_lower", def_pmin[CM_K3K4], NULL, 0);
307 iftPutDouble(&ift, "k3k4_upper", def_pmax[CM_K3K4], NULL, 0);
308 iftPutDouble(&ift, "k5_lower", def_pmin[CM_K5], NULL, 0);
309 iftPutDouble(&ift, "k5_upper", def_pmax[CM_K5], NULL, 0);
310 iftPutDouble(&ift, "Vb_lower", def_pmin[CM_VB], NULL, 0);
311 iftPutDouble(&ift, "Vb_upper", def_pmax[CM_VB], NULL, 0);
312 ret=iftWrite(&ift, limfile, 0);
313 if(ret) {
314 fprintf(stderr, "Error in writing '%s': %s\n", limfile, ift.status);
315 iftEmpty(&ift); return(9);
316 }
317 if(strcasecmp(limfile, "stdout")!=0)
318 fprintf(stdout, "Parameter file %s with initial values written.\n", limfile);
319 iftEmpty(&ift); return(0);
320 }
321
322
323 /* Did we get all the information that we need? */
324 if(fitdur==0) fitdur=1.0E+100;
325 else if(fitdur<0) {tpcPrintUsage(argv[0], info, stderr); return(1);}
326 if(!rfile[0]) {
327 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
328 return(1);
329 }
330
331
332 /*
333 * Read model parameter upper and lower limits
334 * if file for that was given
335 */
336 if(limfile[0]) {
337 if(verbose>1) printf("reading %s\n", limfile);
338 ret=iftRead(&ift, limfile, 1, 0);
339 if(ret) {
340 fprintf(stderr, "Error in reading '%s': %s\n", limfile, ift.status);
341 return(9);
342 }
343 if(verbose>2) iftWrite(&ift, "stdout", 0);
344 double v;
345 int n=0;
346 /* K1 */
347 if(iftGetDoubleValue(&ift, 0, "K1_lower", &v, 0)>=0) {def_pmin[CM_K1]=v; n++;}
348 if(iftGetDoubleValue(&ift, 0, "K1_upper", &v, 0)>=0) {def_pmax[CM_K1]=v; n++;}
349 /* K1/k2 */
350 if(iftGetDoubleValue(&ift, 0, "K1k2_lower", &v, 0)>=0) {def_pmin[CM_K1K2]=v; n++;}
351 if(iftGetDoubleValue(&ift, 0, "K1k2_upper", &v, 0)>=0) {def_pmax[CM_K1K2]=v; n++;}
352 /* k3 */
353 if(iftGetDoubleValue(&ift, 0, "k3_lower", &v, 0)>=0) {def_pmin[CM_K3]=v; n++;}
354 if(iftGetDoubleValue(&ift, 0, "k3_upper", &v, 0)>=0) {def_pmax[CM_K3]=v; n++;}
355 /* k3/k4 */
356 if(iftGetDoubleValue(&ift, 0, "k3k4_lower", &v, 0)>=0) {def_pmin[CM_K3K4]=v; n++;}
357 if(iftGetDoubleValue(&ift, 0, "k3k4_upper", &v, 0)>=0) {def_pmax[CM_K3K4]=v; n++;}
358 /* k5 */
359 if(iftGetDoubleValue(&ift, 0, "k5_lower", &v, 0)>=0) {def_pmin[CM_K5]=v; n++;}
360 if(iftGetDoubleValue(&ift, 0, "k5_upper", &v, 0)>=0) {def_pmax[CM_K5]=v; n++;}
361 /* Vb */
362 if(iftGetDoubleValue(&ift, 0, "Vb_lower", &v, 0)>=0) {def_pmin[CM_VB]=v; n++;}
363 if(iftGetDoubleValue(&ift, 0, "Vb_upper", &v, 0)>=0) {def_pmax[CM_VB]=v; n++;}
364 iftEmpty(&ift);
365 if(n==0) {fprintf(stderr, "Error: invalid parameter file.\n"); return(9);}
366 }
367 /* Check that these are ok */
368 for(pi=n=0, ret=0; pi<parNr; pi++) {
369 if(def_pmin[pi]<0.0) ret++;
370 if(def_pmax[pi]<def_pmin[pi]) ret++;
371 if(def_pmax[pi]>def_pmin[pi]) n++;
372 }
373 if(ret) {
374 fprintf(stderr, "Error: invalid parameter constraints.\n");
375 return(9);
376 }
377 if(n==0) {
378 fprintf(stderr, "Error: no model parameters left free for fitting.\n");
379 return(9);
380 }
381
382 /* Fixed/fitted Vb */
383 if(fVb>=0.0) def_pmin[CM_VB]=def_pmax[CM_VB]=fVb;
384 if(def_pmin[4]==def_pmax[CM_VB]) fVb=def_pmin[CM_VB];
385 if(fVb==0.0) strcpy(bfile, "");
386 if(verbose>1) {
387 printf("bfile := %s\n", bfile);
388 if(fVb>=0.0) printf("fVb := %g\n", fVb);
389 }
390 /* Fixed/fitted K1/k2 */
391 if(fk1k2>0.0) def_pmin[CM_K1K2]=def_pmax[CM_K1K2]=fk1k2;
392 else if(def_pmin[CM_K1K2]==def_pmax[CM_K1K2]) fk1k2=def_pmin[CM_K1K2];
393 if(verbose>1) {
394 if(fk1k2>0.0) printf("fk1k2 := %g\n", fk1k2);
395 }
396 /* Fixed/fitted K3/k4 */
397 if(fk3k4>0.0) def_pmin[CM_K3K4]=def_pmax[CM_K3K4]=fk3k4;
398 else if(def_pmin[CM_K3K4]==def_pmax[CM_K3K4]) fk3k4=def_pmin[CM_K3K4];
399 if(verbose>1) {
400 if(fk3k4>0.0) printf("fk3k4 := %g\n", fk3k4);
401 }
402
403
404 /*
405 * Read tissue and input data
406 */
407 if(verbose>1) printf("reading tissue and input data\n");
408 ret=dftReadModelingData(dfile, pfile, bfile, NULL, &fitdur,
409 &fitframeNr, &dft, &input, stdout, verbose-2, tmp);
410 if(ret!=0) {
411 fprintf(stderr, "Error: %s\n", tmp);
412 return(2);
413 }
414 if(fitframeNr<6 || input.frameNr<6) {
415 fprintf(stderr, "Error: too few samples in specified fit duration.\n");
416 dftEmpty(&input); dftEmpty(&dft); return(2);
417 }
418 /* If there is no blood TAC, then create a zero blood TAC */
419 if(input.voiNr<2) {
420 if(verbose>2) printf("setting blood tac to zero\n");
421 ret=dftAddmem(&input, 1);
422 if(ret) {
423 fprintf(stderr, "Error: cannot allocate more memory.\n");
424 dftEmpty(&dft); dftEmpty(&input); return(3);
425 }
426 strcpy(input.voi[1].voiname, "blood");
427 strcpy(input.voi[1].name, input.voi[1].voiname);
428 for(fi=0; fi<input.frameNr; fi++) input.voi[1].y[fi]=0.0;
429 input.voiNr=2;
430 }
431 if(verbose>10) dftPrint(&dft);
432 if(verbose>10) dftPrint(&input);
433 /* Print the weights */
434 if(verbose>2) {
435 fprintf(stdout, "common_data_weights := %g", dft.w[0]);
436 for(fi=1; fi<dft.frameNr; fi++) fprintf(stdout, ", %g", dft.w[fi]);
437 fprintf(stdout, "\n");
438 }
439
440
441 /*
442 * Read reference TAC
443 */
444 /* Check if user even wants any reference region */
445 if(!refname[0]) {
446 if(verbose>1) printf("no reference region data\n");
447 ref=-1;
448 } else {
449 if(verbose>1) printf("reading reference region data\n");
450 if((n=dftReadReference(&dft, refname, &inputtype, &ref, tmp, verbose-3))<1) {
451 fprintf(stderr, "Error in reading '%s': %s\n", refname, tmp);
452 if(verbose>2) printf("dftReadReference()=%d\n", n);
453 dftEmpty(&dft); dftEmpty(&input); return(6);
454 }
455 if(verbose>30) dftPrint(&dft);
456 if(n>1) {
457 fprintf(stderr, "Warning: %s selected of %d reference regions.\n",
458 dft.voi[ref].name, n);
459 if(verbose>2)
460 fprintf(stdout, "selected reference region := %s\n", dft.voi[ref].name);
461 }
462 if(inputtype==5) { // Reference region name was given
463 refAdded=0; strcpy(refname, "");
464 } else { // reference file was given; ref TACs may have to be deleted later
465 refAdded=1;
466 }
467 if(verbose>15) dftPrint(&dft);
468 if(verbose>1) printf("Reference region: %s\n", dft.voi[ref].name );
469 }
470
471 /* Allocate an extra TAC for the bootstrap */
472 if(doBootstrap) {
473 ret=dftAddmem(&dft, 1); if(ret) {
474 fprintf(stderr, "Error: cannot allocate more memory.\n");
475 dftEmpty(&dft); dftEmpty(&input); return(9);
476 }
477 strcpy(dft.voi[dft.voiNr].voiname, "BS");
478 strcpy(dft.voi[dft.voiNr].name, "BS");
479 }
480 if(verbose>10) dftPrint(&dft);
481
482
483 /*
484 * Prepare the room for the results
485 */
486 if(verbose>1) printf("initializing result data\n");
487 ret=res_allocate_with_dft(&res, &dft); if(ret!=0) {
488 fprintf(stderr, "Error: cannot setup memory for results.\n");
489 dftEmpty(&input); dftEmpty(&dft); return(7);
490 }
491 /* Copy titles & file names */
492 tpcProgramName(argv[0], 1, 1, res.program, 256);
493 strcpy(res.datafile, dfile);
494 strcpy(res.plasmafile, pfile);
495 strcpy(res.bloodfile, bfile);
496 if(ref>=0) sprintf(res.refroi, "%s", dft.voi[ref].name);
497 if(refname[0]) strcpy(res.reffile, refname);
498 strcpy(res.fitmethod, "TGO");
499 /* Constants */
500 res.isweight=dft.isweight;
501 if(fVb>=0.0) res.Vb=100.0*fVb;
502 /* Set data range */
503 sprintf(res.datarange, "%g - %g %s", 0.0, fitdur, dftTimeunit(dft.timeunit));
504 res.datanr=fitframeNr;
505 /* Set current time to results */
506 res.time=time(NULL);
507 /* Set parameter number, including also the extra "parameters"
508 and the parameter names and units */
509 res.parNr=9;
510 pi=0; strcpy(res.parname[pi], "K1"); strcpy(res.parunit[pi], "ml/(min*ml)");
511 pi++; strcpy(res.parname[pi], "K1/k2"); strcpy(res.parunit[pi], "");
512 pi++; strcpy(res.parname[pi], "k3"); strcpy(res.parunit[pi], "1/min");
513 pi++; strcpy(res.parname[pi], "k3/k4"); strcpy(res.parunit[pi], "");
514 pi++; strcpy(res.parname[pi], "k5"); strcpy(res.parunit[pi], "1/min");
515 pi++; strcpy(res.parname[pi], "Vb"); strcpy(res.parunit[pi], "%");
516 pi++; strcpy(res.parname[pi], "Ki"); strcpy(res.parunit[pi], "ml/(min*ml)");
517 pi++; strcpy(res.parname[pi], "WSS"); strcpy(res.parunit[pi], "");
518 pi++; strcpy(res.parname[pi], "AIC"); strcpy(res.parunit[pi], "");
519
520 /* Set model function */
521 if(model==0) func=func_sk5; else func=func_pk5;
522
523
524 /*
525 * Fit at first the reference ROI(s), if required
526 */
527 if(ref>=0) for(ri=0; ri<dft.voiNr; ri++) if(dft.voi[ri].sw>0) {
528 if(verbose>0)
529 fprintf(stdout, "fitting %s as reference region\n", dft.voi[ri].name);
530 /* Initiate values */
531 petmeas=dft.voi[ri].y; petsim=dft.voi[ri].y2;
532 /* Set constraints */
533 for(pi=0; pi<parNr; pi++) { pmin[pi]=def_pmin[pi]; pmax[pi]=def_pmax[pi]; }
534 for(pi=fittedparNr=0; pi<parNr; pi++) if(pmax[pi]>pmin[pi]) fittedparNr++;
535 if(verbose>3) {
536 printf(" ref_constraints :=");
537 for(pi=0; pi<parNr; pi++) printf(" [%g,%g]", pmin[pi], pmax[pi]);
538 printf("\n");
539 printf("fittedparNr := %d\n", fittedparNr);
540 }
541 /* Fit */
544 // n=fittedparNr; if(n>4) n=4; tgoNr=50+50*n; neighNr=8;
545 tgoNr=50+30*fittedparNr;
546 neighNr=6*fittedparNr;
547 iterNr=0;
548 ret=tgo(
549 pmin, pmax, func, NULL, parNr, neighNr, &res.voi[ri].parameter[CM_WSS],
550 res.voi[ri].parameter, tgoNr, iterNr, verbose-8);
551 if(ret>0) {
552 fprintf(stderr, "Error in optimization (%d).\n", ret);
553 dftEmpty(&input); dftEmpty(&dft); resEmpty(&res); return(8);
554 }
555 /* Correct fitted parameters to match constraints like inside function */
556 (void)modelCheckParameters(parNr, pmin, pmax, res.voi[ri].parameter,
557 res.voi[ri].parameter, NULL);
558 res.voi[ri].parameter[CM_WSS]=wss_wo_penalty;
559 /* If k3 or k3/k4 is zero, then both k3 and k3/k4, and k5, should be zero */
560 if(res.voi[ri].parameter[CM_K3]<1.0E-20 ||
561 res.voi[ri].parameter[CM_K3K4]<1.0E-20)
562 {
563 res.voi[ri].parameter[CM_K3]=res.voi[ri].parameter[CM_K3K4]=0.0;
564 res.voi[ri].parameter[CM_K5]=0.0;
565 }
566 if(verbose>1) {
567 fprintf(stdout, " K1/k2 := %g\n", res.voi[ri].parameter[CM_K1K2]);
568 //fprintf(stdout, " k3/k4 := %g\n", res.voi[ri].parameter[CM_K3K4]);
569 }
570 if(verbose>4) {
571 printf("Original and fitted TACs:\n");
572 for(fi=0; fi<fitframeNr; fi++)
573 printf(" %8.3f %9.3f %9.3f\n", dft.x[fi], petmeas[fi], petsim[fi]);
574 printf("Original and fitted TACs:\n");
575 }
576 /* Fix K1/k2 to non-reference regions, but only after all reference
577 regions are fitted */
578 if(ri==ref) {
579 fk1k2=res.voi[ri].parameter[CM_K1K2];
580 if(verbose>2) {fprintf(stdout, " fixed K1/k2 := %g\n", fk1k2);}
581 }
582 /* Bootstrap */
583 if(doBootstrap) {
584 if(verbose>2) printf(" bootstrapping\n");
585 /* bootstrap changes measured and simulated data, therefore use copies */
586 petmeas=dft.voi[dft.voiNr].y2; petsim=dft.voi[dft.voiNr].y3;
587 if(doSD) sd=res.voi[ri].sd; else sd=NULL;
588 if(doCL) {cl1=res.voi[ri].cl1; cl2=res.voi[ri].cl2;} else cl1=cl2=NULL;
589 ret=bootstrap(
590 0, cl1, cl2, sd,
591 res.voi[ri].parameter, pmin, pmax, fitframeNr,
592 // measured original TAC, not modified
593 dft.voi[ri].y,
594 // fitted TAC, not modified
595 dft.voi[ri].y2,
596 // tissue TAC noisy data is written to be used by objf
597 petmeas,
598 parNr, dft.w, func, tmp, verbose-4
599 );
600 if(ret) {
601 fprintf(stderr, "Error in bootstrap: %s\n", tmp);
602 for(pi=0; pi<parNr; pi++) {
603 if(doSD) sd[pi]=nan("");
604 if(doCL) cl1[pi]=cl2[pi]=nan("");
605 }
606 }
607 }
608 /* Calculate AIC based on nr of parameters that actually are fitted */
609 for(pi=n=0; pi<parNr; pi++) if(pmax[pi]>pmin[pi]) n++;
610 if(verbose>2) printf("nr_of_fitted_parameters := %d\n", n);
611 for(fi=m=0; fi<fitframeNr; fi++) if(dft.w[fi]>0.0) m++;
612 if(verbose>2) printf("nr_of_fitted_samples := %d\n", m);
613 res.voi[ri].parameter[CM_AIC]=aicSS(res.voi[ri].parameter[CM_WSS], m, n);
614
615 /* Calculate Ki */
616 K1=res.voi[ri].parameter[CM_K1];
617 k2=K1/res.voi[ri].parameter[CM_K1K2];
618 k3=res.voi[ri].parameter[CM_K3];
619 k4=k3/res.voi[ri].parameter[CM_K3K4];
620 k5=res.voi[ri].parameter[CM_K5];
621 if(model==0) {
622 f=k2*k4+k2*k5+k3*k5;
623 if(f<=1.0E-100) res.voi[ri].parameter[CM_KI]=0.0;
624 else res.voi[ri].parameter[CM_KI]=K1*k3*k5/f;
625 } else {
626 f=k2+k5;
627 if(f<=1.0E-100) res.voi[ri].parameter[CM_KI]=0.0;
628 else res.voi[ri].parameter[CM_KI]=K1*k5/f;
629 }
630
631 /* Convert Vb fraction to percentage */
632 res.voi[ri].parameter[CM_VB]*=100.;
633 if(doSD) res.voi[ri].sd[CM_VB]*=100.;
634 if(doCL) {res.voi[ri].cl1[CM_VB]*=100.; res.voi[ri].cl2[CM_VB]*=100.;}
635
636 } // next reference region
637
638
639 /*
640 * Fit other than reference regions
641 */
642 if(verbose>0) {fprintf(stdout, "fitting regional TACs: "); fflush(stdout);}
643 if(verbose>1) printf("\n");
644 /* Set K1/k2 constraint based on above fitted reference region, if required */
645 if(fk1k2>0.0) def_pmin[CM_K1K2]=def_pmax[CM_K1K2]=fk1k2;
646 /* One ROI at a time */
647 for(ri=0; ri<dft.voiNr; ri++) if(dft.voi[ri].sw==0) {
648 if(verbose>2) printf("\n %d %s:\n", ri, dft.voi[ri].name);
649
650 /* Initiate values */
651 petmeas=dft.voi[ri].y; petsim=dft.voi[ri].y2;
652
653 /* Set constraints */
654 for(pi=0; pi<parNr; pi++) { pmin[pi]=def_pmin[pi]; pmax[pi]=def_pmax[pi]; }
655 for(pi=fittedparNr=0; pi<parNr; pi++) if(pmax[pi]>pmin[pi]) fittedparNr++;
656 if(verbose>3) {
657 printf(" constraints :=");
658 for(pi=0; pi<parNr; pi++) printf(" [%g,%g]", pmin[pi], pmax[pi]);
659 printf("\n");
660 printf("fittedparNr := %d\n", fittedparNr);
661 }
662
663 /* Fit */
666 // n=fittedparNr; if(n>4) n=4; tgoNr=50*50*n; neighNr=8; iterNr=0;
667 tgoNr=50+30*fittedparNr;
668 neighNr=6*fittedparNr;
669 iterNr=0;
670 ret=tgo(
671 pmin, pmax, func, NULL, parNr, neighNr, &res.voi[ri].parameter[CM_WSS],
672 res.voi[ri].parameter, tgoNr, iterNr, verbose-8);
673 if(ret>0) {
674 fprintf(stderr, "\nError in optimization (%d).\n", ret);
675 dftEmpty(&input); dftEmpty(&dft); resEmpty(&res); return(8);
676 }
677 /* Correct fitted parameters to match constraints like inside function */
678 (void)modelCheckParameters(parNr, pmin, pmax, res.voi[ri].parameter,
679 res.voi[ri].parameter, NULL);
680 res.voi[ri].parameter[CM_WSS]=wss_wo_penalty;
681 /* If k3 or k3/k4 is zero, then both k3 and k3/k4, and k5, should be zero */
682 if(res.voi[ri].parameter[CM_K3]<1.0E-20 ||
683 res.voi[ri].parameter[CM_K3K4]<1.0E-20)
684 {
685 res.voi[ri].parameter[CM_K3]=res.voi[ri].parameter[CM_K3K4]=0.0;
686 res.voi[ri].parameter[CM_K5]=0.0;
687 }
688
689 /* Bootstrap */
690 if(doBootstrap) {
691 if(verbose>2) printf(" bootstrapping\n");
692 /* bootstrap changes measured and simulated data, therefore use copies */
693 petmeas=dft.voi[dft.voiNr].y2; petsim=dft.voi[dft.voiNr].y3;
694 if(doSD) sd=res.voi[ri].sd; else sd=NULL;
695 if(doCL) {cl1=res.voi[ri].cl1; cl2=res.voi[ri].cl2;} else cl1=cl2=NULL;
696 ret=bootstrap(
697 0, cl1, cl2, sd,
698 res.voi[ri].parameter, pmin, pmax, fitframeNr,
699 // measured original TAC, not modified
700 dft.voi[ri].y,
701 // fitted TAC, not modified
702 dft.voi[ri].y2,
703 // tissue TAC noisy data is written to be used by objf
704 petmeas,
705 parNr, dft.w, func, tmp, verbose-4
706 );
707 if(ret) {
708 fprintf(stderr, "Error in bootstrap: %s\n", tmp);
709 for(pi=0; pi<parNr; pi++) {
710 if(doSD) sd[pi]=nan("");
711 if(doCL) cl1[pi]=cl2[pi]=nan("");
712 }
713 }
714 }
715
716 /* Calculate Ki */
717 K1=res.voi[ri].parameter[CM_K1];
718 k2=K1/res.voi[ri].parameter[CM_K1K2];
719 k3=res.voi[ri].parameter[CM_K3];
720 k4=k3/res.voi[ri].parameter[CM_K3K4];
721 k5=res.voi[ri].parameter[CM_K5];
722 if(model==0) {
723 f=k2*k4+k2*k5+k3*k5;
724 if(f<=1.0E-100) res.voi[ri].parameter[CM_KI]=0.0;
725 else res.voi[ri].parameter[CM_KI]=K1*k3*k5/f;
726 } else {
727 f=k2+k5;
728 if(f<=1.0E-100) res.voi[ri].parameter[CM_KI]=0.0;
729 else res.voi[ri].parameter[CM_KI]=K1*k5/f;
730 }
731
732 /* Calculate AIC, based on nr of parameters that actually are fitted */
733 for(pi=n=0; pi<parNr; pi++) if(pmax[pi]>pmin[pi]) n++;
734 if(verbose>2) printf("nr_of_fitted_parameters := %d\n", n);
735 for(fi=m=0; fi<fitframeNr; fi++) if(dft.w[fi]>0.0) m++;
736 if(verbose>2) printf("nr_of_fitted_samples := %d\n", m);
737 res.voi[ri].parameter[CM_AIC]=aicSS(res.voi[ri].parameter[CM_WSS], m, n);
738
739 /* Convert Vb fraction to percentage */
740 res.voi[ri].parameter[CM_VB]*=100.;
741 if(doSD) res.voi[ri].sd[CM_VB]*=100.;
742 if(doCL) {res.voi[ri].cl1[CM_VB]*=100.; res.voi[ri].cl2[CM_VB]*=100.;}
743
744 /* done with this region */
745 if(dft.voiNr>2 && verbose==1) {fprintf(stdout, "."); fflush(stdout);}
746
747 } /* next region */
748 if(verbose>0) {fprintf(stdout, "\n"); fflush(stdout);}
749
750
751 /*
752 * Print results on screen
753 */
754 if(verbose>0) {resPrint(&res); fprintf(stdout, "\n");}
755
756
757 /*
758 * Save results
759 */
760 if(verbose>1) printf("saving results\n");
761 ret=resWrite(&res, rfile, verbose-3);
762 if(ret) {
763 fprintf(stderr, "Error in writing '%s': %s\n", rfile, reserrmsg);
764 dftEmpty(&dft); dftEmpty(&input); resEmpty(&res);
765 return(11);
766 }
767 if(verbose>0) fprintf(stdout, "Model parameters written in %s\n", rfile);
768
769
770 /*
771 * Saving and/or plotting of fitted TACs
772 */
773 if(svgfile[0] || ffile[0]) {
774
775 /* Create a DFT containing fitted TACs */
776 char tmp[64];
777 DFT dft2;
778 dftInit(&dft2); ret=dftdup(&dft, &dft2);
779 if(ret) {
780 fprintf(stderr, "Error: cannot save fitted curves.\n");
781 dftEmpty(&dft); dftEmpty(&input); resEmpty(&res);
782 return(21);
783 }
784 for(ri=0; ri<dft.voiNr; ri++) for(fi=0; fi<fitframeNr; fi++)
785 dft2.voi[ri].y[fi]=dft2.voi[ri].y2[fi];
786 dft2.frameNr=fitframeNr;
787
788 /* Save SVG plot of fitted and original data */
789 if(svgfile[0]) {
790 if(verbose>1) printf("saving SVG plot\n");
791 sprintf(tmp, "K1-k5 fit: ");
792 if(strlen(dft.studynr)>0) strcat(tmp, dft.studynr);
793 ret=plot_fitrange_svg(&dft, &dft2, tmp, 0.0, 1.02*dft.x[fitframeNr-1],
794 0.0, nan(""), svgfile, verbose-8);
795 if(ret) {
796 fprintf(stderr, "Error (%d) in writing '%s'.\n", ret, svgfile);
797 dftEmpty(&dft2); dftEmpty(&dft); dftEmpty(&input); resEmpty(&res);
798 return(30+ret);
799 }
800 if(verbose>0) printf("Plots written in %s\n", svgfile);
801 }
802
803 /* Delete reference region(s) from the data */
804 if(refAdded!=0) {
805 for(ri=dft2.voiNr-1; ri>=0; ri--) if(dft2.voi[ri].sw!=0)
806 dftDelete(&dft2, ri);
807 }
808
809 /* Save fitted TACs */
810 if(ffile[0]) {
811 if(verbose>1) printf("saving fitted curves\n");
812 tpcProgramName(argv[0], 1, 0, tmp, 128);
813 sprintf(dft2.comments, "# program := %s\n", tmp);
814 if(dftWrite(&dft2, ffile)) {
815 fprintf(stderr, "Error in writing '%s': %s\n", ffile, dfterrmsg);
816 dftEmpty(&dft2); dftEmpty(&dft); dftEmpty(&input); resEmpty(&res);
817 return(22);
818 }
819 if(verbose>0) printf("Fitted TACs written in %s\n", ffile);
820 }
821
822 dftEmpty(&dft2);
823 }
824
825 dftEmpty(&dft); dftEmpty(&input); resEmpty(&res);
826 return(0);
827}
828/*****************************************************************************/
829
830/*****************************************************************************
831 *
832 * Functions to be minimized
833 *
834 *****************************************************************************/
835
836/* Compartments in series */
837double func_sk5(int parNr, double *p, void *fdata)
838{
839 int fi, ret;
840 double Vb, k2, k4, d, wss=0.0;
841 double pa[MAX_PARAMETERS], penalty=1.0;
842
843 /* Check parameters against the constraints */
844 ret=modelCheckParameters(parNr, pmin, pmax, p, pa, &penalty);
845 if(fdata) {}
846 /* Calculate individual parameters */
847 k2=pa[CM_K1]/pa[CM_K1K2];
848 k4=pa[CM_K3]/pa[CM_K3K4];
849 Vb=pa[CM_VB];
850
851 /* Simulate the tissue PET TAC */
852 ret=simC3vs(
853 input.x, input.voi[0].y, input.voi[1].y, input.frameNr,
854 pa[CM_K1], k2, pa[CM_K3], k4, pa[CM_K5], 0.0, 0.0, Vb, 1.0,
855 input.voi[0].y2, NULL, NULL, NULL, NULL, NULL);
856 if(ret) {
857 printf("error %d in simulation\n", ret);
858 return(nan(""));
859 }
860
861 /* Interpolate & integrate to measured PET frames */
863 ret=interpolate4pet(
864 input.x, input.voi[0].y2, input.frameNr,
865 dft.x1, dft.x2, petsim, NULL, NULL, fitframeNr);
866 else
867 ret=interpolate(
868 input.x, input.voi[0].y2, input.frameNr,
869 dft.x, petsim, NULL, NULL, fitframeNr);
870 if(ret) {
871 printf("error %d in interpolation\n", ret);
872 return(nan(""));
873 }
874
875 /* Calculate error */
876 for(fi=0, wss=0.0; fi<fitframeNr; fi++) if(dft.w[fi]>0.0) {
877 d=petmeas[fi]-petsim[fi];
878 wss+=dft.w[fi]*d*d;
879 }
880 wss_wo_penalty=wss;
881 wss*=penalty;
882
883 return(wss);
884}
885
886
887/* Compartments in parallel */
888double func_pk5(int parNr, double *p, void *fdata)
889{
890 int fi, ret;
891 double Vb, k2, k4, d, wss=0.0;
892 double pa[MAX_PARAMETERS], penalty=1.0;
893
894
895 /* Check parameters against the constraints */
896 ret=modelCheckParameters(parNr, pmin, pmax, p, pa, &penalty);
897 if(fdata) {}
898 /* Calculate individual parameters */
899 k2=pa[CM_K1]/pa[CM_K1K2];
900 k4=pa[CM_K3]/pa[CM_K3K4];
901 Vb=pa[CM_VB];
902
903 /* Simulate the tissue PET TAC */
904 ret=simC3vp(
905 input.x, input.voi[0].y, input.voi[1].y, input.frameNr,
906 pa[CM_K1], k2, pa[CM_K3], k4, pa[CM_K5], 0.0, 0.0, Vb, 1.0,
907 input.voi[0].y2, NULL, NULL, NULL, NULL, NULL);
908 if(ret) {
909 printf("error %d in simulation\n", ret);
910 return(nan(""));
911 }
912
913 /* Interpolate & integrate to measured PET frames */
915 ret=interpolate4pet(
916 input.x, input.voi[0].y2, input.frameNr,
917 dft.x1, dft.x2, petsim, NULL, NULL, fitframeNr);
918 else
919 ret=interpolate(
920 input.x, input.voi[0].y2, input.frameNr,
921 dft.x, petsim, NULL, NULL, fitframeNr);
922 if(ret) {
923 printf("error %d in interpolation\n", ret);
924 return(nan(""));
925 }
926
927 /* Calculate error */
928 for(fi=0, wss=0.0; fi<fitframeNr; fi++) if(dft.w[fi]>0.0) {
929 d=petmeas[fi]-petsim[fi];
930 wss+=dft.w[fi]*d*d;
931 }
932 wss_wo_penalty=wss;
933 wss*=penalty;
934
935 return(wss);
936}
937/*****************************************************************************/
938
939/*****************************************************************************/
944int resK1k2Median(
946 char *filename,
948 double *median,
950 double *mean,
952 char *msg
953) {
954 RES res;
955 int ri, col, n;
956 char *cptr;
957 double *lista;
958
959 /* Read result file */
960 resInit(&res);
961 if(resRead(filename, &res, 0)!=0) {
962 if(msg!=NULL) sprintf(msg, "cannot read %s: %s", filename, reserrmsg);
963 return(1);
964 }
965 /* Which column contains K1/k2 */
966 col=-1; ri=0; cptr=strtok(res.titleline, " \t");
967 while(cptr!=NULL && col<0) {
968 if(strcasecmp(cptr, "K1/k2")==0) col=ri;
969 else if(strcasecmp(cptr, "K1k2")==0) col=ri;
970 ri++; cptr=strtok(NULL, " \t");
971 }
972 if(ri<0) {
973 if(msg!=NULL) sprintf(msg, "K1/k2 not found in %s", filename);
974 resEmpty(&res); return(3);
975 }
976 n=res.voiNr;
977 /* Calculate mean and median */
978 lista=(double*)malloc(n*sizeof(double));
979 for(ri=0; ri<n; ri++) lista[ri]=res.voi[ri].parameter[col];
980 resEmpty(&res);
981 if(mean!=NULL) {
982 *mean=dmean(lista, n, NULL);
983 if(*mean<=0.0) {
984 if(msg!=NULL) sprintf(msg, "invalid K1/k2 mean in %s", filename);
985 free(lista); return(6);
986 }
987 }
988 if(median!=NULL) {
989 *median=dmedian(lista, n);
990 if(*median<=0.0) {
991 if(msg!=NULL) sprintf(msg, "invalid K1/k2 median in %s", filename);
992 free(lista); return(5);
993 }
994 }
995 free(lista);
996 return 0;
997}
998/*****************************************************************************/
999
1000/*****************************************************************************/
double aicSS(double ss, const int n, const int k)
Definition aic.c:20
int bootstrap(int iterNr, double *cLim1, double *cLim2, double *SD, double *parameter, double *lowlim, double *uplim, int frameNr, double *origTac, double *fitTac, double *bsTac, int parNr, double *weight, double(*objf)(int, double *, void *), char *status, int verbose)
Definition bootstrap.c:55
int modelCheckParameters(int par_nr, double *lower_p, double *upper_p, double *test_p, double *accept_p, double *penalty)
Definition constraints.c:15
int atof_with_check(char *double_as_string, double *result_value)
Definition decpoint.c:107
double atof_dpi(char *str)
Definition decpoint.c:59
void dftInit(DFT *data)
Definition dft.c:38
int dftdup(DFT *dft1, DFT *dft2)
Definition dft.c:655
char dfterrmsg[64]
Definition dft.c:6
int dftAddmem(DFT *dft, int voiNr)
Definition dft.c:107
int dftDelete(DFT *dft, int voi)
Definition dft.c:538
void dftEmpty(DFT *data)
Definition dft.c:20
int dftReadReference(DFT *tissue, char *filename, int *filetype, int *ref_index, char *status, int verbose)
Definition dftinput.c:204
int dftReadModelingData(char *tissuefile, char *inputfile1, char *inputfile2, char *inputfile3, double *fitdur, int *fitframeNr, DFT *tis, DFT *inp, FILE *loginfo, int verbose, char *status)
Definition dftinput.c:342
void dftPrint(DFT *data)
Definition dftio.c:538
int dftWrite(DFT *data, char *filename)
Definition dftio.c:594
int res_allocate_with_dft(RES *res, DFT *dft)
Definition dftres.c:14
int iftPutDouble(IFT *ift, char *key, double value, char *cmt_type, int verbose)
Definition ift.c:145
void iftEmpty(IFT *ift)
Definition ift.c:60
void iftInit(IFT *ift)
Definition ift.c:45
int iftRead(IFT *ift, char *filename, int is_key_required, int verbose)
Definition iftfile.c:24
int iftWrite(IFT *ift, char *filename, int verbose)
Definition iftfile.c:282
int iftGetDoubleValue(IFT *ift, int si, const char *key, double *value, int verbose)
Definition iftsrch.c:268
int interpolate(double *x, double *y, int nr, double *newx, double *newy, double *newyi, double *newyii, int newnr)
Linear interpolation and integration.
Definition integr.c:28
int interpolate4pet(double *x, double *y, int nr, double *newx1, double *newx2, double *newy, double *newyi, double *newyii, int newnr)
Interpolate and integrate TAC to PET frames.
Definition integr.c:510
Header file for libtpccurveio.
char reserrmsg[64]
Definition result.c:6
void resInit(RES *res)
Definition result.c:52
void resPrint(RES *res)
Definition result.c:186
int resWrite(RES *res, char *filename, int verbose)
Definition result.c:565
int resRead(char *filename, RES *res, int verbose)
Definition result.c:199
#define DFT_TIME_STARTEND
void resEmpty(RES *res)
Definition result.c:22
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
void tpcProgramName(const char *program, int version, int copyright, char *prname, int n)
Definition proginfo.c:101
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 simC3vp(double *t, double *ca, double *cb, int nr, double k1, double k2, double k3, double k4, double k5, double k6, double f, double vb, double fa, double *cpet, double *cta, double *ctb, double *ctc, double *ctab, double *ctvb)
Definition simulate.c:373
int simC3vs(double *t, double *ca, double *cb, int nr, double k1, double k2, double k3, double k4, double k5, double k6, double f, double vb, double fa, double *cpet, double *cta, double *ctb, double *ctc, double *ctab, double *ctvb)
Definition simulate.c:243
int tgo(double *lowlim, double *uplim, double(*objf)(int, double *, void *), void *objfData, int dim, int neighNr, double *fmin, double *gmin, int samNr, int tgoNr, int verbose)
Definition tgo.c:39
int TGO_LOCAL_INSIDE
Definition tgo.c:29
#define MAX_PARAMETERS
Definition libtpcmodel.h:31
int TGO_SQUARED_TRANSF
Definition tgo.c:27
double dmean(double *data, int n, double *sd)
Definition median.c:73
double dmedian(double *data, int n)
Definition median.c:48
int mean(double *x, double *y, int nr, double *xmean, double *xsd, double *ymean, double *ysd)
Definition pearson.c:341
Header file for libtpcmodext.
int plot_fitrange_svg(DFT *dft1, DFT *dft2, char *main_title, double x1, double x2, double y1, double y2, char *fname, int verbose)
Definition plotfit.c:16
Header file for libtpcsvg.
int timetype
Voi * voi
int timeunit
char studynr[MAX_STUDYNR_LEN+1]
double * w
double * x1
char comments[_DFT_COMMENT_LEN+1]
int voiNr
double * x2
int frameNr
int isweight
double * x
const char * status
Definition libtpcmisc.h:277
char titleline[1024]
int parNr
char parname[MAX_RESPARAMS][MAX_RESPARNAME_LEN+1]
int voiNr
int datanr
ResVOI * voi
double Vb
char program[1024]
char plasmafile[FILENAME_MAX]
char datarange[128]
int isweight
char datafile[FILENAME_MAX]
char reffile[FILENAME_MAX]
char fitmethod[128]
char refroi[64]
char parunit[MAX_RESPARAMS][MAX_RESPARNAME_LEN+1]
char bloodfile[FILENAME_MAX]
time_t time
double parameter[MAX_RESPARAMS]
double cl2[MAX_RESPARAMS]
double cl1[MAX_RESPARAMS]
double sd[MAX_RESPARAMS]
double * y2
char voiname[MAX_REGIONSUBNAME_LEN+1]
char sw
double * y
char name[MAX_REGIONNAME_LEN+1]
double * y3