8#include "tpcclibConfig.h"
27double func_suri(
int parNr,
double *p,
void*);
31typedef struct FITDATA {
47static char *info[] = {
48 "Non-linear fitting of the Surge function plus integral (recirculation)",
49 "to PET time-activity curves (TACs).",
52 " when x<=dT, f(x) = 0 ",
53 " when x>dT, f(x) = A*(x-dT)*exp(-B*(x-dT)) + ",
54 " (C*A/B^2)*(1-exp(-B*(x-dT))-B*(x-dT)*exp(-B*(x-dT)))",
55 ", where A>=0, B>=0, C>=0, and dT>=0.",
57 "Usage: @P [Options] tacfile [parfile]",
61 " All weights are set to 1.0 (no weighting), or weights are based on",
62 " sampling interval. By default, weights in tacfile are used, if available.",
64 " Specify the constraints for function parameters;",
65 " This file with default values can be created by giving this option",
66 " as the only command-line argument to this program.",
67 " Without file name the default values are printed on screen.",
68 " Setting feasible limits are highly recommended.",
70 " Fitted and measured TACs are plotted in specified SVG file.",
73 "See also: fit_sinf, fit_feng, fit_ratf, fit2dat",
75 "Keywords: TAC, curve fitting",
94int main(
int argc,
char **argv)
96 int ai, help=0, version=0, verbose=1;
97 char tacfile[FILENAME_MAX], parfile[FILENAME_MAX], svgfile[FILENAME_MAX];
98 char limfile[FILENAME_MAX];
100 unsigned int model=0;
106 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
107 tacfile[0]=parfile[0]=svgfile[0]=limfile[0]=(char)0;
110 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
112 char *cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(!*cptr)
continue;
113 if(strcasecmp(cptr,
"W1")==0) {
115 }
else if(strcasecmp(cptr,
"WF")==0) {
117 }
else if(strncasecmp(cptr,
"SVG=", 4)==0 && strlen(cptr)>4) {
118 strlcpy(svgfile, cptr+4, FILENAME_MAX);
continue;
119 }
else if(strncasecmp(cptr,
"LIM=", 4)==0 && strlen(cptr)>4) {
120 strlcpy(limfile, cptr+4, FILENAME_MAX);
continue;
121 }
else if(strcasecmp(cptr,
"LIM")==0) {
122 strcpy(limfile,
"stdout");
continue;
124 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
133 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
138 if(ai<argc)
strlcpy(tacfile, argv[ai++], FILENAME_MAX);
139 if(ai<argc)
strlcpy(parfile, argv[ai++], FILENAME_MAX);
141 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
147 if(tacfile[0]) printf(
"tacfile := %s\n", tacfile);
148 if(limfile[0]) printf(
"limfile := %s\n", limfile);
149 if(parfile[0]) printf(
"parfile := %s\n", parfile);
150 if(svgfile[0]) printf(
"svgfile := %s\n", svgfile);
151 printf(
"model := %s\n",
modelCode(model));
152 printf(
"weights := %d\n",
weights);
157 fprintf(stderr,
"Error: cannot initiate parameter list.\n");
return(1);}
159 strcpy(plim.
n[0].
name,
"A"); plim.
n[0].
lim1=0.0; plim.
n[0].
lim2=1.0E+04;
160 strcpy(plim.
n[1].
name,
"B"); plim.
n[1].
lim1=1.0E-06; plim.
n[1].
lim2=1.0E+01;
161 strcpy(plim.
n[2].
name,
"C"); plim.
n[2].
lim1=1.0E-06; plim.
n[2].
lim2=1.0E+03;
164 if(limfile[0] && !tacfile[0]) {
166 if(strcasecmp(limfile,
"stdout")!=0 &&
fileExist(limfile)) {
167 fprintf(stderr,
"Error: parameter constraint file %s exists.\n", limfile);
172 if(verbose>1 && strcasecmp(limfile,
"stdout")!=0)
173 printf(
"writing parameter constraints file\n");
175 fprintf(stderr,
"Error: cannot write constraints file.\n");
178 if(strcasecmp(limfile,
"stdout")!=0)
179 fprintf(stdout,
"Parameter constraints written in %s\n", limfile);
185 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
188 if(strcasecmp(limfile,
"stdout")==0) limfile[0]=(char)0;
196 fprintf(stderr,
"Error: cannot read constraints file.\n");
207 if(verbose>1) printf(
"reading %s\n", tacfile);
215 printf(
"tacNr := %d\n", tac.
tacNr);
216 printf(
"sampleNr := %d\n", tac.
sampleNr);
219 printf(
"isframe := %d\n", tac.
isframe);
222 fprintf(stderr,
"Error: file contains no data.\n");
226 fprintf(stderr,
"Error: too few samples.\n");
231 fprintf(stderr,
"Error: data contains missing values.\n");
239 fprintf(stderr,
"Error: invalid data sample times.\n");
243 printf(
"xmin := %g\n", xmin);
244 printf(
"xmax := %g\n", xmax);
247 if(!limfile[0] && plim.
n[0].
lim2>plim.
n[0].
lim1 && xmax<plim.
n[0].
lim2/0.75)
248 plim.
n[0].
lim2=0.75*xmax;
254 for(
int i=0; i<tac.
sampleNr; i++) tac.
w[i]=1.0;
258 for(
int i=0; i<tac.
sampleNr; i++) tac.
w[i]=1.0;
270 if(verbose>1) printf(
"preparing space for parameters\n");
278 for(
int i=0; i<tac.
tacNr; i++) {
292 iftPut(&par.
h,
"program", buf, 0, NULL);
295 iftPut(&par.
h,
"datafile", tacfile, 0, NULL);
301 if(verbose>1) printf(
"preparing for fitting\n");
305 if(verbose>0) printf(
"fitting...\n");
306 for(
int ci=0; ci<tac.
tacNr; ci++) {
307 if(verbose>1) printf(
"TAC %d: %s\n", 1+ci, tac.
c[ci].
name);
309 double ymax;
int ymaxi;
310 if(
tacYRange(&tac, ci, NULL, &ymax, NULL, &ymaxi, NULL, NULL)!=0) {
311 fprintf(stderr,
"Error: invalid y (concentration) values.\n");
314 if(verbose>3) printf(
" ymax := %g\n", ymax);
320 fitdata.ymeas=tac.
c[ci].
y;
326 fprintf(stderr,
"Error: cannot initiate NLLS.\n");
332 for(
int i=0; i<par.
parNr; i++) {
336 for(
int i=0; i<par.
parNr; i++) {
357 printf(
"measured and fitted TAC:\n");
359 printf(
"\t%g\t%g\t%g\n", tac.
x[i], tac.
c[ci].
y[i], yfit[i]);
364 for(
int i=0; i<par.
parNr; i++) par.
r[ci].
p[i]=nlo.
xfull[i];
374 if(verbose>1) printf(
" saving %s\n", parfile);
375 FILE *fp=fopen(parfile,
"w");
377 fprintf(stderr,
"Error: cannot open file for writing.\n");
386 if(verbose>0) printf(
"parameters saved in %s\n", parfile);
395 if(verbose>1) printf(
"plotting measured and fitted data\n");
408 for(
int ci=0; ci<tac.
tacNr && ret==0; ci++)
420 for(
int ci=0; ci<tac.
tacNr && ret==0; ci++)
424 fprintf(stderr,
"Error: cannot calculate function values.\n");
430 ret=
tacPlotFitSVG(&tac, &ftac,
"", nan(
""), nan(
""), nan(
""), nan(
""), svgfile, &status);
437 if(verbose>0) printf(
"Measured and fitted data plotted in %s\n", svgfile);
453double func_suri(
int parNr,
double *p,
void *fdata)
456 FITDATA *d=(FITDATA*)fdata;
459 for(
unsigned int i=0; i<d->n; i++) {
461 if(isnan(d->ymeas[i]) || isnan(d->x[i]))
continue;
462 double x=d->x[i]-p[3];
468 d->ysim[i]=x*e + (c/(b*b))*(1.0-(b*x+1.0)*e);
471 v=d->ysim[i]-d->ymeas[i];
475 for(
unsigned int i=0; i<(
unsigned int)parNr; i++) printf(
" %g", p[i]);
476 printf(
" -> %g\n", wss);
char * ctime_r_int(const time_t *t, char *buf)
Convert calendar time t into a null-terminated string of the form YYYY-MM-DD hh:mm:ss,...
int fileExist(const char *filename)
int mfEvalY(const char *fid, const int parNr, const double *p, const int sampleNr, const double *x, double *y, const int verbose)
unsigned int drandSeed(short int seed)
Make and optionally set the seed for rand(), drand, drandRange, and drandGaussian().
int iftPut(IFT *ift, const char *key, const char *value, char comment, TPCSTATUS *status)
unsigned int simSamples(double initStep, double maxStep, double endTime, int mode, double *x)
char * modelCode(const unsigned int i)
unsigned int modelParNr(const unsigned int code)
unsigned int modelCodeIndex(const char *s)
void nloptInit(NLOPT *nlo)
int nloptAllocate(NLOPT *nlo, unsigned int parNr)
void nloptFree(NLOPT *nlo)
void nloptWrite(NLOPT *d, FILE *fp)
int parAllocate(PAR *par, int parNr, int tacNr)
int parWrite(PAR *par, FILE *fp, parformat format, int extra, TPCSTATUS *status)
int parReadLimits(PAR *par, const char *fname, const int verbose)
void parListLimits(PAR *par, FILE *fp)
int parWriteLimits(PAR *par, const char *fname, const int verbose)
int parAllocateWithTAC(PAR *par, TAC *tac, int parNr, TPCSTATUS *status)
Allocate PAR based on data in TAC.
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)
int nloptSimplexARRS(NLOPT *nlo, unsigned int maxIter, TPCSTATUS *status)
void statusInit(TPCSTATUS *s)
char * errorMsg(tpcerror e)
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
double(* _fun)(int, double *, void *)
IFT h
Optional (but often useful) header information.
char name[MAX_PARNAME_LEN+1]
char name[MAX_TACNAME_LEN+1]
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
int tacAllocate(TAC *tac, int sampleNr, int tacNr)
int tacCopyTacchdr(TACC *d1, TACC *d2)
int tacCopyHdr(TAC *tac1, TAC *tac2)
Copy TAC header data from tac1 to tac2.
int tacPlotFitSVG(TAC *tac1, TAC *tac2, const char *main_title, const double x1, const double x2, const double y1, const double y2, const char *fname, TPCSTATUS *status)
int tacRead(TAC *d, const char *fname, TPCSTATUS *status)
char * tacFormattxt(tacformat c)
int tacWrite(TAC *tac, FILE *fp, tacformat format, int extra, TPCSTATUS *status)
int tacSortByTime(TAC *d, TPCSTATUS *status)
int tacIsWeighted(TAC *tac)
unsigned int tacWSampleNr(TAC *tac)
int tacWByFreq(TAC *tac, isotope isot, TPCSTATUS *status)
int tacGetSampleInterval(TAC *d, double ilimit, double *minfdur, double *maxfdur)
Get the shortest and longest sampling intervals or frame lengths in TAC structure.
int tacXRange(TAC *d, double *xmin, double *xmax)
Get the range of x values (times) in TAC structure.
int tacYRange(TAC *d, int i, double *ymin, double *ymax, int *smin, int *smax, int *imin, int *imax)
Get the range of y values (concentrations) in TAC struct.
int nloptIATGO(NLOPT *nlo, const int doLocal, unsigned int maxIterNr, double neighFract, TPCSTATUS *status)
Header file for library libtpcextensions.
weights
Is data weighted, or are weight factors available with data?
@ WEIGHTING_OFF
Not weighted or weights not available (weights for all included samples are 1.0).
char * unitName(int unit_code)
Header file for libtpcfileutil.
Header file for library libtpcift.
@ ISOTOPE_UNKNOWN
Unknown.
Header file for library libtpcnlopt.
Header file for libtpcpar.
@ PAR_FORMAT_FIT
Function fit format of Turku PET Centre.
@ PAR_FORMAT_TSV_UK
UK TSV (point as decimal separator).
Header file for libtpcrand.
Header file for library libtpctac.
@ TAC_FORMAT_UNKNOWN
Unknown format.
Header file for libtpctacmod.