TPCCLIB
Loading...
Searching...
No Matches
fit_rrtm.c
Go to the documentation of this file.
1
9/*****************************************************************************/
10#include "tpcclibConfig.h"
11/*****************************************************************************/
12#include <stdio.h>
13#include <stdlib.h>
14#include <math.h>
15#include <unistd.h>
16#include <string.h>
17#include <time.h>
18/*****************************************************************************/
19#include "libtpcmisc.h"
20#include "libtpcmodel.h"
21#include "libtpccurveio.h"
22#include "libtpcsvg.h"
23#include "libtpcmodext.h"
24/*****************************************************************************/
25
26/*****************************************************************************/
27const int parNr=3;
28int fitframeNr=0;
29double *t, *cr, *ct, *tis, *w; /* These are pointers, not allocated */
30double pmin[MAX_PARAMS], pmax[MAX_PARAMS];
31double wss_wo_penalty=0.0;
32/* Local functions */
33double rrtmFunc(int parNr, double *p, void*);
34/*****************************************************************************/
35
36/*****************************************************************************/
37static char *info[] = {
38 "NLLSQ estimation of R1 (=K1/K1'), k2, and k3 applying the reduced reference",
39 "tissue compartment model, RRTM (1). This model is based on the reference",
40 "tissue compartment model (2, 3), but here it is assumed that the binding or",
41 "metabolism of tracer is irreversible (k4=0) during the PET scanning.",
42 " ",
43 "Usage: @P [Options] ttacfile reference endtime resultfile",
44 " ",
45 "TTAC file can be in DFT or PMOD format. Sample times must be in minutes.",
46 "If TTAC file contains weights, those are used in the NLLSQ fitting.",
47 "Reference region TAC can be given separate TAC file or as the name or number",
48 "of the reference region in TTAC file.",
49 " ",
50 "Options:",
51 " -lim=<filename>",
52 " Specify the constraints for model parameters;",
53 " This file with default values can be created by giving this option",
54 " as the only command-line argument to this program.",
55 " -SD[=<y|N>]",
56 " Standard deviations are calculated and saved in results (y), or",
57 " not calculated (n).",
58 " -CL[=<y|N>]",
59 " 95% Confidence limits are calculated and saved in results (y), or",
60 " not calculated (n).",
61 " -w1",
62 " All weights are set to 1.0 (no weighting); by default, weights in",
63 " TTAC file are used, if available.",
64 " -wf",
65 " Weight by sampling interval.",
66 " -fit=<Filename>",
67 " Fitted regional TACs are written in file.",
68 " -svg=<Filename>",
69 " Fitted and measured TACs are plotted in specified SVG file.",
70 " -stdoptions", // List standard options like --help, -v, etc
71 " ",
72 " ",
73 "Values of R1, k2, and k3 are written in the specified result file.",
74 "Fitted curves are written in DFT format, if file name is given.",
75 " ",
76 "Example 1: file a789.dft contains regions-of-interest and reference region,",
77 "with name 'cereb'. The whole time range is used in the fit.",
78 "Fitted TACs are plotted in SVG format.",
79 " @P -svg=a789rrtm.svg a789.dft cereb 999 a789.res",
80 " ",
81 "Example 2: Reference region TAC is in a separate file, a789ref.dft.",
82 "Standard deviations and confidence limits are also estimated.",
83 "TAC data from injection to 60 min is used in the fitting.",
84 " @P -SD=y -CL=y a789.dft a789ref.dft 60 a789.res",
85 " ",
86 "Example 3a: Create a file containing default parameter limits:",
87 " @P -lim=rrtm.lim",
88 " ",
89 "Example 3b: Apply user-defined parameter constraints specified in rrtm.lim:",
90 " @P -lim=rrtm.lim a789.dft cereb 999 a789.res",
91
92 "References:",
93 "1. Oikonen V. Model equations for reference tissue compartmental models.",
94 " https://www.turkupetcentre.net/reports/tpcmod0002.pdf",
95 "2. Cunningham VJ, Hume SP, Price GR, Ahier RG, Cremer JE, Jones AKP.",
96 " Compartmental analysis of diprenorphine binding to opiate receptors",
97 " in the rat in vivo and its comparison with equilibrium data in vitro.",
98 " J Cereb Blood Flow Metab 1991;11:1-9.",
99 "3. Lammertsma AA, Hume SP. Simplified reference tissue model for PET",
100 " receptor studies. NeuroImage 1996;4:153-158.",
101 " ",
102 "See also: patlak, fitk3, tacweigh, rescoll, sim_rtcm, fit_trtm",
103 " ",
104 "Keywords: TAC, modelling, irreversible uptake, RTCM, reference input",
105 0};
106/*****************************************************************************/
107
108/*****************************************************************************/
109/* Turn on the globbing of the command line, since it is disabled by default in
110 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
111 In Unix&Linux wildcard command line processing is enabled by default. */
112/*
113#undef _CRT_glob
114#define _CRT_glob -1
115*/
116int _dowildcard = -1;
117/*****************************************************************************/
118
119/*****************************************************************************/
123int main(int argc, char **argv)
124{
125 int ai, help=0, version=0, verbose=1;
126 char rtacfile[FILENAME_MAX], ttacfile[FILENAME_MAX], resfile[FILENAME_MAX],
127 fitfile[FILENAME_MAX], svgfile[FILENAME_MAX], limfile[FILENAME_MAX];
128 char *cptr, tmp[256];
129 double fitdur=nan("");
130 int weights=0; // 0=default, 1=no weighting, 2=frequency
131 int doBootstrap=0, doSD=0, doCL=0;
132 double *sd, *cl1, *cl2;
133 double def_pmin[MAX_PARAMETERS], def_pmax[MAX_PARAMETERS];
134 int ret, n;
135
136
137 /* Set parameter initial values and constraints */
138 /* R1 */ def_pmin[0]=0.001; def_pmax[0]=2.0;
139 /* k2 */ def_pmin[1]=0.000001; def_pmax[1]=0.5;
140 /* k3 */ def_pmin[2]=0.0; def_pmax[2]=1.0;
141
142 /*
143 * Get arguments
144 */
145 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
146 rtacfile[0]=ttacfile[0]=resfile[0]=fitfile[0]=svgfile[0]=limfile[0]=(char)0;
147 /* Get options first, because it affects what arguments are read */
148 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
149 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
150 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
151 if(strncasecmp(cptr, "CL", 2)==0) {
152 if(strlen(cptr)==2) {doCL=1; continue;}
153 cptr+=2; if(*cptr=='=') {
154 cptr++;
155 if(*cptr=='Y' || *cptr=='y') {doCL=1; continue;}
156 if(*cptr=='N' || *cptr=='n') {doCL=0; continue;}
157 }
158 } else if(strncasecmp(cptr, "SD", 2)==0) {
159 if(strlen(cptr)==2) {doSD=1; continue;}
160 cptr+=2; if(*cptr=='=') {
161 cptr++;
162 if(*cptr=='Y' || *cptr=='y') {doSD=1; continue;}
163 if(*cptr=='N' || *cptr=='n') {doSD=0; continue;}
164 }
165 } else if(strncasecmp(cptr, "LIM=", 4)==0 && strlen(cptr)>4) {
166 strlcpy(limfile, cptr+4, FILENAME_MAX); continue;
167 } else if(strcasecmp(cptr, "LIM")==0) {
168 strcpy(limfile, "stdout"); continue;
169 } else if(strcasecmp(cptr, "W1")==0) {
170 weights=1; continue;
171 } else if(strcasecmp(cptr, "WF")==0) {
172 weights=2; continue;
173 } else if(strncasecmp(cptr, "FIT=", 4)==0) {
174 strlcpy(fitfile, cptr+4, FILENAME_MAX); if(strlen(fitfile)>0) continue;
175 } else if(strncasecmp(cptr, "SVG=", 4)==0) {
176 strlcpy(svgfile, cptr+4, FILENAME_MAX); if(strlen(svgfile)>0) continue;
177 }
178 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
179 return(1);
180 } else break;
181
182 /* Print help or version? */
183 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
184 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
185 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
186
187 /* Process other arguments, starting from the first non-option */
188 if(ai<argc) strlcpy(ttacfile, argv[ai++], FILENAME_MAX);
189 if(ai<argc) strlcpy(rtacfile, argv[ai++], FILENAME_MAX);
190 if(ai<argc) {
191 if(atof_with_check(argv[ai], &fitdur)!=0 || fitdur<0.0) {
192 fprintf(stderr, "Error: invalid fit time: '%s'.\n", argv[ai]);
193 return(1);
194 }
195 if(fitdur==0) fitdur=1.0E+10;
196 ai++;
197 }
198 if(ai<argc) strlcpy(resfile, argv[ai++], FILENAME_MAX);
199 if(ai<argc) {
200 fprintf(stderr, "Error: invalid argument '%s'.\n", argv[ai]);
201 return(1);
202 }
203 if(doSD || doCL) doBootstrap=1; else doBootstrap=0;
204
205 /* In verbose mode print arguments and options */
206 if(verbose>1) {
207 printf("ttacfile := %s\n", ttacfile);
208 printf("reference := %s\n", rtacfile);
209 printf("resfile := %s\n", resfile);
210 printf("fitfile := %s\n", fitfile);
211 printf("svgfile := %s\n", svgfile);
212 printf("limfile := %s\n", limfile);
213 printf("required_fittime := %g min\n", fitdur);
214 printf("weights := %d\n", weights);
215 printf("doBootstrap := %d\n", doBootstrap);
216 printf("doSD := %d\n", doSD);
217 printf("doCL := %d\n", doCL);
218 }
219
220 /* If only file name for parameter constraints was given, then write one
221 with default contents, and exit */
222 if(limfile[0] && !ttacfile[0]) {
223 /* Check that initial value file does not exist */
224 if(strcasecmp(limfile, "stdout")!=0 && access(limfile, 0) != -1) {
225 fprintf(stderr, "Error: parameter constraint file %s exists.\n", limfile);
226 return(9);
227 }
228 if(verbose>1 && strcasecmp(limfile, "stdout")!=0)
229 printf("writing parameter constraints file\n");
230 /* Create parameter file */
231 IFT ift; iftInit(&ift);
232 iftPutDouble(&ift, "R1_lower", def_pmin[0], NULL, 0);
233 iftPutDouble(&ift, "R1_upper", def_pmax[0], NULL, 0);
234 iftPutDouble(&ift, "k2_lower", def_pmin[1], NULL, 0);
235 iftPutDouble(&ift, "k2_upper", def_pmax[1], NULL, 0);
236 iftPutDouble(&ift, "k3_lower", def_pmin[2], NULL, 0);
237 iftPutDouble(&ift, "k3_upper", def_pmax[2], NULL, 0);
238 ret=iftWrite(&ift, limfile, 0);
239 if(ret) {
240 fprintf(stderr, "Error in writing '%s': %s\n", limfile, ift.status);
241 iftEmpty(&ift); return(9);
242 }
243 if(strcasecmp(limfile, "stdout")!=0)
244 fprintf(stdout, "Parameter file %s with initial values written.\n", limfile);
245 iftEmpty(&ift); return(0);
246 }
247
248
249 /* Did we get all the information that we need? */
250 if(!resfile[0]) {
251 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
252 return(1);
253 }
254
255 /*
256 * Read model parameter upper and lower limits
257 * if file for that was given
258 */
259 if(limfile[0]) {
260 if(verbose>1) printf("reading %s\n", limfile);
261 IFT ift; iftInit(&ift);
262 double v;
263 ret=iftRead(&ift, limfile, 1, 0);
264 if(ret) {
265 fprintf(stderr, "Error in reading '%s': %s\n", limfile, ift.status);
266 return(9);
267 }
268 if(verbose>10) iftWrite(&ift, "stdout", 0);
269 int n=0;
270 if(iftGetDoubleValue(&ift, 0, "R1_lower", &v, 0)>=0) {def_pmin[0]=v; n++;}
271 if(iftGetDoubleValue(&ift, 0, "R1_upper", &v, 0)>=0) {def_pmax[0]=v; n++;}
272 if(iftGetDoubleValue(&ift, 0, "k2_lower", &v, 0)>=0) {def_pmin[1]=v; n++;}
273 if(iftGetDoubleValue(&ift, 0, "k2_upper", &v, 0)>=0) {def_pmax[1]=v; n++;}
274 if(iftGetDoubleValue(&ift, 0, "k3_lower", &v, 0)>=0) {def_pmin[2]=v; n++;}
275 if(iftGetDoubleValue(&ift, 0, "k3_upper", &v, 0)>=0) {def_pmax[2]=v; n++;}
276 iftEmpty(&ift);
277 if(n==0) {fprintf(stderr, "Error: invalid parameter file.\n"); return(9);}
278 }
279 /* Check that these are ok */
280 n=0; ret=0;
281 for(int pi=0; pi<parNr; pi++) {
282 if(verbose>3) printf(" %d %g %g\n", pi+1, def_pmin[pi], def_pmax[pi]);
283 if(def_pmin[pi]<0.0) ret++;
284 if(def_pmax[pi]<def_pmin[pi]) ret++;
285 if(def_pmax[pi]>def_pmin[pi]) n++;
286 if(verbose>3 && ret>0) printf(" -> invalid\n");
287 }
288 if(ret!=0) {
289 fprintf(stderr, "Error: invalid parameter constraints.\n");
290 return(9);
291 }
292 if(n==0) {
293 fprintf(stderr, "Error: no model parameters left free for fitting.\n");
294 return(9);
295 }
296 if(verbose>1) {
297 printf("Parameter constraints:\n");
298 for(int pi=0; pi<parNr; pi++) {
299 printf("def_pmin[%d] := %g\n", pi+1, def_pmin[pi]);
300 printf("def_pmax[%d] := %g\n", pi+1, def_pmax[pi]);
301 }
302 }
303
304
305
306 /*
307 * Read TTAC file
308 */
309 if(verbose>1) printf("reading %s\n", ttacfile);
310 DFT dft; dftInit(&dft);
311 if(dftRead(ttacfile, &dft)) {
312 fprintf(stderr, "Error in reading '%s': %s\n", ttacfile, dfterrmsg);
313 return(2);
314 }
315 /* Check for NA's */
316 if(dft_nr_of_NA(&dft) > 0) {
317 fprintf(stderr, "Error: missing sample(s) in %s\n", ttacfile);
318 dftEmpty(&dft); return(2);
319 }
320 /* Sort the data by increasing sample times */
321 dftSortByFrame(&dft);
322 /* Set time unit to min */
323 ret=dftTimeunitConversion(&dft, TUNIT_MIN);
324 if(ret) fprintf(stderr, "Warning: check that regional data times are in minutes.\n");
325 /* Remove frame overlaps and gaps */
326 if(dft.timetype==DFT_TIME_STARTEND) {
327 if(verbose>2) fprintf(stdout, "checking frame overlap in %s\n", ttacfile);
328 ret=dftDeleteFrameOverlap(&dft);
329 if(ret) {
330 fprintf(stderr, "Error: %s has overlapping frame times.\n", ttacfile);
331 dftEmpty(&dft); return(2);
332 }
333 }
334 /* Set fit duration */
335 int first, last;
336 double starttime, endtime;
337 starttime=0.0; endtime=fitdur;
338 fitframeNr=fittime_from_dft(&dft, &starttime, &endtime, &first, &last, verbose-2);
339 if(fitframeNr<5) {
340 fprintf(stderr, "Error: too few data points for a decent fit.\n");
341 dftEmpty(&dft); return(2);
342 }
343 if(verbose>2) {
344 printf("dft.frameNr := %d\n", dft.frameNr);
345 printf("starttime := %g\n", starttime);
346 printf("endtime := %g\n", endtime);
347 printf("first := %d\n", first);
348 printf("last := %d\n", last);
349 printf("fitframeNr := %d\n", fitframeNr);
350 }
351 fitdur=endtime;
352 /* Check that there is not any significant delay in the beginning of the data */
353 if(dft.timetype==DFT_TIME_STARTEND) {
354 if(dft.x1[0]>0.45) {
355 fprintf(stderr, "Error: TACs must start at time zero.\n");
356 dftEmpty(&dft); return(2);
357 }
358 if(dft.x1[0]>0.0833333) {
359 fprintf(stderr, "Warning: TACs should start at time zero.\n");
360 }
361 }
362 if(verbose>2) printf("Tissue calibration unit := %s\n", dft.unit);
363
364 /* Add data weights, if requested */
365 if(weights==1) {
366 dft.isweight=0;
367 for(int i=0; i<dft.frameNr; i++) dft.w[i]=1.0;
368 } else if(weights==2) {
369 if(dftWeightByFreq(&dft)!=0) {
370 fprintf(stderr, "Error: cannot set data weights.\n");
371 dftEmpty(&dft); return(2);
372 }
373 } else if(dft.isweight==0) {
374 fprintf(stderr, "Warning: data is not weighted.\n");
375 }
376 /* Print the weights */
377 if(verbose>2) {
378 fprintf(stdout, "common_data_weights := %g", dft.w[0]);
379 for(int i=1; i<dft.frameNr; i++) fprintf(stdout, ", %g", dft.w[i]);
380 fprintf(stdout, "\n");
381 }
382
383
384 /*
385 * Read reference TAC
386 */
387 if(verbose>1) printf("\nreading reference\n");
388 int inputtype=-1, ref=-1;
389 ret=dftReadReference(&dft, rtacfile, &inputtype, &ref, tmp, verbose-1);
390 if(ret<=0) {
391 fprintf(stderr, "Error in reading reference input: %s\n", tmp);
392 dftEmpty(&dft); if(verbose>1) printf("ret := %d\n", ret);
393 return(3);
394 }
395 if(ret>1) {
396 fprintf(stderr, "Warning: several reference regions found: %s selected.\n", dft.voi[ref].name);
397 } else if(verbose>1) printf("reference_region := %s\n", dft.voi[ref].name);
398 if(verbose>2) printf("inputtype := %d\n", inputtype);
399
400 /* Allocate an extra TAC for the bootstrap */
401 int bsi=-1;
402 if(doBootstrap) {
403 ret=dftAddmem(&dft, 1); if(ret) {
404 fprintf(stderr, "Error: cannot allocate more memory.\n");
405 dftEmpty(&dft); return(4);
406 }
407 bsi=dft.voiNr;
408 strcpy(dft.voi[bsi].voiname, "BS");
409 strcpy(dft.voi[bsi].name, "BS");
410 }
411
412
413
414 /*
415 * Prepare the room for results
416 */
417 if(verbose>1) printf("initializing result data\n");
418 RES res; resInit(&res);
419 ret=res_allocate_with_dft(&res, &dft); if(ret!=0) {
420 fprintf(stderr, "Error: cannot set-up memory for results.\n");
421 dftEmpty(&dft); return(4);
422 }
423 /* Copy titles & filenames */
424 tpcProgramName(argv[0], 1, 1, res.program, 256);
425 strcpy(res.datafile, ttacfile);
426 if(inputtype!=5 && rtacfile[0]) strcpy(res.reffile, rtacfile);
427 if(ref>=0) strcpy(res.refroi, dft.voi[ref].name);
428 strcpy(res.fitmethod, "TGO");
429 /* Constants */
430 res.isweight=dft.isweight;
431 /* Set data range */
432 sprintf(res.datarange, "%g - %g %s", 0.0, fitdur, petTunit(dft.timeunit));
433 res.datanr=fitframeNr;
434 /* Set current time to results */
435 res.time=time(NULL);
436 /* Set parameter number, including also the extra "parameters"
437 and the parameter names and units */
438 res.parNr=4;
439 {
440 int pi;
441 pi=0; strcpy(res.parname[pi], "R1"); strcpy(res.parunit[pi], "");
442 pi++; strcpy(res.parname[pi], "k2"); strcpy(res.parunit[pi], "1/min");
443 pi++; strcpy(res.parname[pi], "k3"); strcpy(res.parunit[pi], "1/min");
444 pi++; strcpy(res.parname[pi], "WSS"); strcpy(res.parunit[pi], "");
445 }
446
447
448
449 /*
450 * Fit one VOI at a time
451 */
452 if(verbose>0) printf("\nfitting...\n");
453 int tgoNr=0, neighNr=0, iterNr=0;
454 double wss;
455 /* Set common data pointers */
456 t=dft.x; cr=dft.voi[ref].y;
457 /* Fit model to one TAC at a time */
458 for(int ri=0; ri<dft.voiNr; ri++) if(ri!=ref) {
459
460 if(verbose>1) printf("Region %d %s\n", ri+1, dft.voi[ri].name);
461 /* Set data pointers */
462 tis=dft.voi[ri].y; ct=dft.voi[ri].y2; w=dft.w;
463 double *p=res.voi[ri].parameter;
464
465 /* Set common parameter constraints */
466 for(int pi=0; pi<parNr; pi++) {pmin[pi]=def_pmin[pi]; pmax[pi]=def_pmax[pi];}
467 if(verbose>30) {
468 printf("Parameter constraints:\n");
469 for(int pi=0; pi<parNr; pi++) printf(" %10.3E - %10.3E\n", pmin[pi], pmax[pi]);
470 }
471
472 /* Fit */
473 if(verbose>2) printf(" fitting curve...\n");
476 tgoNr=220;
477 neighNr=20;
478 ret=tgo(pmin, pmax, rrtmFunc, NULL, parNr, neighNr, &wss, p, tgoNr, iterNr, verbose-8);
479 if(ret>0) {
480 fprintf(stderr, "Error in optimization (%d).\n", ret);
481 dftEmpty(&dft); resEmpty(&res); return(6);
482 }
483 if(verbose>3) {
484 for(int pi=0; pi<parNr; pi++) printf(" %g", p[pi]);
485 printf(" -> WSS=%g\n", p[parNr]); fflush(stdout);
486 }
487 /* Correct fitted parameters to match constraints like inside the function */
488 (void)modelCheckParameters(parNr, pmin, pmax, p, p, NULL);
489 p[parNr]=wss=wss_wo_penalty;
490 if(verbose>2) printf("wss := %g\nfitframeNr := %d\n", wss, fitframeNr);
491
492 /* Bootstrap */
493 if(doBootstrap) {
494 if(verbose>2) printf(" bootstrapping...\n");
495 /* bootstrap changes measured and simulated data, therefore use copies */
496 tis=dft.voi[bsi].y; ct=dft.voi[bsi].y2;
497 if(doSD) sd=res.voi[ri].sd; else sd=NULL;
498 if(doCL) {cl1=res.voi[ri].cl1; cl2=res.voi[ri].cl2;} else cl1=cl2=NULL;
499 ret=bootstrap(
500 0, cl1, cl2, sd, p, pmin, pmax, fitframeNr,
501 // measured and fitted original TAC, not modified
502 dft.voi[ri].y, dft.voi[ri].y2,
503 // tissue TAC noisy data is written to be used by objf
504 tis,
505 parNr, w, rrtmFunc, tmp, verbose-5
506 );
507 if(ret) {
508 fprintf(stderr, "Error in bootstrap: %s\n", tmp);
509 for(int pi=0; pi<parNr; pi++) {
510 if(doSD) sd[pi]=nan("");
511 if(doCL) cl1[pi]=cl2[pi]=nan("");
512 }
513 }
514 // back to what pointers were
515 tis=dft.voi[ri].y; tis=dft.voi[ri].y2;
516 }
517
518 } /* Next VOI */
519 if(verbose>0) {fprintf(stdout, "\n"); fflush(stdout);}
520
521 /* Delete the reference region from the results */
522 resDelete(&res, ref);
523 /* If reference data file was given and it contained several TACs then delete those too */
524 if(inputtype!=5) {
525 for(int i=dft.voiNr-1; i>=0; i--) if(dft.voi[i].sw!=0) resDelete(&res, i);
526 }
527
528 /*
529 * Print results on screen
530 */
531 if(verbose>0) {resPrint(&res); fprintf(stdout, "\n");}
532
533
534 /*
535 * Save results
536 */
537 if(verbose>1) printf("saving results in %s\n", resfile);
538 ret=resWrite(&res, resfile, verbose-5);
539 if(ret) {
540 fprintf(stderr, "Error in writing '%s': %s\n", resfile, reserrmsg);
541 resEmpty(&res); dftEmpty(&dft);
542 return(11);
543 }
544 if(verbose>0) fprintf(stdout, "Model parameters written in %s\n", resfile);
545
546
547
548 /*
549 * Saving and/or plotting of fitted TACs
550 */
551 if(svgfile[0] || fitfile[0]) {
552
553 /* Create a DFT containing fitted TACs */
554 char tmp[64];
555 DFT dft2;
556 dftInit(&dft2); ret=dftdup(&dft, &dft2);
557 if(ret) {
558 fprintf(stderr, "Error: cannot save fitted curves.\n");
559 dftEmpty(&dft); resEmpty(&res);
560 return(21);
561 }
562 for(int ri=0; ri<dft.voiNr; ri++)
563 if(ri!=ref)
564 for(int fi=0; fi<fitframeNr; fi++)
565 dft2.voi[ri].y[fi]=dft2.voi[ri].y2[fi];
566 dft2.frameNr=fitframeNr;
567
568 /* Save SVG plot of fitted and original data */
569 if(svgfile[0]) {
570 if(verbose>1) printf("saving SVG plot\n");
571 sprintf(tmp, "RRTM fit ");
572 if(strlen(dft.studynr)>0) strcat(tmp, dft.studynr);
573 ret=plot_fitrange_svg(&dft, &dft2, tmp, 0.0, 1.02*dft.x[fitframeNr-1],
574 0.0, nan(""), svgfile, verbose-8);
575 if(ret) {
576 fprintf(stderr, "Error (%d) in writing '%s'.\n", ret, svgfile);
577 dftEmpty(&dft2); dftEmpty(&dft); resEmpty(&res);
578 return(30+ret);
579 }
580 if(verbose>0) printf("Plots written in %s\n", svgfile);
581 }
582
583 /* Delete reference region(s) from the data, unless it already existed in data */
584 if(inputtype!=5) {
585 for(int i=dft2.voiNr-1; i>=0; i--) if(dft2.voi[i].sw!=0) dftDelete(&dft2, i);
586 }
587
588 /* Save fitted TACs */
589 if(fitfile[0]) {
590 if(verbose>1) printf("saving fitted curves\n");
591 tpcProgramName(argv[0], 1, 0, tmp, 128);
592 sprintf(dft2.comments, "# program := %s\n", tmp);
593 if(dftWrite(&dft2, fitfile)) {
594 fprintf(stderr, "Error in writing '%s': %s\n", fitfile, dfterrmsg);
595 dftEmpty(&dft2); dftEmpty(&dft); resEmpty(&res);
596 return(22);
597 }
598 if(verbose>0) printf("Fitted TACs written in %s\n", fitfile);
599 }
600
601 dftEmpty(&dft2);
602 }
603
604
605 resEmpty(&res);
606 dftEmpty(&dft);
607
608 return(0);
609}
610/*****************************************************************************/
611
612/*****************************************************************************
613 *
614 * Functions to be minimized
615 *
616 *****************************************************************************/
617double rrtmFunc(int parNr, double *p, void *fdata)
618{
619 int ret;
620 double R1, k2, k3, d, wss=0.0;
621 double pa[MAX_PARAMETERS], penalty=1.0;
622
623
624 /* Check parameters against the constraints */
625 ret=modelCheckParameters(parNr, pmin, pmax, p, pa, &penalty);
626 if(fdata) {}
627 /* Get parameters */
628 R1=pa[0]; k2=pa[1]; k3=pa[2];
629
630 /* Simulate the tissue PET TAC */
631 ret=simRTCM(t, cr, fitframeNr, R1, k2, k3, 0.0, ct, NULL, NULL);
632 if(ret) {
633 fprintf(stderr, " error %d in simulation\n", ret);
634 return(nan(""));
635 }
636
637 /* Calculate error */
638 for(int i=0; i<fitframeNr; i++) if(w[i]>0.0) {
639 d=ct[i]-tis[i];
640 wss+=w[i]*d*d;
641 }
642 wss_wo_penalty=wss;
643 wss*=penalty;
644 if(0) printf("R1=%g k2=%g k3=%g => %g\n", R1, k2, k3, wss);
645
646 return(wss);
647}
648/*****************************************************************************/
649
650/*****************************************************************************/
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
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 dftDeleteFrameOverlap(DFT *dft)
Definition dft.c:1237
int dftAddmem(DFT *dft, int voiNr)
Definition dft.c:107
int dftSortByFrame(DFT *dft)
Definition dft.c:1169
int dftDelete(DFT *dft, int voi)
Definition dft.c:538
void dftEmpty(DFT *data)
Definition dft.c:20
int dft_nr_of_NA(DFT *dft)
Definition dft.c:905
int dftReadReference(DFT *tissue, char *filename, int *filetype, int *ref_index, char *status, int verbose)
Definition dftinput.c:204
int dftRead(char *filename, DFT *data)
Definition dftio.c:22
int dftWrite(DFT *data, char *filename)
Definition dftio.c:594
int res_allocate_with_dft(RES *res, DFT *dft)
Definition dftres.c:14
int dftTimeunitConversion(DFT *dft, int tunit)
Definition dftunit.c:119
int fittime_from_dft(DFT *dft, double *startTime, double *endTime, int *first, int *last, int verbose)
Definition fittime.c:16
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
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 resDelete(RES *res, int voi)
Definition result.c:1342
#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
char * petTunit(int tunit)
Definition petunits.c:226
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 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
#define MAX_PARAMS
Definition libtpcmodel.h:35
int simRTCM(double *t, double *cr, int nr, double R1, double k2, double k3, double k4, double *ct, double *cta, double *ctb)
Definition simulate.c:835
Header file for libtpcmodext.
int dftWeightByFreq(DFT *dft)
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
int frameNr
int isweight
double * x
char unit[MAX_UNITS_LEN+1]
const char * status
Definition libtpcmisc.h:277
int parNr
char parname[MAX_RESPARAMS][MAX_RESPARNAME_LEN+1]
int datanr
ResVOI * voi
char program[1024]
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]
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]