8#include "tpcclibConfig.h"
22double func_ratf(
int parNr,
double *p,
void*);
24double *x, *ymeas, *yfit, *w;
30static char *info[] = {
31 "Non-linear fitting of 1st-3rd degree rational function to PET plasma and",
32 "tissue time-activity curves (TACs).",
36 " p1 + p3*x + p5*x^2 + p7*x^3 ",
37 " f(x) = --------------------------- ",
38 " p2 + p4*x + p6*x^2 + p8*x^3 ",
40 ", where p1=0 and p2=1.",
42 "Usage: @P [Options] tacfile fitfile",
46 " All weights are set to 1.0 (no weighting); by default, weights in",
47 " data file are used, if available.",
49 " Weight by sampling interval.",
51 " Fitted and measured TACs are plotted in specified SVG file.",
54 "Options for selecting the rational function:",
55 " -p3p3 3rd degree polynomial/3rd degree polynomial (default)",
56 " -p3p2 3rd degree polynomial/2nd degree polynomial",
57 " -p2p2 2nd degree polynomial/2nd degree polynomial",
58 " -p2p1 2nd degree polynomial/1st degree polynomial",
59 " -p1p1 1st degree polynomial/1st degree polynomial",
61 "Program writes the fit start and end times, nr of points, WSS,",
62 "and parameters (p1, p2, ...) of the fitted function to the fit file.",
64 "See also: fit2dat, fit_exp, fit_sigm, fit_ppf",
66 "Keywords: curve fitting, TAC, simulation, rational function",
85int main(
int argc,
char **argv)
87 int ai, help=0, version=0, verbose=1;
88 int fi, pi, ri, type=-1, ret;
89 char *cptr, datfile[FILENAME_MAX], fitfile[FILENAME_MAX],
90 svgfile[FILENAME_MAX];
94 double a, b, c, tstart, tstop, miny, maxy;
95 enum {MODEL_UNKNOWN, MODEL_P3P3, MODEL_P3P2, MODEL_P2P2,
96 MODEL_P2P1, MODEL_P1P1};
97 int model=MODEL_UNKNOWN;
98 static char *model_name[] = {
"Unknown",
"pol3/pol3",
"pol3/pol2",
"pol2/pol2",
99 "pol2/pol1",
"pol1/pol1", 0};
100 int func_par_nr[6]={0,6,5,4,3,2};
107 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
108 datfile[0]=fitfile[0]=svgfile[0]=(char)0;
111 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
112 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
114 if(strcasecmp(cptr,
"P3P3")==0) {
115 model=MODEL_P3P3; type=233;
continue;
116 }
else if(strcasecmp(cptr,
"P3P2")==0) {
117 model=MODEL_P3P2; type=232;
continue;
118 }
else if(strcasecmp(cptr,
"P2P2")==0) {
119 model=MODEL_P2P2; type=222;
continue;
120 }
else if(strcasecmp(cptr,
"P2P1")==0) {
121 model=MODEL_P2P1; type=221;
continue;
122 }
else if(strcasecmp(cptr,
"P1P1")==0) {
123 model=MODEL_P1P1; type=211;
continue;
124 }
else if(strcasecmp(cptr,
"W1")==0) {
126 }
else if(strcasecmp(cptr,
"WF")==0) {
128 }
else if(strncasecmp(cptr,
"SVG=", 4)==0 && strlen(cptr)>4) {
129 strcpy(svgfile, cptr+4);
continue;
131 fprintf(stderr,
"Error: invalid option '%s'\n", argv[ai]);
136 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
141 for(; ai<argc; ai++) {
142 if(!datfile[0]) {strcpy(datfile, argv[ai]);
continue;}
143 else if(!fitfile[0]) {strcpy(fitfile, argv[ai]);
continue;}
144 fprintf(stderr,
"Error: invalid argument '%s'\n", argv[ai]);
150 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
154 if(type<=0) type=233;
155 if(model==MODEL_UNKNOWN) model=MODEL_P3P3;
156 parNr=func_par_nr[model];
160 printf(
"datfile := %s\n", datfile);
161 printf(
"fitfile := %s\n", fitfile);
162 printf(
"svgfile := %s\n", svgfile);
163 printf(
"type := %d\n", type);
164 printf(
"parNr := %d\n", parNr);
165 printf(
"weights := %d\n", weights);
172 pmin[0]=-1.0e3; pmax[0]=5.0e3;
173 pmin[1]=-5.0e2; pmax[1]=1.0e3;
174 pmin[2]=-5.0e2; pmax[2]=1.0e4;
175 pmin[3]=-0.10; pmax[3]=1.0e4;
176 pmin[4]=-5.00; pmax[4]=5.0e3;
177 pmin[5]=-1.0e2; pmax[5]=1.0e4;
183 if(verbose>1) printf(
"reading %s\n", datfile);
185 fprintf(stderr,
"Error in reading '%s': %s\n", datfile,
dfterrmsg);
189 fprintf(stderr,
"Error: not enough samples for decent fitting.\n");
196 fprintf(stderr,
"Error: missing sample(s) in %s\n", datfile);
205 ret=
dftMinMax(&dft, &tstart, &tstop, &miny, &maxy);
207 fprintf(stderr,
"Error: invalid contents in %s\n", datfile);
210 if(dataNr<3 || tstop<=0.0 || maxy<=0.0) {
211 fprintf(stderr,
"Error: invalid contents in %s\n", datfile);
214 if(tstart<0.0) fprintf(stderr,
"Warning: negative x value(s).\n");
215 if(miny<0.0) fprintf(stderr,
"Warning: negative y value(s).\n");
221 }
else if(weights==1) {
223 }
else if(weights==2) {
232 if(verbose>1) printf(
"allocating memory for fits.\n");
235 fprintf(stderr,
"Error: cannot allocate space for fit results (%d).\n", ret);
240 strncpy(fit.
datafile, datfile, FILENAME_MAX);
244 for(ri=0; ri<dft.
voiNr; ri++) {
254 double xscale, yscale[dft.
voiNr];
256 for(ri=0; ri<dft.
voiNr; ri++) {
258 for(fi=1; fi<dft.
frameNr; fi++)
259 if(dft.
voi[ri].
y[fi]>a) a=dft.
voi[ri].
y[fi];
263 printf(
"xscale=%g yscale=", xscale);
264 for(ri=0; ri<dft.
voiNr; ri++) printf(
"%g ", yscale[ri]);
269 scaled_data=malloc(
sizeof(
double)*3*dft.
frameNr);
270 if(scaled_data==NULL) {
271 fprintf(stderr,
"Error: out of memory.\n");
276 x=scaled_data; ymeas=scaled_data+dft.
frameNr; yfit=ymeas+dft.
frameNr;
279 for(fi=0; fi<dft.
frameNr; fi++) x[fi]=xscale*dft.
x[fi];
285 if(verbose>1) {printf(
"fitting\n"); fflush(stdout);}
286 for(ri=0; ri<dft.
voiNr; ri++) {
287 if(verbose>0 && dft.
voiNr>1) printf(
"%s\n", dft.
voi[ri].
name);
290 for(fi=0; fi<dft.
frameNr; fi++)
291 ymeas[fi]=yscale[ri]*dft.
voi[ri].
y[fi];
294 fit.
voi[ri].
p[0]=0.0; fit.
voi[ri].
p[1]=1.0;
295 fit.
voi[ri].
wss=3.402823e+38;
300 ret=
tgo(pmin, pmax, func_ratf, NULL, parNr, 15, &fit.
voi[ri].
wss,
301 fit.
voi[ri].
p+2, 1000, 3, verbose-8);
303 fprintf(stderr,
"Error %d in TGO.\n", ret);
310 printf(
" Measured Fitted:\n");
311 for(fi=0; fi<dft.
frameNr; fi++)
312 printf(
" %2d: %8.2e %8.2e %8.2e\n", fi+1, x[fi], ymeas[fi], yfit[fi]);
316 printf(
" fitted parameters (scaled), with limits:\n");
317 for(pi=0; pi<parNr; pi++)
318 printf(
" %g [%g, %g]\n", fit.
voi[ri].
p[pi+2], pmin[pi], pmax[pi]);
324 fit.
voi[ri].
p+2, fit.
voi[ri].
p+2, &a);
327 func_ratf(parNr, fit.
voi[ri].
p+2, NULL);
330 for(fi=0; fi<dft.
frameNr; fi++) dft.
voi[ri].
y2[fi]=yfit[fi]/yscale[ri];
334 for(fi=0; fi<dft.
frameNr; fi++) {
337 if(fi==0 || fabs(b)>c) c=fabs(b);
340 if(verbose>1) printf(
" max_dev := %g\n", c);
341 if(verbose>4) printf(
"\n last_y := %g\n\n", dft.
voi[ri].
y2[dft.
frameNr-1]);
344 for(pi=0; pi<parNr; pi+=2)
345 fit.
voi[ri].
p[pi+2]/=yscale[ri];
346 for(pi=0; pi<parNr; pi++)
347 fit.
voi[ri].
p[pi+2]*=(
double)pow(xscale, floor(1+pi/2));
365 if(verbose>1) printf(
"saving results in %s\n", fitfile);
367 fprintf(stderr,
"Error in writing '%s': %s\n", fitfile,
fiterrmsg);
375 if(verbose>1) printf(
"saving SVG plot\n");
382 fprintf(stderr,
"Error: cannot plot fitted curves.\n");
386 for(ri=0; ri<dft.
voiNr; ri++)
for(fi=0; fi<dft.
frameNr; fi++)
391 strcat(tmp, model_name[model]); strcat(tmp,
" ");
395 fprintf(stderr,
"Error (%d) in writing '%s'.\n", ret, svgfile);
399 if(verbose>0) printf(
"Plots written in %s\n", svgfile);
416double func_ratf(
int parNr,
double *p,
void *fdata)
419 double v, dd, dr, x2, x3, wss;
426 for(i=0; i<parNr; i++) printf(
" p[%d]=%g", i, p[i]);
432 for(i=0, wss=0.0; i<dataNr; i++) {
434 if(parNr>=3) {x2=x[i]*x[i];
if(parNr>=5) x3=x2*x[i];}
437 if(parNr>=2) dr+=pa[1]*x[i];
438 if(parNr>=4) dr+=pa[3]*x2;
439 if(parNr>=6) dr+=pa[5]*x3;
442 if(parNr>=1) dd+=pa[0]*x[i];
443 if(parNr>=3) dd+=pa[2]*x2;
444 if(parNr>=5) dd+=pa[4]*x3;
448 v=yfit[i]-ymeas[i]; wss+=w[i]*v*v;
450 if(!isfinite(wss)) wss=nan(
"");
int modelCheckParameters(int par_nr, double *lower_p, double *upper_p, double *test_p, double *accept_p, double *penalty)
int dftdup(DFT *dft1, DFT *dft2)
int dftSortByFrame(DFT *dft)
int dftMinMax(DFT *dft, double *minx, double *maxx, double *miny, double *maxy)
int dft_nr_of_NA(DFT *dft)
int dftRead(char *filename, DFT *data)
int fit_allocate_with_dft(FIT *fit, DFT *dft)
Header file for libtpccurveio.
int fitWrite(FIT *fit, char *filename)
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
void tpcProgramName(const char *program, int version, int copyright, char *prname, int n)
int tpcHtmlUsage(const char *program, char *text[], const char *path)
void tpcPrintBuild(const char *program, FILE *fp)
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
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)
Header file for libtpcmodext.
int plot_fit_svg(DFT *dft1, DFT *dft2, char *main_title, char *fname, int verbose)
int dftWeightByFreq(DFT *dft)
Header file for libtpcsvg.
char studynr[MAX_STUDYNR_LEN+1]
char unit[MAX_UNITS_LEN+1]
char datafile[FILENAME_MAX]
char unit[MAX_UNITS_LEN+1]
char name[MAX_REGIONNAME_LEN+1]