TPCCLIB
Loading...
Searching...
No Matches
fit_hiad.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 <math.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/*****************************************************************************/
25double func1821(int parNr, double *p, void*);
26double func1801(int parNr, double *p, void*);
27/*****************************************************************************/
28double (*func)(int parNr, double *p, void*);
29double *x, *ymeas, *yfit, *w; /* Local */
30int dataNr=0, parNr=5;
31double pmin[MAX_PARAMETERS], pmax[MAX_PARAMETERS];
32double dlowtime;
33/*****************************************************************************/
34
35/*****************************************************************************/
36static char *info[] = {
37 "Non-linear fitting of the sum of Hill and Hill derivative function to",
38 "the PET time-activity curves (TACs):",
39 "f(x) = A * { [n*xt^(n-1)]/[h^n+xt^n] - [n*xt^(2*n-1)]/[h^n+xt^n]^2 ",
40 " + [k*xt^n]/[h^n+xt^n] }",
41 ", where xt=x-dt and n>=1.",
42 " ",
43 "Usage: @P [Options] tacfile [parfile]",
44 " ",
45 "Options:",
46 " -Hill",
47 " Hill function without the Hill derivative function is used;",
48 " f(x) = (A*xt^n)/(h^n+xt^n).",
49 " -w1 All weights are set to 1.0 (no weighting); by default, weights in",
50 " data file are used, if available.",
51 " -wf",
52 " Weight by sampling interval.",
53 " -k=<value>",
54 " Parameter k is constrained to given value; setting k to zero causes",
55 " the function to approach zero.",
56 " -n=<value>",
57 " Parameter n (HillSlope) is constrained to the given value;",
58 " n<1 is not allowed.",
59 " -delay=<<value>|mean|median>",
60 " Delay time (dt) is constrained to specified value or to mean or median",
61 " of all TACs.",
62/*" -dlow=<time>",
63 " Penalize Hill derivative higher than 1% of total tissue activity",
64 " after specified time",*/
65 " -MRL",
66 " Error is returned if MRL check is not passed.",
67 " -res=<Filename>",
68 " Fitted parameters are also written in result file format.",
69 " -svg=<Filename>",
70 " Fitted and measured TACs are plotted in specified SVG file.",
71 " -fit=<Filename>",
72 " Fitted TACs are written in TAC format.",
73 " -stdoptions", // List standard options like --help, -v, etc
74 " ",
75 "TAC file must contain at least 2 columns, sample times (x) and",
76 "concentrations (y).",
77 "Weights can be specified as usual if data is in DFT format.",
78 " ",
79 "Program writes the fit start and end times, nr of points, WSS,",
80 "and parameters of the fitted function to the fit file.",
81 " ",
82 "See also: fit2dat, fit_sigm, fit_bpr, fit_ppf, fit_exp, fit_ratf",
83 " ",
84 "Keywords: curve fitting, Hill function",
85 0};
86/*****************************************************************************/
87
88/*****************************************************************************/
89/* Turn on the globbing of the command line, since it is disabled by default in
90 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
91 In Unix&Linux wildcard command line processing is enabled by default. */
92/*
93#undef _CRT_glob
94#define _CRT_glob -1
95*/
96int _dowildcard = -1;
97/*****************************************************************************/
98
99/*****************************************************************************/
103int main(int argc, char **argv)
104{
105 int ai, help=0, version=0, verbose=1;
106 int fi, pi, ri, m, n, ret;
107 int type=1821; // 1821 or 1801
108 int weights=0; // 0=default, 1=no weighting, 2=frequency
109 double fixed_n=nan("");
110 double fixed_k=nan("");
111 double fixed_delay=nan("");
112 int MRL_check=0; // 0=off, 1=on
113 int fix_delay=0; // 0: not fixed; 1: fixed to given value;
114 // 2: fixed to mean; 3: fixed to median.
115 char datfile[FILENAME_MAX], fitfile[FILENAME_MAX], parfile[FILENAME_MAX],
116 svgfile[FILENAME_MAX], resfile[FILENAME_MAX], *cptr, temp[512];
117 char progname[256];
118 DFT dft;
119 FIT fit;
120 double tstart, tstop, miny, maxy, maxt;
121 int tgo_nr, iter_nr, neigh_nr;
122 double def_pmin[MAX_PARAMETERS], def_pmax[MAX_PARAMETERS];
123
124 /*
125 * Set defaults for parameter constraints
126 */
127 dlowtime=nan("");
128 /* delay */ def_pmin[0]=0.0; def_pmax[0]=0.0; // set later
129 /* A */ def_pmin[1]=1.0E-06; def_pmax[1]=1.0E+06; // set later
130 /* h */ def_pmin[2]=1.0E-06; def_pmax[2]=200.0; // set later
131 /* n */ def_pmin[3]=1.0; def_pmax[3]=10.0;
132 /* k */ def_pmin[4]=0.0; def_pmax[4]=20.0; // set later
133
134
135 /*
136 * Get arguments
137 */
138 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
139 datfile[0]=fitfile[0]=parfile[0]=svgfile[0]=resfile[0]=(char)0;
140 dftInit(&dft); fitInit(&fit);
141 tpcProgramName(argv[0], 1, 1, progname, 256);
142 /* Options */
143 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
144 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
145 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
146 if(strcasecmp(cptr, "W1")==0) {
147 weights=1; continue;
148 } else if(strcasecmp(cptr, "WF")==0) {
149 weights=2; continue;
150 } else if(strcasecmp(cptr, "HILL")==0) {
151 type=1801; parNr=4; continue;
152 } else if(strncasecmp(cptr, "N=", 2)==0) {
153 if(!atof_with_check(cptr+2, &fixed_n) && fixed_n>0.0) {
154 def_pmin[3]=def_pmax[3]=fixed_n; continue;
155 }
156 } else if(strncasecmp(cptr, "k=", 2)==0 && strlen(cptr)>2) {
157 if(!atof_with_check(cptr+2, &fixed_k) && fixed_k>=0.0) {
158 def_pmin[4]=def_pmax[4]=fixed_k; continue;
159 }
160 } else if(strncasecmp(cptr, "DELAY=", 6)==0 && strlen(cptr)>6) {
161 cptr+=6;
162 if(strcasecmp(cptr, "MEAN")==0) {fix_delay=2; continue;}
163 else if(strncasecmp(cptr, "AVERAGE", 2)==0) {fix_delay=2; continue;}
164 if(strcasecmp(cptr, "MEDIAN")==0) {fix_delay=3; continue;}
165 if(!atof_with_check(cptr, &fixed_delay)) {
166 fix_delay=1; def_pmin[0]=def_pmax[0]=fixed_delay;
167 continue;
168 }
169 } else if(strncasecmp(cptr, "DLOW=", 5)==0) {
170 if(!atof_with_check(cptr+5, &dlowtime) && dlowtime>0.0) continue;
171 } else if(strcasecmp(cptr, "MRL")==0) {
172 MRL_check=1; continue;
173 } else if(strncasecmp(cptr, "SVG=", 4)==0 && strlen(cptr)>4) {
174 strcpy(svgfile, cptr+4); continue;
175 } else if(strncasecmp(cptr, "FIT=", 4)==0 && strlen(cptr)>4) {
176 strcpy(fitfile, cptr+4); continue;
177 } else if(strncasecmp(cptr, "RES=", 4)==0 && strlen(cptr)>4) {
178 strcpy(resfile, cptr+4); continue;
179 }
180 fprintf(stderr, "Error: invalid option '%s'\n", argv[ai]);
181 return(1);
182 } else break;
183
184 /* Print help or version? */
185 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
186 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
187 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
188
189 /* Process other arguments, starting from the first non-option */
190 for(; ai<argc; ai++) {
191 if(!datfile[0]) {strcpy(datfile, argv[ai]); continue;}
192 else if(!parfile[0]) {strcpy(parfile, argv[ai]); continue;}
193 fprintf(stderr, "Error: invalid argument '%s'\n", argv[ai]);
194 return(1);
195 }
196 if(!parfile[0]) strcpy(parfile, "stdout");
197 if(type==1821) func=func1821; else func=func1801;
198
199
200 /* Is something missing? */
201 if(!datfile[0]) {
202 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
203 return(1);
204 }
205
206 /* In verbose mode print arguments and options */
207 if(verbose>1) {
208 printf("datfile := %s\n", datfile);
209 printf("parfile := %s\n", parfile);
210 printf("fitfile := %s\n", fitfile);
211 printf("resfile := %s\n", resfile);
212 printf("svgfile := %s\n", svgfile);
213 printf("MRL_check := %d\n", MRL_check);
214 if(!isnan(fixed_n)) printf("fixed_n := %g\n", fixed_n);
215 if(!isnan(fixed_k)) printf("fixed_k := %g\n", fixed_k);
216 if(!isnan(dlowtime)) printf("dlowtime := %g\n", dlowtime);
217 printf("fix_delay := %d\n", fix_delay);
218 if(fix_delay==1) printf("fixed_delay := %g\n", fixed_delay);
219 printf("type := %d\n", type);
220 printf("weights := %d\n", weights);
221 }
222
223
224 /*
225 * Read data
226 */
227 if(verbose>1) printf("reading %s\n", datfile);
228 if(dftRead(datfile, &dft)) {
229 fprintf(stderr, "Error in reading '%s': %s\n", datfile, dfterrmsg);
230 return(2);
231 }
232 dataNr=dft.frameNr;
233
234 /* Sort the samples by time in case data is catenated from several curves */
235 (void)dftSortByFrame(&dft);
236 if(verbose>30) dftPrint(&dft);
237
238 /* Get min and max X and Y */
239 ret=dftMinMax(&dft, &tstart, &tstop, &miny, &maxy);
240 if(ret!=0) {
241 fprintf(stderr, "Error: invalid contents in %s\n", datfile);
242 dftEmpty(&dft); return(2);
243 }
244 if(tstop<=0.0 || maxy<=0.0) {
245 fprintf(stderr, "Error: invalid contents in %s\n", datfile);
246 dftEmpty(&dft); return(2);
247 }
248 if(tstart<0.0) fprintf(stderr, "Warning: negative x value(s).\n");
249 if(miny<0.0) fprintf(stderr, "Warning: negative y value(s).\n");
250
251 /* Check and set weights */
252 if(weights==0) {
253 if(dft.isweight==0) {
254 dft.isweight=1; for(fi=0; fi<dft.frameNr; fi++) dft.w[fi]=1.0;}
255 } else if(weights==1) {
256 dft.isweight=1; for(fi=0; fi<dft.frameNr; fi++) dft.w[fi]=1.0;
257 } else if(weights==2) {
258 dftWeightByFreq(&dft);
259 }
260 for(fi=0; fi<dft.frameNr; fi++) if(isnan(dft.voi[0].y[fi])) dft.w[fi]=0;
261 if(verbose>2) {
262 printf("data_weights := %g", dft.w[0]);
263 for(fi=1; fi<dft.frameNr; fi++) printf(", %g", dft.w[fi]);
264 printf("\n");
265 }
266
267 /*
268 * If only one TAC to fit, ignore delay fixed to mean or median
269 */
270 if(dft.voiNr==1 && (fix_delay==2 || fix_delay==3)) {
271 fprintf(stderr, "Note: delay setting ignored because only one TAC to fit.\n");
272 fix_delay=0;
273 }
274
275 /*
276 * Allocate memory for fits
277 */
278 if(verbose>1) printf("allocating memory for fits.\n");
279 ret=fit_allocate_with_dft(&fit, &dft);
280 if(ret) {
281 fprintf(stderr, "Error: cannot allocate space for fit results (%d).\n", ret);
282 dftEmpty(&dft); return(4);
283 }
284 /* Set necessary information in fit data structure */
285 fit.voiNr=dft.voiNr;
286 strncpy(fit.datafile, datfile, FILENAME_MAX);
287 tpcProgramName(argv[0], 1, 1, fit.program, 1024);
288 fit.time=time(NULL);
289 for(ri=0; ri<dft.voiNr; ri++) {
290 fit.voi[ri].type=type; fit.voi[ri].parNr=parNr;
291 fit.voi[ri].start=tstart; fit.voi[ri].end=tstop;
292 fit.voi[ri].dataNr=dataNr;
293 }
294
295
296
297
298 /*
299 * Estimate mean or median delay time, to be fixed in second fits
300 */
301 if(fix_delay==2 || fix_delay==3) {
302 double maxv;
303 if(verbose>0) {printf("fitting common delay time\n"); fflush(stdout);}
304 def_pmin[0]=def_pmax[0]=0.0;
305 for(ri=0; ri<dft.voiNr; ri++) {
306 if(verbose>1) {
307 printf("%d: %s\n", ri+1, dft.voi[ri].name); fflush(stdout);}
308
309 /* Set data pointers */
310 x=dft.x; ymeas=dft.voi[ri].y; yfit=dft.voi[ri].y2; w=dft.w;
311 /* Set the initial values for parameters */
312 fit.voi[ri].wss=3.402823e+38;
313
314 /* Set parameter constraints */
315 for(pi=0; pi<parNr; pi++) {pmin[pi]=def_pmin[pi]; pmax[pi]=def_pmax[pi];}
316 /* some are based on TAC max value and time */
317 ret=dftMinMaxTAC(&dft, ri, NULL, &maxt, NULL, &maxv, NULL, NULL, NULL, NULL);
318 if(ret) {
319 fprintf(stderr, "Error: invalid TAC data for fitting.\n");
320 dftEmpty(&dft); fitEmpty(&fit); return(5);
321 }
322 if(verbose>4) printf(" maxt := %g\n maxv := %g\n", maxt, maxv);
323 /* delay */
324 pmin[0]=-0.05*fabs(tstop); def_pmin[0]+=pmin[0];
325 pmax[0]=0.95*fabs(maxt); def_pmax[0]+=pmax[0];
326 /* A */
327 pmin[1]=0.01*maxv;
328 pmax[1]=50.0*maxv;
329 /* h */
330 pmax[2]=0.2*fabs(maxt); //2.0*maxt;
331 if(verbose>4) {
332 printf(" constraints :=");
333 for(pi=0; pi<parNr; pi++) printf(" [%g,%g]", pmin[pi], pmax[pi]);
334 printf("\n");
335 }
336
337 /* fit */
340 neigh_nr=6; iter_nr=1; tgo_nr=1000;
341 ret=tgo(pmin, pmax, func, NULL, parNr, neigh_nr, &fit.voi[ri].wss,
342 fit.voi[ri].p, tgo_nr, iter_nr, verbose-5);
343 if(ret) {
344 fprintf(stderr, "Error %d in TGO.\n", ret);
345 dftEmpty(&dft); fitEmpty(&fit);
346 return(5);
347 }
348 /* Warn user about parameters that collide with limits */
349 ret=modelCheckLimits(parNr, pmin, pmax, fit.voi[ri].p);
350 if(ret!=0 && verbose>0)
351 fprintf(stderr, "Warning: fit collided with the limits.\n");
352 if(verbose>2) {
353 printf(" fitted parameters:");
354 for(pi=0; pi<parNr; pi++) printf(" %g", fit.voi[ri].p[pi]);
355 printf("\n wss := %g\n", fit.voi[ri].wss);
356 }
357 if(verbose==1 && dft.voiNr>1) {printf("."); fflush(stdout);}
358 } // next TAC
359 if(verbose==1) {printf("\n");}
360
361 /* calculate median */
362 double dfm[dft.voiNr], delay_mean, delay_median, delay_sd, v;
363 for(ri=0; ri<dft.voiNr; ri++) dfm[ri]=fit.voi[ri].p[0];
364 delay_mean=dmean(dfm, dft.voiNr, &delay_sd);
365 delay_median=dmedian(dfm, dft.voiNr);
366 if(verbose>1) {
367 printf("mean_delay_time := %6.4f +- %6.4f\n", delay_mean, delay_sd);
368 printf("median_delay_time := %.4f\n", delay_median);
369 }
370 if(fix_delay==2) v=delay_mean; else v=delay_median;
371 def_pmin[0]/=(double)dft.voiNr; def_pmax[0]/=(double)dft.voiNr;
372 if(v<def_pmin[0] || v>def_pmax[0]) {
373 if(verbose>2) {
374 printf("def_pmin[0] := %g\n", def_pmin[0]);
375 printf("def_pmax[0] := %g\n", def_pmax[0]);
376 }
377 fprintf(stderr,
378 "Error: delay time could not be fixed to regional mean or median\n");
379 dftEmpty(&dft); fitEmpty(&fit); return(5);
380 }
381 def_pmin[0]=def_pmax[0]=v;
382 if(verbose>0) printf("fixed_delay_time := %g\n", def_pmin[0]);
383 }
384
385
386
387 /*
388 * Fit one TAC at a time
389 */
390 if(verbose>0) {printf("fitting\n"); fflush(stdout);}
391 for(ri=0; ri<dft.voiNr; ri++) {
392 if(verbose>1) {printf("%d: %s\n", ri+1, dft.voi[ri].name); fflush(stdout);}
393 /* Set data pointers */
394 x=dft.x; ymeas=dft.voi[ri].y; yfit=dft.voi[ri].y2; w=dft.w;
395 /* Set the initial values for parameters */
396 fit.voi[ri].wss=3.402823e+38;
397
398 /* Set parameter constraints */
399 for(pi=0; pi<parNr; pi++) {pmin[pi]=def_pmin[pi]; pmax[pi]=def_pmax[pi];}
400 /* some are based on TAC max value and time */
401 double maxv;
402 ret=dftMinMaxTAC(&dft, ri, NULL, &maxt, NULL, &maxv, NULL, NULL, NULL, NULL);
403 if(ret) {
404 fprintf(stderr, "Error: invalid TAC data for fitting.\n");
405 dftEmpty(&dft); fitEmpty(&fit); return(5);
406 }
407 if(verbose>4) printf(" maxt := %g\n maxv := %g\n", maxt, maxv);
408 /* delay */
409 if(fix_delay==0) { // if delay time was not fixed
410 pmin[0]=-0.05*fabs(tstop);
411 pmax[0]=0.95*fabs(maxt);
412 }
413 /* A */
414 pmin[1]=0.01*maxv;
415 pmax[1]=50.0*maxv;
416 /* h */
417 pmax[2]=0.3*dft.x[dft.frameNr-1];
418 if(verbose>2) {
419 printf(" constraints :=");
420 for(pi=0; pi<parNr; pi++) printf(" [%g,%g]", pmin[pi], pmax[pi]);
421 printf("\n");
422 }
423
424 /* fit */
427 neigh_nr=6; iter_nr=1; tgo_nr=1000;
428 ret=tgo(pmin, pmax, func, NULL, parNr, neigh_nr, &fit.voi[ri].wss,
429 fit.voi[ri].p, tgo_nr, iter_nr, verbose-5);
430 if(ret) {
431 fprintf(stderr, "Error %d in TGO.\n", ret);
432 dftEmpty(&dft); fitEmpty(&fit);
433 return(5);
434 }
435 /* Warn user about parameters that collide with limits */
436 ret=modelCheckLimits(parNr, pmin, pmax, fit.voi[ri].p);
437 if(ret!=0 && verbose>0)
438 fprintf(stderr, "Warning: fit collided with the limits.\n");
439 /* Force parameter values inside limits, as they are in the simulation */
440 double a;
441 modelCheckParameters(parNr, pmin, pmax,
442 fit.voi[ri].p, fit.voi[ri].p, &a);
443 fit.voi[ri].wss/=a; // remove penalty from reported WSS
444 if(verbose>2) {
445 printf(" fitted parameters:");
446 for(pi=0; pi<parNr; pi++) printf(" %g", fit.voi[ri].p[pi]);
447 printf("\n wss := %g\n", fit.voi[ri].wss);
448 }
449 /* Calculate the maximum of Hill derivative part */
450 if(verbose>1 && type!=1801) {
451 double a, b, c, A, h, n, s, maxx1, maxx2;
452 A=fit.voi[ri].p[1]; h=fit.voi[ri].p[2]; n=fit.voi[ri].p[3];
453 a=2.0*n-n*n-1.0; b=-n*(n-1.0)*pow(h, n); c=n*(n-1.0)*pow(h, 2.0*n);
454 s=sqrt(b*b - 4.0*a*c);
455 maxx1=pow((-b-s)/a, 1.0/n)/pow(2.0, 1.0/n);
456 maxx2=pow((-b+s)/a, 1.0/n)/pow(2.0, 1.0/n);
457 double hn, xn, hnxn, hilld;
458 hn=pow(h, n);
459 xn=pow(maxx1, n); hnxn=hn+xn;
460 hilld= A*n*pow(maxx1, n-1.0)/hnxn - n*pow(maxx1, 2.0*n-1.0)/(hnxn*hnxn);
461 printf("maxx1=%g maxy1=%g\n", maxx1+fit.voi[ri].p[0], hilld);
462 xn=pow(maxx2, n); hnxn=hn+xn;
463 hilld= A*n*pow(maxx2, n-1.0)/hnxn - n*pow(maxx2, 2.0*n-1.0)/(hnxn*hnxn);
464 printf("maxx2=%g maxy2=%g\n", maxx2+fit.voi[ri].p[0], hilld);
465 }
466
467 /* Check the MRL */
468 if(verbose>1) printf("Checking the MRL.\n");
469 m=mrl_between_tacs(yfit, ymeas, dataNr);
470 if(m>3 && m>dataNr/3) {
471 if(MRL_check!=0) {
472 fprintf(stderr, "Error: bad fit.\n");
473 fprintf(stderr, "MRL := %d / %d\n", m, dataNr);
474 dftEmpty(&dft); fitEmpty(&fit);
475 return(7);
476 }
477 }
478 if(m>2 && m>dataNr/4) {
479 fprintf(stderr, "Warning: bad fit.\n");
480 fprintf(stderr, "MRL := %d / %d\n", m, dataNr);
481 } else if(verbose>1) {
482 printf("MRL test passed.\n");
483 if(verbose>2) fprintf(stderr, "MRL := %d / %d\n", m, dataNr);
484 }
485
486 if(verbose==1 && dft.voiNr>1) {printf("."); fflush(stdout);}
487 } // next TAC
488 if(verbose==1) {printf("\n");}
489
490
491
492 /*
493 * Save fit results
494 */
495 if(verbose>1) printf("saving results in %s\n", parfile);
496 ret=fitWrite(&fit, parfile); if(ret) {
497 fprintf(stderr, "Error (%d) in writing '%s': %s\n", ret, parfile, fiterrmsg);
498 dftEmpty(&dft); fitEmpty(&fit); return(11);
499 }
500 if(verbose>0) printf("Function parameters written in %s\n", parfile);
501
502
503 /* Also allocate memory for result file, if needed */
504 if(resfile[0]) {
505 if(verbose>1) printf("allocating memory for results.\n");
506 RES res;
507 resInit(&res);
508 ret=fitToResult(&fit, &res, temp);
509 if(ret!=0) {
510 fprintf(stderr, "Error in making results: %s\n", temp);
511 dftEmpty(&dft); fitEmpty(&fit); resEmpty(&res); return(4);
512 }
513 n=0; strcpy(res.parname[n++], "Function");
514 strcpy(res.parname[n++], "Delay");
515 strcpy(res.parname[n++], "A");
516 strcpy(res.parname[n++], "h");
517 strcpy(res.parname[n++], "n");
518 if(type==1821) {
519 strcpy(res.parname[n++], "K");
520 }
521 strcpy(res.parname[n++], "WSS");
522 strcpy(res.program, progname);
523 sprintf(res.datarange, "%g - %g", tstart, tstop);
524 strcpy(res.studynr, dft.studynr);
525 if(verbose>0) resPrint(&res);
526 if(verbose>1) printf("saving results in %s\n", resfile);
527 if(resWrite(&res, resfile, verbose-3)) {
528 fprintf(stderr, "Error in writing '%s': %s\n", resfile, reserrmsg);
529 dftEmpty(&dft); fitEmpty(&fit); resEmpty(&res); return(11);
530 }
531 resEmpty(&res);
532 if(verbose>1) printf("Function parameters written in %s\n", resfile);
533 }
534
535
536
537 /*
538 * Plot fitted curves
539 */
540 if(svgfile[0]) {
541 if(verbose>1) printf("creating SVG plot\n");
542 DFT adft;
543 char tmp[FILENAME_MAX];
544 double a;
545
546 if(verbose>1)
547 printf("calculating fitted curve at automatically generated sample times\n");
548 dftInit(&adft);
549 ret=dftAutointerpolate(&dft, &adft, 1.05*tstop, verbose-10);
550 if(ret) {
551 fprintf(stderr, "Error %d in memory allocation for fitted curves.\n", ret);
552 dftEmpty(&dft); fitEmpty(&fit); dftEmpty(&adft);
553 return(13);
554 }
555 //for(fi=0; fi<adft.frameNr; fi++) adft.w[fi]=1.0;
556 for(ri=0, ret=0; ri<adft.voiNr; ri++) {
557 for(fi=0; fi<adft.frameNr; fi++) {
558 ret=fitEval(&fit.voi[ri], adft.x[fi], &a); if(ret!=0) break;
559 adft.voi[ri].y[fi]=a;
560 }
561 if(ret!=0) break;
562 }
563 if(ret!=0) {
564 fprintf(stderr, "Error: cannot calculate fitted TAC for '%s'.\n", svgfile);
565 dftEmpty(&dft); dftEmpty(&adft); fitEmpty(&fit);
566 return(14);
567 }
568
569 /* Save SVG plot of fitted and original data */
570 if(verbose>1) printf("writing %s\n", svgfile);
571 tpcProgramName(argv[0], 0, 0, tmp, 128); strcat(tmp, " ");
572 if(strlen(adft.studynr)>1) strcat(tmp, adft.studynr);
573 ret=plot_fitrange_svg(&dft, &adft, tmp, 0.0, nan(""), 0.0, nan(""),
574 svgfile, verbose-10);
575 if(ret) {
576 fprintf(stderr, "Error (%d) in writing '%s'.\n", ret, svgfile);
577 dftEmpty(&adft); dftEmpty(&dft); fitEmpty(&fit);
578 return(30+ret);
579 }
580 if(verbose>0) printf("Plots written in %s\n", svgfile);
581
582 dftEmpty(&adft);
583 }
584
585 /*
586 * Save fitted TACs (original data is lost here, so do this in the end)
587 */
588 if(fitfile[0]) {
589 if(verbose>1) printf("saving fitted curves in %s\n", fitfile);
590 double a;
591 for(ri=0, ret=0; ri<dft.voiNr; ri++) {
592 for(fi=0; fi<dft.frameNr; fi++) {
593 ret=fitEval(&fit.voi[ri], dft.x[fi], &a); if(ret!=0) break;
594 dft.voi[ri].y[fi]=a;
595 }
596 if(ret!=0) break;
597 }
598 if(ret!=0) {
599 fprintf(stderr, "Error: cannot calculate fitted TACs for '%s'.\n", fitfile);
600 dftEmpty(&dft); fitEmpty(&fit);
601 return(21);
602 }
603 tpcProgramName(argv[0], 1, 0, temp, 128);
604 sprintf(dft.comments, "# program := %s\n", temp);
605 dft.isweight=0;
606 if(dftWrite(&dft, fitfile)) {
607 fprintf(stderr, "Error in writing '%s': %s\n", fitfile, dfterrmsg);
608 dftEmpty(&dft); fitEmpty(&fit);
609 return(22);
610 }
611 if(verbose>0) printf("Fitted TACs written in %s\n", fitfile);
612 }
613
614 /* Free memory */
615 dftEmpty(&dft); fitEmpty(&fit);
616
617 return(0);
618}
619/*****************************************************************************/
620
621/*****************************************************************************
622 *
623 * Functions to be minimized
624 *
625 *****************************************************************************/
627double func1821(int parNr, double *p, void *fdata)
628{
629 int i;
630 double t, A, h, n, k,
631 xt, xn, hn, hnxn, hill, hilld, v, wss;
632 //double dmaxv, dmaxt;
633 double pa[MAX_PARAMETERS], penalty=1.0;
634 if(fdata) {}
635
636 /* Check parameters against the constraints */
637 (void)modelCheckParameters(parNr, pmin, pmax, p, pa, &penalty);
638
639 /* Get parameters */
640 t=pa[0]; A=pa[1]; h=pa[2]; n=pa[3]; k=pa[4];
641
642 /* Calculate the curve values and weighted SS */
643 hn=pow(h, n); //dmaxv=dmaxt=0.0;
644 for(i=0, wss=0.0; i<dataNr; i++) if(w[i]>0.0) {
645 xt=x[i]-t; if(xt<=0.0) {
646 yfit[i]=0.0; hilld=0.0;
647 } else {
648 xn=pow(xt, n); hnxn=hn+xn;
649 hilld= n*pow(xt, n-1.0)/hnxn - n*pow(xt, 2.0*n-1.0)/(hnxn*hnxn);
650 hill=k*xn/hnxn;
651 if(hilld>=0.0 && hilld<1.0E20 && hill>=0.0 && hill<1.0E20) {
652 yfit[i]=A*(hilld+hill);
653 } else
654 return(nan(""));
655 //if(hilld>dmaxv) {dmaxv=hilld; dmaxt=x[i];}
656 }
657 v=yfit[i]-ymeas[i];
658 /* Penalize Hill derivative > 0 after specified time by
659 removing its contribution to fitted TAC */
660 //if(x[i]>=dlowtime) v=fabs(v)+fabs(A*hilld)*(1.0+x[i]-dlowtime);
661 //if(x[i]>=dlowtime) v-=A*hilld;
662 v*=v;
663 wss+=w[i]*v;
664 }
665
666
667 /* Penalize Hill derivative > 1% at specified time */
668 if(dlowtime>0.0) {
669 xt=dlowtime-t;
670 xn=pow(xt, n); hnxn=hn+xn;
671 hilld= n*pow(xt, n-1.0)/hnxn - n*pow(xt, 2.0*n-1.0)/(hnxn*hnxn);
672 hill=k*xn/hnxn;
673 v=hilld/(hill+hilld);
674 v*=10000.0; v-=1.0; if(v<0.0) v=0.0;
675 v+=1.0; v=v*v*v*v; penalty*=v;
676 //v=hilld/(hill+hilld) - 0.01; if(v<0.0) v=0.0;
677 //v+=1.0; v*=v; penalty*=v;
678 }
679
680 wss*=penalty;
681
682 return(wss);
683}
684
686double func1801(int parNr, double *p, void *fdata)
687{
688 int i;
689 double t, A, h, n,
690 xt, xn, hn, hnxn, hill, v, wss;
691 double pa[MAX_PARAMETERS], penalty=1.0;
692 if(fdata) {}
693
694 /* Check parameters against the constraints */
695 modelCheckParameters(parNr, pmin, pmax, p, pa, &penalty);
696
697 /* Get parameters */
698 t=pa[0]; A=pa[1]; h=pa[2]; n=pa[3];
699
700 /* Calculate the curve values and weighted SS */
701 hn=pow(h, n);
702 for(i=0, wss=0.0; i<dataNr; i++) if(w[i]>0.0) {
703 xt=x[i]-t; if(xt<=0.0) {
704 yfit[i]=0.0;
705 } else {
706 xn=pow(xt, n); hnxn=hn+xn;
707 hill=xn/hnxn;
708 if(hill>=0.0 && hill<1.0E20) {
709 yfit[i]=A*hill;
710 } else
711 return(nan(""));
712 }
713 v=yfit[i]-ymeas[i]; v*=v;
714 wss+=w[i]*v;
715 }
716
717 wss*=penalty;
718
719 return(wss);
720}
721/*****************************************************************************/
722
723/*****************************************************************************/
int modelCheckParameters(int par_nr, double *lower_p, double *upper_p, double *test_p, double *accept_p, double *penalty)
Definition constraints.c:15
int modelCheckLimits(int par_nr, double *lower_p, double *upper_p, double *test_p)
Definition constraints.c:59
int atof_with_check(char *double_as_string, double *result_value)
Definition decpoint.c:107
void dftInit(DFT *data)
Definition dft.c:38
int dftMinMaxTAC(DFT *dft, int tacindex, double *minx, double *maxx, double *miny, double *maxy, int *mini, int *maxi, int *mins, int *maxs)
Definition dft.c:1024
char dfterrmsg[64]
Definition dft.c:6
int dftSortByFrame(DFT *dft)
Definition dft.c:1169
int dftMinMax(DFT *dft, double *minx, double *maxx, double *miny, double *maxy)
Definition dft.c:974
void dftEmpty(DFT *data)
Definition dft.c:20
int dftRead(char *filename, DFT *data)
Definition dftio.c:22
void dftPrint(DFT *data)
Definition dftio.c:538
int dftWrite(DFT *data, char *filename)
Definition dftio.c:594
int dftAutointerpolate(DFT *dft, DFT *dft2, double endtime, int verbose)
int fitToResult(FIT *fit, RES *res, char *status)
Definition fitres.c:56
int fit_allocate_with_dft(FIT *fit, DFT *dft)
Definition fitres.c:14
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 fitEval(FitVOI *r, double x, double *y)
Definition mathfunc.c:618
void fitEmpty(FIT *fit)
Definition mathfunc.c:18
int fitWrite(FIT *fit, char *filename)
Definition mathfunc.c:54
int resWrite(RES *res, char *filename, int verbose)
Definition result.c:565
char fiterrmsg[64]
Definition mathfunc.c:6
void fitInit(FIT *fit)
Definition mathfunc.c:38
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
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 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
int mrl_between_tacs(double y1[], double y2[], int n)
Definition runs_test.c:103
#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
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.
Voi * voi
char studynr[MAX_STUDYNR_LEN+1]
double * w
char comments[_DFT_COMMENT_LEN+1]
int voiNr
int frameNr
int isweight
double * x
int voiNr
char datafile[FILENAME_MAX]
char program[1024]
FitVOI * voi
time_t time
double wss
double end
double start
double p[MAX_FITPARAMS]
char studynr[MAX_STUDYNR_LEN+1]
char parname[MAX_RESPARAMS][MAX_RESPARNAME_LEN+1]
char program[1024]
char datarange[128]
double * y2
double * y
char name[MAX_REGIONNAME_LEN+1]