TPCCLIB
Loading...
Searching...
No Matches
fit_sigm.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 <string.h>
14#include <time.h>
15/*****************************************************************************/
16#include "libtpcmisc.h"
17#include "libtpcmodel.h"
18#include "libtpccurveio.h"
19#include "libtpcsvg.h"
20#include "libtpcmodext.h"
21/*****************************************************************************/
22int FIT2DAT_MAXNR=10000;
23/*****************************************************************************/
24
25/*****************************************************************************/
26double func841(int parNr, double *p, void*);
27double func844(int parNr, double *p, void*);
28double func2801(int parNr, double *p, void*);
29/*****************************************************************************/
30double *x, *ymeas, *yfit, *w; /* Local */
31int dataNr=0, parNr=3;
32double pmin[MAX_PARAMETERS], pmax[MAX_PARAMETERS];
33double min1, min2, max1, max2;
34double (*func)(int parNr, double *p, void*);
35/*****************************************************************************/
36
37/*****************************************************************************/
38static char *info[] = {
39 "Non-linear fitting of the Hill function (sigmoid function) to a (xi,yi)",
40 "curve data. Optionally, a background term B is added to the function:",
41 " ",
42 " f(x) = (A * x^n ) / ( x^n + K ) + B , where A>=0, K>0, n>0, B>=0 ",
43 " ",
44 "Function for estimating EC50 from sigmoidal dose-response curve is obtained",
45 "by rearranging and marking n=HillSlope, A=Top-Bottom, B=Bottom, and",
46 "K=EC50^n :",
47 " ",
48 " f(x) = Bottom + (Top-Bottom)/(1 + (EC50/x)^HillSlope)",
49 " ",
50 "With HillSlope constrained to 1 (see options below) the function reduces to",
51 "unconstrained one site binding hyperbola, f(x)=Top*x/(EC50+x).",
52 " ",
53 "Usage: @P [Options] tacfile [fitfile]",
54 " ",
55 "Options:",
56 " -EC50",
57 " EC50 is estimated by fitting sigmoidal dose-response curve function",
58 " when drug concentrations are on a linear scale (not on a log scale);",
59 " By default, parameter Top is fitted and Bottom is constrained to 0,",
60 " which can be changed with options (see below).",
61 " -w1 All weights are set to 1.0 (no weighting); by default, weights in",
62 " data file are used, if available.",
63 " -wf",
64 " Weight by sampling interval.",
65 " -n=<value>",
66 " Parameter n or HillSlope is constrained to the given value; set -n=1",
67 " to fit one site binding hyperbola.",
68 " -B Parameter B or Bottom is fitted; by default B=0",
69 " -B=<value>",
70 " Parameter B or Bottom is constrained to the given value.",
71 " -A=<value>",
72 " Parameter Top is constrained to the given value; currently this option",
73 " does not affect parameter A in the default function.",
74 " -MRL",
75 " Error is returned if MRL check is not passed.",
76 " -res=<Filename>",
77 " Fitted parameters are also written in result file format (3).",
78 " -svg=<Filename>",
79 " Fitted and measured TACs are plotted in specified SVG file.",
80 " -fit=<Filename>",
81 " Fitted TACs are written in DFT format.",
82 " -stdoptions", // List standard options like --help, -v, etc
83 " ",
84 "TAC file must contain at least 2 columns, sample times (or concentrations)",
85 "and measurement values (or receptor occupancies).",
86 "Weights can be specified as usual if data is in DFT format (1).",
87 " ",
88 "Program writes the fit start and end times, nr of points, WSS,",
89 "and parameters of the fitted function to the fit file (2).",
90 " ",
91 "References:",
92 "1. https://www.turkupetcentre.net/analysis/doc/format_dft.html",
93 "2. https://www.turkupetcentre.net/analysis/doc/format_fit.html",
94 "3. https://www.turkupetcentre.net/analysis/doc/format_res.html",
95 " ",
96 "See also: fit_hiad, fit_ppf, fit_exp, fit_ratf, fit_bpr, fit2dat, tacinv",
97 " ",
98 "Keywords: curve fitting, Hill function, sigmoid, EC50, dose-response curve",
99 0};
100/*****************************************************************************/
101
102/*****************************************************************************/
103/* Turn on the globbing of the command line, since it is disabled by default in
104 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
105 In Unix&Linux wildcard command line processing is enabled by default. */
106/*
107#undef _CRT_glob
108#define _CRT_glob -1
109*/
110int _dowildcard = -1;
111/*****************************************************************************/
112
113/*****************************************************************************/
117int main(int argc, char **argv)
118{
119 int ai, help=0, version=0, verbose=1;
120 int fi, pi, ri, type=841, m, n, ret;
121 int is_n_fixed=0, is_b_fixed=1, is_a_fixed=0;
122 int weights=0; // 0=default, 1=no weighting, 2=frequency
123 double fixed_n=1.0, fixed_b=0.0, fixed_a=100.0;
124 int MRL_check=0; // 0=off, 1=on
125 char datfile[FILENAME_MAX], fitfile[FILENAME_MAX], outfile[FILENAME_MAX],
126 svgfile[FILENAME_MAX], resfile[FILENAME_MAX], *cptr, temp[512];
127 char progname[256];
128 DFT dft;
129 FIT fit;
130 RES res;
131 double a, tstart, tstop, miny, maxy;
132 int tgo_nr, iter_nr, neigh_nr;
133
134
135 /*
136 * Get arguments
137 */
138 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
139 datfile[0]=fitfile[0]=outfile[0]=svgfile[0]=resfile[0]=(char)0;
140 dftInit(&dft); fitInit(&fit); resInit(&res);
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(strncasecmp(cptr, "N=", 2)==0) {
151 cptr+=2; if(strlen(cptr)>0) {
152 is_n_fixed=1; fixed_n=atof_dpi(cptr);
153 if(fixed_n>0.0) continue;
154 }
155 } else if(strncasecmp(cptr, "A=", 2)==0) {
156 cptr+=2; if(strlen(cptr)>0) {
157 is_a_fixed=1; fixed_a=atof_dpi(cptr);
158 if(fixed_a>0.0) continue;
159 }
160 } else if(strncasecmp(cptr, "Top=", 4)==0) {
161 cptr+=4; if(strlen(cptr)>0) {
162 is_a_fixed=1; fixed_a=atof_dpi(cptr);
163 if(fixed_a>0.0) continue;
164 }
165 } else if(strncasecmp(cptr, "B=", 2)==0) {
166 cptr+=2; if(strlen(cptr)>0) {
167 is_b_fixed=1; fixed_b=atof_dpi(cptr);
168 parNr=4;
169 continue;
170 }
171 } else if(strncasecmp(cptr, "BOTTOM=", 7)==0) {
172 cptr+=7; if(strlen(cptr)>0) {
173 is_b_fixed=1; fixed_b=atof_dpi(cptr); parNr=4;
174 continue;
175 }
176 } else if(strcasecmp(cptr, "B")==0) {
177 is_b_fixed=0; parNr=4;
178 continue;
179 } else if(strcasecmp(cptr, "BOTTOM")==0) {
180 is_b_fixed=0; parNr=4;
181 continue;
182 } else if(strcasecmp(cptr, "EC50")==0) {
183 parNr=4; type=2801;
184 continue;
185 } else if(strcasecmp(cptr, "MRL")==0) {
186 MRL_check=1; continue;
187 } else if(strncasecmp(cptr, "SVG=", 4)==0 && strlen(cptr)>4) {
188 strcpy(svgfile, cptr+4); continue;
189 } else if(strncasecmp(cptr, "FIT=", 4)==0 && strlen(cptr)>4) {
190 strcpy(outfile, cptr+4); continue;
191 } else if(strncasecmp(cptr, "RES=", 4)==0 && strlen(cptr)>4) {
192 strcpy(resfile, cptr+4); continue;
193 }
194 fprintf(stderr, "Error: invalid option '%s'\n", argv[ai]);
195 return(1);
196 } else break;
197
198 /* Print help or version? */
199 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
200 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
201 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
202
203 /* Process other arguments, starting from the first non-option */
204 for(; ai<argc; ai++) {
205 if(!datfile[0]) {strcpy(datfile, argv[ai]); continue;}
206 else if(!fitfile[0]) {strcpy(fitfile, argv[ai]); continue;}
207 fprintf(stderr, "Error: invalid argument '%s'\n", argv[ai]);
208 return(1);
209 }
210 if(!fitfile[0]) strcpy(fitfile, "stdout");
211 if(type==841 && parNr==4) type=844;
212 if(type==841) func=func841;
213 else if(type==844) func=func844;
214 else func=func2801;
215
216 /* Is something missing? */
217 if(!datfile[0]) {
218 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
219 return(1);
220 }
221 if(is_a_fixed && type!=2801) {
222 fprintf(stderr, "Error: option -a can not be used without option -EC50.\n");
223 return(1);
224 }
225 if(is_a_fixed && is_b_fixed && fixed_a<=fixed_b) {
226 fprintf(stderr, "Error: invalid constraints for Top and Bottom.\n");
227 return(1);
228 }
229
230 /* In verbose mode print arguments and options */
231 if(verbose>1) {
232 printf("datfile := %s\n", datfile);
233 printf("fitfile := %s\n", fitfile);
234 printf("resfile := %s\n", resfile);
235 printf("outfile := %s\n", outfile);
236 printf("svgfile := %s\n", svgfile);
237 if(is_a_fixed) printf("fixed_a := %g\n", fixed_a);
238 if(is_b_fixed) printf("fixed_b := %g\n", fixed_b);
239 if(is_n_fixed) printf("fixed_n := %g\n", fixed_n);
240 printf("type := %d\n", type);
241 printf("weights := %d\n", weights);
242 printf("MRL_check := %d\n", MRL_check);
243 fflush(stdout);
244 }
245 if(verbose>4) MATHFUNC_TEST=verbose-4; else MATHFUNC_TEST=0;
246
247
248 /*
249 * Read data
250 */
251 if(verbose>1) printf("reading %s\n", datfile);
252 if(dftRead(datfile, &dft)) {
253 fprintf(stderr, "Error in reading '%s': %s\n", datfile, dfterrmsg);
254 return(2);
255 }
256 dataNr=dft.frameNr;
257
258 /* Sort the samples by time in case data is catenated from several curves */
259 (void)dftSortByFrame(&dft);
260 if(verbose>30) dftPrint(&dft);
261
262 /* Get min and max X and Y */
263 ret=dftMinMax(&dft, &tstart, &tstop, &miny, &maxy);
264 if(ret!=0) {
265 fprintf(stderr, "Error: invalid contents in %s\n", datfile);
266 dftEmpty(&dft); return(2);
267 }
268 if(tstop<=0.0 || maxy<=0.0) {
269 fprintf(stderr, "Error: invalid contents in %s\n", datfile);
270 dftEmpty(&dft); return(2);
271 }
272 if(tstart<0.0) fprintf(stderr, "Warning: negative x value(s).\n");
273 if(miny<0.0) fprintf(stderr, "Warning: negative y value(s).\n");
274
275 /* Check and set weights */
276 if(weights==0) {
277 if(dft.isweight==0) {
278 dft.isweight=1; for(fi=0; fi<dft.frameNr; fi++) dft.w[fi]=1.0;}
279 } else if(weights==1) {
280 dft.isweight=1; for(fi=0; fi<dft.frameNr; fi++) dft.w[fi]=1.0;
281 } else if(weights==2) {
282 dftWeightByFreq(&dft);
283 }
284 if(verbose==10) dftPrint(&dft);
285
286
287 /*
288 * Allocate memory for fits
289 */
290 if(verbose>1) printf("allocating memory for fits.\n");
291 ret=fit_allocate_with_dft(&fit, &dft);
292 if(ret) {
293 fprintf(stderr, "Error: cannot allocate space for fit results (%d).\n", ret);
294 dftEmpty(&dft); return(4);
295 }
296 /* Set necessary information in fit data structure */
297 fit.voiNr=dft.voiNr;
298 strncpy(fit.datafile, datfile, FILENAME_MAX);
299 tpcProgramName(argv[0], 1, 1, fit.program, 1024);
300 fit.time=time(NULL);
301 for(ri=0; ri<dft.voiNr; ri++) {
302 fit.voi[ri].type=type; fit.voi[ri].parNr=parNr;
303 fit.voi[ri].start=tstart; fit.voi[ri].end=tstop;
304 fit.voi[ri].dataNr=dataNr;
305 }
306
307
308 /*
309 * Fit the curves
310 */
311 if(verbose>1) {printf("fitting\n"); fflush(stdout);}
312 for(ri=0; ri<dft.voiNr; ri++) {
313 if(verbose>0 && dft.voiNr>1) printf("%s\n", dft.voi[ri].name);
314
315 /* Set weights for this curve, ie, if NaN, then use 0 weight */
316 for(fi=0; fi<dft.frameNr; fi++)
317 if(isnan(dft.voi[ri].y[fi])) dft.voi[ri].y3[fi]=0.0;
318 else dft.voi[ri].y3[fi]=dft.w[fi];
319
320 /* Set data pointers */
321 x=dft.x; ymeas=dft.voi[ri].y; yfit=dft.voi[ri].y2; w=dft.voi[ri].y3;
322 if(verbose>2) {
323 printf("data_weights[%d] := %g", ri+1, dft.w[0]);
324 for(fi=1; fi<dft.frameNr; fi++) printf(", %g", w[fi]);
325 printf("\n");
326 }
327
328 /* Set the initial values for parameters */
329 fit.voi[ri].wss=3.402823e+38;
330
331 /* for defining constraints, find the min and max value of the */
332 /* beginning and end of the data set */
333 n=dataNr/3; if(n<2) n=2;
334 fi=0; while(isnan(dft.voi[ri].y[fi])) fi++;
335 min1=max1=dft.voi[ri].y[fi];
336 for(fi=0; fi<n; fi++) if(!isnan(dft.voi[ri].y[fi])) {
337 if(min1>dft.voi[ri].y[fi]) min1=dft.voi[ri].y[fi];
338 if(max1<dft.voi[ri].y[fi]) max1=dft.voi[ri].y[fi];
339 }
340 fi=dataNr-1; while(isnan(dft.voi[ri].y[fi])) fi--;
341 min2=max2=dft.voi[ri].y[fi];
342 for(fi=dataNr-n; fi<dataNr; fi++) if(!isnan(dft.voi[ri].y[fi])) {
343 if(min2>dft.voi[ri].y[fi]) min2=dft.voi[ri].y[fi];
344 if(max2<dft.voi[ri].y[fi]) max2=dft.voi[ri].y[fi];
345 }
346 if(verbose>3) printf("min1 := %g\nmax1 := %g\nmin2 := %g\nmax2 := %g\n",
347 min1, max1, min2, max2);
348
349 /* Set parameter constraints */
350 if(type==841 || type==844) {
351 pmin[0]=(min2>1.0E-08)?min2:1.0E-08;
352 pmax[0]=(10.0*max2>pmin[0])?10.0*max2:pmin[0];
353 if(is_n_fixed==0) {
354 pmin[1]=1.0E-08; pmax[1]=20.0; //50.0;
355 } else {
356 pmin[1]=pmax[1]=fixed_n;
357 }
358 pmin[2]=1.0E-08; pmax[2]=1.0E20;
359 if(is_n_fixed!=0 && fixed_n==1.0) pmax[2]=4.0*dft.x[dataNr-1];
360 if(type==844) {
361 if(is_b_fixed==0) {
362 pmin[3]=0.0; pmax[3]=0.5*(max1+max2);
363 //pmin[3]=(min1>1.0e-6)?min1:1.0e-6; pmin[0]-=pmin[3]; pmin[3]*=0.5;
364 //max1*=2.0; pmax[3]=(max1>pmin[3])?max1:pmin[3]; //pmax[0]-=pmin[3];
365 pmin[0]-=pmax[3];
366 } else {
367 //pmin[3]=pmax[3]=fixed_b; pmin[0]-=pmin[3]; pmax[0]-=pmin[3];
368 pmin[3]=pmax[3]=fixed_b; pmin[0]-=pmax[3]; pmax[0]-=pmin[3];
369 }
370 if(pmin[0]<0.0) pmin[0]=0.0;
371 }
372 /* Log10 scaling of parameter 3 */
373 pmin[2]=log10(pmin[2]);
374 pmax[2]=log10(pmax[2]);
375 } else { // type==2801
376 /* Top */
377 if(is_a_fixed!=0) {
378 pmin[0]=pmax[0]=fixed_a;
379 } else {
380 a=0.5*(min1+min2);
381 pmin[0]=(a>1.0E-10)?a:1.0E-10;
382 pmax[0]=10.0*max2;
383 }
384 /* Bottom */
385 if(is_b_fixed!=0) {
386 pmin[1]=pmax[1]=fixed_b;
387 } else {
388 pmin[1]=0.0; pmax[1]=0.5*(max1+max2);
389 }
390 /* EC50 */
391 pmin[2]=1.0E-08; pmax[2]=4.0*tstop;
392 /* HillSlope */
393 if(is_n_fixed!=0) {
394 pmin[3]=pmax[3]=fixed_n;
395 } else {
396 pmin[3]=1.0E-08; pmax[3]=20.0;
397 }
398 }
399 if(verbose>3) {
400 fflush(stdout); printf("Constraints for the fit:\n");
401 for(pi=0; pi<parNr; pi++)
402 printf(" %g - %g\n", pmin[pi], pmax[pi]);
403 fflush(stdout);
404 }
405
406 /* Check that the actual sample number exceeds the number of actually
407 fitted parameters */
408 for(pi=m=0; pi<parNr; pi++) if(pmin[pi]<pmax[pi]) m++;
409 n=getActualSamplenr(&dft, ri);
410 if(verbose>2)
411 printf("Comparison of nr of samples and params to fit: %d / %d\n", n, m);
412 if((n-1)<m) {
413 fprintf(stderr, "Error: too few samples for fitting in %s\n", datfile);
414 if(verbose>0) printf("n := %d\nm := %d\n", n, m);
415 dftEmpty(&dft); fitEmpty(&fit); return(2);
416 }
417
418 /* fit */
419 if(verbose>2) printf("fitting\n");
420 if(type==841) {iter_nr=3; tgo_nr=1000; neigh_nr=15; /*20*/}
421 else {iter_nr=3; tgo_nr=2000; neigh_nr=20; /*50*/}
424 ret=tgo(pmin, pmax, func, NULL, parNr, neigh_nr, &fit.voi[ri].wss,
425 fit.voi[ri].p, tgo_nr, iter_nr, verbose-5);
426 if(ret) {
427 fprintf(stderr, "Error %d in TGO.\n", ret);
428 dftEmpty(&dft); fitEmpty(&fit);
429 return(4);
430 }
431
432 /* Warn user about parameters that collide with limits */
433 ret=modelCheckLimits(parNr, pmin, pmax, fit.voi[ri].p);
434 if(ret!=0 && verbose>0) {
435 fprintf(stderr, "Warning: fit collided with the limits.\n");
436 }
437 /* Force parameter values inside limits, as they are in the simulation */
438 modelCheckParameters(parNr, pmin, pmax,
439 fit.voi[ri].p, fit.voi[ri].p, &a);
440 fit.voi[ri].wss/=a; // remove penalty from reported WSS
441
442 /* Print measured and fitted curve */
443 func(parNr, fit.voi[ri].p, NULL);
444 if(verbose>2) {
445 printf(" Measured Fitted Weight\n");
446 for(fi=0; fi<dataNr; fi++)
447 if(!isnan(ymeas[fi]))
448 printf(" %2d: %9.2e %9.2e %9.2e %7.1e\n",
449 fi+1, x[fi], ymeas[fi], yfit[fi], w[fi]);
450 else
451 printf(" %2d: %9.2e %-9.9s %9.2e %7.1e\n", fi+1, x[fi],
452 ".", yfit[fi], w[fi]);
453 printf(" fitted parameters:");
454 for(pi=0; pi<parNr; pi++) printf(" %g", fit.voi[ri].p[pi]);
455 printf("\n");
456 }
457
458 /* Check the MRL */
459 if(verbose>1) {printf("Checking the MRL.\n"); fflush(stdout);}
460 m=mrl_between_tacs(yfit, ymeas, dataNr);
461 if(m>3 && m>dataNr/3) {
462 if(MRL_check!=0) {
463 fprintf(stderr, "Error: bad fit.\n");
464 fprintf(stderr, "MRL := %d / %d\n", m, dataNr);
465 dftEmpty(&dft); fitEmpty(&fit);
466 fflush(stderr);
467 return(7);
468 }
469 }
470 if(m>2 && m>dataNr/4) {
471 fprintf(stderr, "Warning: bad fit.\n");
472 fprintf(stderr, "MRL := %d / %d\n", m, dataNr);
473 fflush(stderr);
474 } else if(verbose>1) {
475 printf("MRL test passed.\n"); fflush(stdout);
476 if(verbose>2) {
477 fprintf(stderr, "MRL := %d / %d\n", m, dataNr); fflush(stderr);}
478 }
479
480 /* Back-scale p2 */
481 if(type==841 || type==844) {
482 fit.voi[ri].p[2]=pow(10., fit.voi[ri].p[2]);
483 }
484
485 } // next curve
486
487 /*
488 * Save fit results
489 */
490 if(verbose>1) printf("saving results in %s\n", fitfile);
491 ret=fitWrite(&fit, fitfile); if(ret) {
492 fprintf(stderr, "Error (%d) in writing '%s': %s\n", ret, fitfile, fiterrmsg);
493 dftEmpty(&dft); fitEmpty(&fit); return(11);
494 }
495 if(verbose>0) printf("Function parameters written in %s\n", fitfile);
496
497 /* Also allocate memory for result file, if needed */
498 if(resfile[0]) {
499 if(verbose>1) printf("allocating memory for results.\n");
500 resInit(&res);
501 ret=fitToResult(&fit, &res, temp);
502 if(ret!=0) {
503 fprintf(stderr, "Error in making results: %s\n", temp);
504 dftEmpty(&dft); fitEmpty(&fit); resEmpty(&res); return(4);
505 }
506 n=0; strcpy(res.parname[n++], "Function");
507 if(type==841 || type==844) {
508 strcpy(res.parname[n++], "A");
509 strcpy(res.parname[n++], "n");
510 strcpy(res.parname[n++], "K");
511 }
512 if(type==844) {
513 strcpy(res.parname[n++], "B");
514 }
515 if(type==2801) {
516 strcpy(res.parname[n++], "Top");
517 strcpy(res.parname[n++], "Bottom");
518 strcpy(res.parname[n++], "EC50");
519 strcpy(res.parname[n++], "HillSlope");
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 * Plot fitted curves
538 */
539 if(svgfile[0]) {
540 if(verbose>1) printf("creating SVG plot\n");
541 DFT adft;
542 char tmp[FILENAME_MAX];
543
544 if(verbose>1)
545 printf("calculating fitted curve at automatically generated sample times\n");
546 dftInit(&adft);
547 ret=dftAutointerpolate(&dft, &adft, 1.05*tstop, verbose-10);
548 if(ret) {
549 fprintf(stderr, "Error %d in memory allocation for fitted curves.\n", ret);
550 dftEmpty(&dft); fitEmpty(&fit); dftEmpty(&adft);
551 return(13);
552 }
553 //for(fi=0; fi<adft.frameNr; fi++) adft.w[fi]=1.0;
554 for(ri=0, ret=0; ri<adft.voiNr; ri++) {
555 for(fi=0; fi<adft.frameNr; fi++) {
556 ret=fitEval(&fit.voi[ri], adft.x[fi], &a); if(ret!=0) break;
557 adft.voi[ri].y[fi]=a;
558 }
559 if(ret!=0) break;
560 }
561 if(ret!=0) {
562 fprintf(stderr, "Error: cannot calculate fitted TAC for '%s'.\n", svgfile);
563 dftEmpty(&dft); dftEmpty(&adft); fitEmpty(&fit);
564 return(14);
565 }
566
567 /* Save SVG plot of fitted and original data */
568 if(verbose>1) printf("writing %s\n", svgfile);
569 tpcProgramName(argv[0], 0, 0, tmp, 128); strcat(tmp, " ");
570 if(strlen(adft.studynr)>1) strcat(tmp, adft.studynr);
571 ret=plot_fitrange_svg(&dft, &adft, tmp, 0.0, nan(""), 0.0, nan(""),
572 svgfile, verbose-10);
573 if(ret) {
574 fprintf(stderr, "Error (%d) in writing '%s'.\n", ret, svgfile);
575 dftEmpty(&adft); dftEmpty(&dft); fitEmpty(&fit);
576 return(30+ret);
577 }
578 if(verbose>0) printf("Plots written in %s\n", svgfile);
579
580 dftEmpty(&adft);
581 }
582
583
584 /*
585 * Save fitted TACs (original data is lost here, so do this in the end)
586 */
587 if(outfile[0]) {
588 if(verbose>1) printf("saving fitted curves in %s\n", outfile);
589
590 for(ri=0, ret=0; ri<dft.voiNr; ri++) {
591 for(fi=0; fi<dft.frameNr; fi++) {
592 ret=fitEval(&fit.voi[ri], dft.x[fi], &a); if(ret!=0) break;
593 dft.voi[ri].y[fi]=a;
594 }
595 if(ret!=0) break;
596 }
597 if(ret!=0) {
598 fprintf(stderr, "Error: cannot calculate fitted TACs for '%s'.\n", outfile);
599 dftEmpty(&dft); fitEmpty(&fit);
600 return(21);
601 }
602 tpcProgramName(argv[0], 1, 0, temp, 128);
603 sprintf(dft.comments, "# program := %s\n", temp);
604 dft.isweight=0;
605 if(dftWrite(&dft, outfile)) {
606 fprintf(stderr, "Error in writing '%s': %s\n", outfile, dfterrmsg);
607 dftEmpty(&dft); fitEmpty(&fit);
608 return(22);
609 }
610 if(verbose>0) printf("Fitted TACs written in %s\n", outfile);
611 }
612
613 /* Free memory */
614 dftEmpty(&dft); fitEmpty(&fit);
615
616 return(0);
617}
618/*****************************************************************************/
619
620/*****************************************************************************
621 *
622 * Functions to be minimized
623 *
624 *****************************************************************************/
625double func841(int parNr, double *p, void *fdata)
626{
627 int i;
628 double a, b, c, q, v, wss;
629 double pa[MAX_PARAMETERS], penalty=1.0;
630
631 /* Check parameters against the constraints */
632 (void)modelCheckParameters(parNr, pmin, pmax, p, pa, &penalty);
633 if(fdata) {}
634
635 /* Get parameters */
636 a=pa[0]; b=pa[1]; c=pow(10., pa[2]);
637 /* Calculate the curve values and weighted SS */
638 for(i=0, wss=0.0; i<dataNr; i++) {
639 if(x[i]>=0.0) q=pow(x[i], b); else q=1.0;
640 yfit[i]= a*q/(q+c); if(isnan(ymeas[i])) continue;
641 v=yfit[i]-ymeas[i]; wss+=w[i]*v*v;
642 }
643 // printf("%g %g %g -> %g\n", a, b, c, wss);
644 wss*=penalty;
645
646 return(wss);
647}
648
649double func844(int parNr, double *p, void *fdata)
650{
651 int i;
652 double a, b, c, d, q, v, wss;
653 double pa[MAX_PARAMETERS], penalty=1.0;
654 if(fdata) {}
655
656 /* Check parameters against the constraints */
657 (void)modelCheckParameters(parNr, pmin, pmax, p, pa, &penalty);
658
659 /* Get parameters */
660 a=pa[0]; b=pa[1]; c=pow(10., pa[2]); d=pa[3];
661 /* Calculate the curve values and weighted SS */
662 for(i=0, wss=0.0; i<dataNr; i++) {
663 if(ymeas[i]<min1) continue;
664 if(x[i]>=0.0) q=pow(x[i], b); else q=1.0;
665 yfit[i]= a*q/(q+c) + d; if(isnan(ymeas[i])) continue;
666 v=yfit[i]-ymeas[i]; wss+=w[i]*v*v;
667 }
668 // printf("%g %g %g %g -> %g\n", a, b, c, d, wss);
669 wss*=penalty;
670
671 return(wss);
672}
673
674double func2801(int parNr, double *p, void *fdata)
675{
676 int i;
677 double top, bottom, ec50, hillslope, v, wss;
678 double pa[MAX_PARAMETERS], penalty=1.0;
679 if(fdata) {}
680
681 /* Check parameters against the constraints */
682 (void)modelCheckParameters(parNr, pmin, pmax, p, pa, &penalty);
683
684 /* Get parameters */
685 top=pa[0]; bottom=pa[1]; ec50=pa[2]; hillslope=pa[3];
686 /* Calculate the curve values and weighted SS */
687 for(i=0, wss=0.0; i<dataNr; i++) {
688 if(x[i]<0.0) {yfit[i]=bottom; continue;}
689 if(x[i]<1.0E-12) yfit[i]=bottom;
690 else yfit[i]=bottom+(top-bottom)/(1.0+pow(ec50/x[i],hillslope));
691 if(isnan(ymeas[i])) continue;
692 v=yfit[i]-ymeas[i]; wss+=w[i]*v*v;
693 }
694 wss*=penalty;
695
696 return(wss);
697}
698/*****************************************************************************/
699
700/*****************************************************************************/
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
double atof_dpi(char *str)
Definition decpoint.c:59
void dftInit(DFT *data)
Definition dft.c:38
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
int getActualSamplenr(DFT *dft, int ri)
Definition fittime.c:288
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
int MATHFUNC_TEST
Definition mathfunc.c:5
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
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]
double * y3