8#include "tpcclibConfig.h"
32double func_b2p(
int parNr,
double *p,
void*);
34typedef struct FITDATA {
55static char *info[] = {
56 "Calculate or fit PTAC based on BTAC in cell trapping model.",
57 "Give parameter k in units 1/min, or 'fit' in order to try to fit it.",
59 "Usage: @P [Options] btacfile k ptacfile",
63 " Time (in minutes) after the PTAC is assumed to be 0 and BTAC steady;",
64 " by default 3 min; only used when k is fitted.",
66 " BTAC and (1-HCT*)PTAC are plotted in specified SVG file.",
69 "See also: fitmtrap, imgmtrap, b2rbc",
71 "Keywords: input, blood, plasma",
95int main(
int argc,
char **argv)
97 int ai, help=0, version=0, verbose=1;
98 char btacfile[FILENAME_MAX], ptacfile[FILENAME_MAX];
99 char svgfile[FILENAME_MAX];
100 double fixed_k=nan(
"");
110 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
111 btacfile[0]=ptacfile[0]=svgfile[0]=(char)0;
113 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
115 char *cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(!*cptr)
continue;
116 if(strncasecmp(cptr,
"SVG=", 4)==0 && strlen(cptr)>4) {
117 strlcpy(svgfile, cptr+4, FILENAME_MAX);
continue;
118 }
else if(strncasecmp(cptr,
"ZTIME=", 6)==0 && strlen(cptr)>6) {
119 if(!
atofCheck(cptr+6, &zt) && zt>0.0)
continue;
120 }
else if(strcasecmp(cptr,
"W1")==0) {
122 }
else if(strcasecmp(cptr,
"WF")==0) {
125 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
134 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
139 if(ai<argc)
strlcpy(btacfile, argv[ai++], FILENAME_MAX);
141 if(strcasecmp(argv[ai],
"FIT")!=0) {
142 if(
atofCheck(argv[ai], &fixed_k) || !(fixed_k>0.0)) {
143 fprintf(stderr,
"Error: invalid k value '%s'.\n", argv[ai]);
149 if(ai<argc)
strlcpy(ptacfile, argv[ai++], FILENAME_MAX);
151 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
157 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
164 printf(
"btacfile := %s\n", btacfile);
165 printf(
"ptacfile := %s\n", ptacfile);
166 if(!isnan(fixed_k)) printf(
"fixed_k := %g\n", fixed_k);
167 else printf(
"ztime := %g min\n", zt);
176 if(verbose>1) printf(
"reading %s\n", btacfile);
184 printf(
"tacNr := %d\n", tac.
tacNr);
185 printf(
"sampleNr := %d\n", tac.
sampleNr);
188 printf(
"isframe := %d\n", tac.
isframe);
191 fprintf(stderr,
"Error: file contains no data.\n");
193 }
else if(tac.
tacNr>1) {
194 if(verbose>0) fprintf(stderr,
"Warning: file contains more than one curve.\n");
199 fprintf(stderr,
"Error: data contains missing values.\n");
206 fprintf(stderr,
"Error: cannot process duplicate samples.\n");
212 fprintf(stderr,
"Error: invalid data sample times.\n");
225 fprintf(stderr,
"Error: invalid data sample times.\n");
229 printf(
"xmin := %g\n", xmin);
230 printf(
"xmax := %g\n", xmax);
233 fprintf(stderr,
"Error: too few samples.\n");
237 if(isnan(fixed_k) && (zt>=xmax || zt<=xmin)) {
238 fprintf(stderr,
"Error: ztime outside of data range.\n");
244 if(verbose>1) fprintf(stdout,
"allocating memory for PTAC\n");
246 fprintf(stderr,
"Error: cannot allocate memory.\n");
249 strcpy(tac.
c[1].
name,
"PTAC");
250 strcpy(tac.
c[0].
name,
"BTAC");
257 for(
int i=0; i<tac.
sampleNr; i++) tac.
w[i]=1.0;
271 fitdata.ymeas=tac.
c[0].
y;
272 fitdata.ysim=tac.
c[1].
y;
275 fitdata.optcrit=optcrit;
276 if(verbose>10) fitdata.verbose=verbose-10;
else fitdata.verbose=0;
283 func_b2p(1, &fixed_k, &fitdata);
292 if(verbose>1) printf(
"preparing for fitting\n");
298 fprintf(stderr,
"Error: cannot initiate NLLS.\n");
318 printf(
"measured and simulated TAC:\n");
320 printf(
"\t%g\t%g\t%g\n", tac.
x[i], tac.
c[0].
y[i], tac.
c[1].
y[i]);
322 if(verbose>0) printf(
"WSS := %g\n", nlo.
funval);
323 if(verbose>0) printf(
"k := %g\n", nlo.
xfull[0]);
332 if(verbose>1) printf(
"saving (1-HCT)*Cp TAC\n");
336 FILE *fp; fp=fopen(ptacfile,
"w");
338 fprintf(stderr,
"Error: cannot open file for writing '%s'.\n", ptacfile);
349 if(verbose>0) printf(
"(1-HCT)*PTAC written in %s.\n", ptacfile);
363double func_b2p(
int parNr,
double *p,
void *fdata)
365 FITDATA *d=(FITDATA*)fdata;
367 if(d->verbose>0) {printf(
"%s()\n", __func__); fflush(stdout);}
368 if(parNr!=1)
return(nan(
""));
369 if(d->verbose>20) printf(
"p[]: %g\n", p[0]);
374 double t_last=0.0, cp_last=0.0, cpi_last=0.0;
377 for(
unsigned int i=0; i<d->n; i++) {
379 double dt2=0.5*(d->x[i]-t_last);
380 if(!isnan(d->ymeas[i]) && !isnan(d->x[i]) && dt2>0.0) {
382 d->ysim[i] = (d->ymeas[i] - p[0]*(cpi_last + dt2*cp_last)) / (1.0 + dt2*p[0]);
384 cpi+=(d->ysim[i]+cp_last)*dt2;
392 if(d->x[i]>=d->start && !isnan(v)) {
394 wss+=d->w[i]*fabs(v);
400 if(d->verbose>20) printf(
"p[]: %g WSS=%g start=%g\n", p[0], wss, d->start);
int atofCheck(const char *s, double *v)
unsigned int drandSeed(short int seed)
Make and optionally set the seed for rand(), drand, drandRange, and drandGaussian().
void nloptInit(NLOPT *nlo)
int nloptAllocate(NLOPT *nlo, unsigned int parNr)
void nloptFree(NLOPT *nlo)
void nloptWrite(NLOPT *d, FILE *fp)
char * optcritCode(optimality_criterion id)
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
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)
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 *)
char name[MAX_TACNAME_LEN+1]
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
int tacAllocateMore(TAC *tac, int tacNr)
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 tacSwapTACCs(TAC *d, int i1, int i2)
int tacMultipleSamples(TAC *d1, const int fixMode, TAC *d2, const int verbose)
Check TAC data for multiple samples with the same sample time. Optionally replace the multiple sample...
int tacXUnitConvert(TAC *tac, const int u, TPCSTATUS *status)
int tacWByFreq(TAC *tac, isotope isot, TPCSTATUS *status)
int tacXRange(TAC *d, double *xmin, double *xmax)
Get the range of x values (times) in TAC structure.
int nloptITGO1(NLOPT *nlo, const int doLocal, unsigned int tgoNr, unsigned int sampleNr, unsigned int neighNr, TPCSTATUS *status)
Header file for libtpccm.
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).
@ UNIT_UNKNOWN
Unknown unit.
@ TPCERROR_FAIL
General error.
char * unitName(int unit_code)
Header file for libtpcfileutil.
Header file for library libtpcift.
@ ISOTOPE_UNKNOWN
Unknown.
Header file for libtpcli.
Header file for libtpclinopt.
Header file for libtpcmodels.
optimality_criterion
Optimality Criterion for statistical optimizations.
@ OPTCRIT_OLS
Ordinary Least Squares (sum-of-squares, SS).
@ OPTCRIT_LAD
Least Absolute Deviations (sum of absolute deviations, LAE, LAV, LAR).
Header file for library libtpcnlopt.
Header file for libtpcpar.
Header file for libtpcrand.
Header file for library libtpctac.
@ TAC_FORMAT_PMOD
PMOD TAC format.
Header file for libtpctacmod.