TPCCLIB
Loading...
Searching...
No Matches
delay.c
Go to the documentation of this file.
1
4/*****************************************************************************/
5#include "tpcclibConfig.h"
6/*****************************************************************************/
7#include <stdio.h>
8#include <stdlib.h>
9#include <math.h>
10#include <time.h>
11#include <string.h>
12/*****************************************************************************/
13#include "tpcextensions.h"
14#include "tpctac.h"
15#include "tpcli.h"
16#include "tpclinopt.h"
17/*****************************************************************************/
18#include "tpctacmod.h"
19/*****************************************************************************/
20
21/*****************************************************************************/
34 TAC *tac,
36 double dt,
38 int ti,
40 TPCSTATUS *status
41) {
42 int verbose=0; if(status!=NULL) verbose=status->verbose;
43 if(verbose>0) printf("%s(tac, %g, %d)\n", __func__, dt, ti);
44 /* Check the function input */
45 if(tac==NULL || tac->sampleNr<1 || tac->tacNr<1) {
46 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
47 return TPCERROR_NO_DATA;
48 }
49 if(ti>=tac->tacNr) {
50 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
51 return TPCERROR_FAIL;
52 }
53 if(fabs(dt)<1.0E-12) {
54 if(verbose>1) printf(" requested delay time is zero; nothing done.\n");
55 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
56 return(TPCERROR_OK);
57 }
58 /* Check that input does not have any missing values */
59 if(tacXNaNs(tac)>0 || tacYNaNs(tac, ti)>0) {
60 if(verbose>1) printf(" data contains NaN(s).\n");
61 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_MISSING_DATA);
63 }
64
65 /* Get and check the x range */
66 double xmin=nan(""), xmax=nan("");
67 if(tacXRange(tac, &xmin, &xmax)!=0 || dt>=xmax || dt<=-xmax) {
68 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE);
70 }
71 if(verbose>2) printf(" xrange: %g - %g\n", xmin, xmax);
72
73
74 /* If TAC contains just frame mid times, then simple dot-to-dot interpolation */
75 if(tac->isframe==0) {
76 /* Make temporary x array */
77 double tx[tac->sampleNr];
78 for(int i=0; i<tac->sampleNr; i++) tx[i]=tac->x[i]+dt;
79 /* One TAC at a time */
80 for(int j=0; j<tac->tacNr; j++) if(ti<0 || ti==j) {
81 /* Make temporary y array */
82 double ty[tac->sampleNr];
83 for(int i=0; i<tac->sampleNr; i++) ty[i]=tac->c[j].y[i];
84 /* Interpolate temporary data to original times */
85 if(liInterpolate(tx, ty, tac->sampleNr, tac->x, tac->c[j].y, NULL, NULL, tac->sampleNr, 0, 1,
86 verbose-10)!=0)
87 {
88 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
90 }
91 }
92 /* That's it then */
93 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
94 return(TPCERROR_OK);
95 }
96
97 /* We have frame start and end times */
98 /* Convert the data into stepwise dot-to-dot data */
99 TAC stac; tacInit(&stac);
100 {
101 int ret=tacFramesToSteps(tac, &stac, NULL);
102 if(ret!=TPCERROR_OK) {
103 tacFree(&stac);
104 statusSet(status, __func__, __FILE__, __LINE__, ret);
105 return(ret);
106 }
107 }
108 /* Change times of the stepwise data */
109 for(int i=0; i<stac.sampleNr; i++) stac.x[i]+=dt;
110 /* Interpolate stepwise data into original frame times, one TAC at a time */
111 for(int j=0; j<tac->tacNr; j++) if(ti<0 || ti==j) {
112 if(liInterpolateForPET(stac.x, stac.c[j].y, stac.sampleNr, tac->x1, tac->x2, tac->c[j].y,
113 NULL, NULL, tac->sampleNr, 0, 1, verbose-10))
114 {
115 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
117 }
118 }
119 tacFree(&stac);
120
121
122 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
123 return(TPCERROR_OK);
124}
125/*****************************************************************************/
126
127/*****************************************************************************/
133 DELAYFITDATA *d
134) {
135 if(d==NULL) return;
136 d->iNr=d->tNr=d->moveNr=0;
137 tacInit(&d->dtac); tacInit(&d->ditac); tacInit(&d->diitac); tacInit(&d->ddtac); tacInit(&d->dddtac);
138 d->mode=0; d->model=0;
139 d->llsq_n=d->llsq_m=0;
140 d->llsq_mat=NULL;
141 d->llsq_a=NULL;
142 d->llsq_b=d->llsq_x=d->llsq_wp=d->llsq_zz=NULL;
143 d->llsq_i=NULL;
144 return;
145}
146/*****************************************************************************/
152 DELAYFITDATA *d
153) {
154 if(d==NULL) return;
155 d->iNr=d->tNr=d->moveNr=0;
156 tacFree(&d->dtac); tacFree(&d->ditac); tacFree(&d->diitac); tacFree(&d->ddtac); tacFree(&d->dddtac);
157 d->mode=0; d->model=0;
158 d->llsq_n=d->llsq_m=0;
159 free(d->llsq_a); free(d->llsq_mat);
160 free(d->llsq_b); free(d->llsq_x); free(d->llsq_wp); free(d->llsq_zz);
161 free(d->llsq_i);
162 return;
163}
164/*****************************************************************************/
165
166/*****************************************************************************/
182 TAC *btac,
185 TAC *ttac,
187 int ci,
190 double dtmin,
193 double dtmax,
198 double fitend,
201 double dtstep,
205 double *dt,
209 int mode,
211 int model,
216 DELAYFITDATA *tdata,
218 TPCSTATUS *status
219) {
220 int verbose=0; if(status!=NULL) verbose=status->verbose;
221 if(verbose>2) {
222 printf("%s(inp, tis, %d, %g, %g, %g, %g, %d, ...)\n", __func__, ci, dtmin, dtmax, fitend, dtstep, mode);
223 fflush(stdout);
224 }
225
226
227 /* Check provided data */
228 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
229 if(ttac==NULL || (btac==NULL && tdata==NULL)) return(TPCERROR_FAIL);
230 if(btac!=NULL && (btac->tacNr<1 || btac->sampleNr<4)) return(TPCERROR_FAIL);
231 if(ci<0 || ci>=ttac->tacNr || ttac->sampleNr<4) return(TPCERROR_FAIL);
232 if(model<0 || model>2) return(TPCERROR_FAIL);
233 if(dt!=NULL) *dt=nan("");
234
235 /* Initiate (possibly reused) data structure */
236 DELAYFITDATA *b, ltdata; initDelayFitData(&ltdata);
237 if(tdata!=NULL) {
238 b=tdata;
239 if(verbose>3) {
240 if(b->moveNr==0) printf(" given temp data will be filled\n");
241 else printf(" filled temp data will be used\n");
242 fflush(stdout);
243 }
244 } else {
245 b=&ltdata;
246 if(verbose>4) {printf(" local temp data created\n"); fflush(stdout);}
247 }
248
249 /* Check and set temp data when run first time with the given TTAC */
250 if(btac!=NULL || b->moveNr==0) {
251 /* Delay range and steps*/
252 if(!(dtmax>dtmin) || !(dtstep>0.001)) {
253 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE);
255 }
256 b->dtmin=dtmin; b->dtmax=dtmax; b->dtstep=dtstep;
257 /* How many delayed curves needed */
258 b->moveNr=1+(b->dtmax-b->dtmin)/b->dtstep;
259 if(verbose>3) printf(" moveNr := %d\n", b->moveNr);
260 if(b->moveNr<5 || b->moveNr>5000) {
261 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE);
263 }
264 /* Get x range */
265 if(tacXRange(ttac, &b->ttac_xmin, &b->ttac_xmax)!=0 || tacXRange(btac, &b->btac_xmin, &b->btac_xmax)!=0) {
266 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE);
268 }
269 if(verbose>3) printf(" TTAC range := %g - %g\n BTAC range := %g - %g\n",
270 b->ttac_xmin, b->btac_xmax, b->ttac_xmin, b->btac_xmax);
271 /* Check that time units do match */
272 if(btac->tunit!=ttac->tunit) {
273 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_X);
274 return(TPCERROR_INVALID_X);
275 }
276 /* Check that input curve is long enough to fit duration */
277 if(!(fitend>0.0)) {
278 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE);
280 }
281 b->fitend=fitend;
282 if(b->fitend>b->ttac_xmax) b->fitend=b->ttac_xmax;
283 if(b->fitend>b->btac_xmax) b->fitend=b->btac_xmax;
284 if(b->dtmin<0.0 && b->btac_xmax<(b->fitend+b->dtmin))
285 b->fitend+=b->dtmin;
286 if(verbose>3) printf("fitend=%g -> %g\n", fitend, b->fitend);
287 b->iNr=0; for(unsigned int i=0; i<(unsigned int)btac->sampleNr; i++) if(btac->x[i]<=b->fitend) b->iNr++; else break;
288 b->tNr=0; for(unsigned int i=0; i<(unsigned int)ttac->sampleNr; i++) if(ttac->x[i]<=b->fitend) b->tNr++; else break;
289 //printf("iNr=%u tNr=%u\n", b->iNr, b->tNr);
290 if(b->iNr<5 || b->tNr<5) {
291 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE);
293 }
294
295 /* Further, when run the first time, make input TACs moved in time, interpolated and integrated
296 to tissue times */
297 if(verbose>5) {printf(" preparing delayed input data\n"); fflush(stdout);}
298 b->mode=mode;
299 b->model=model;
300 int ret;
301 ret=tacAllocate(&b->dtac, b->tNr, b->moveNr+1); // additional place for tissue curve
302 if(ret!=TPCERROR_OK) {
303 freeDelayFitData(&ltdata);
304 statusSet(status, __func__, __FILE__, __LINE__, ret);
306 }
307 b->dtac.sampleNr=b->tNr;
308 b->dtac.tacNr=b->moveNr+1; // tissue as the last curve
309 b->dtac.isframe=ttac->isframe;
310 for(int i=0; i<b->dtac.sampleNr; i++) {
311 b->dtac.x1[i]=ttac->x1[i]; b->dtac.x[i]=ttac->x[i]; b->dtac.x2[i]=ttac->x2[i];}
312 ret=tacDuplicate(&b->dtac, &b->ditac);
313 if(ret==TPCERROR_OK) ret=tacDuplicate(&b->dtac, &b->diitac);
314 if(ret==TPCERROR_OK) ret=tacDuplicate(&b->dtac, &b->ddtac);
315 if(ret==TPCERROR_OK) ret=tacDuplicate(&b->dtac, &b->dddtac);
316 if(ret!=TPCERROR_OK) {
317 freeDelayFitData(&ltdata);
318 statusSet(status, __func__, __FILE__, __LINE__, ret);
319 return(ret);
320 }
321 /* Integrate/derivate input data, change times, and interpolate to tissue data */
322 double bd[btac->sampleNr], bdd[btac->sampleNr];
323 double bi[btac->sampleNr], bii[btac->sampleNr];
324 if(liDerivate3(btac->x, btac->c[0].y, btac->sampleNr, bd, bdd, 0)) {
325 freeDelayFitData(&ltdata);
326 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
328 }
329 if(btac->isframe==0) {
330 if(liIntegrate(btac->x, btac->c[0].y, btac->sampleNr, bi, 3, 0) ||
331 liIntegrate(btac->x, bi, btac->sampleNr, bii, 3, 0))
333 } else {
334 if(liIntegrateFE(btac->x1, btac->x2, btac->c[0].y, btac->sampleNr, bi, bii, 0))
336 }
337 if(ret) {
338 freeDelayFitData(&ltdata);
339 statusSet(status, __func__, __FILE__, __LINE__, ret);
340 return(ret);
341 }
342 double dx[btac->sampleNr], dx2[btac->sampleNr], *dxp;
343 if(btac->isframe==0) dxp=dx; else dxp=dx2;
344 for(int di=0; di<b->dtac.tacNr-1; di++) {
345 for(int i=0; i<btac->sampleNr; i++) {
346 dx[i]=btac->x[i]+b->dtmin+di*b->dtstep;
347 dx2[i]=btac->x2[i]+b->dtmin+di*b->dtstep;
348 }
349 if(b->dtac.isframe==0) {
350 ret=liInterpolate(dx, btac->c[0].y, btac->sampleNr, b->dtac.x, b->dtac.c[di].y,
351 NULL, NULL, b->dtac.sampleNr, 3, 1, 0);
352
353 if(!ret) ret=liInterpolate(dxp, bi, btac->sampleNr, b->dtac.x, b->ditac.c[di].y,
354 NULL, NULL, b->dtac.sampleNr, 3, 1, 0);
355 if(!ret) ret=liInterpolate(dxp, bii, btac->sampleNr, b->dtac.x, b->diitac.c[di].y,
356 NULL, NULL, b->dtac.sampleNr, 3, 1, 0);
357 if(!ret) ret=liInterpolate(dx, bd, btac->sampleNr, b->dtac.x, b->ddtac.c[di].y,
358 NULL, NULL, b->dtac.sampleNr, 3, 1, 0);
359 if(!ret) ret=liInterpolate(dx, bdd, btac->sampleNr, b->dtac.x, b->dddtac.c[di].y,
360 NULL, NULL, b->dtac.sampleNr, 3, 1, 0);
361 } else {
362 ret=liInterpolateForPET(dx, btac->c[0].y, btac->sampleNr, b->dtac.x1, b->dtac.x2,
363 b->dtac.c[di].y, NULL, NULL, b->dtac.sampleNr, 3, 1, 0);
364 if(!ret) ret=liInterpolateForPET(dxp, bi, btac->sampleNr, b->dtac.x1, b->dtac.x2,
365 b->ditac.c[di].y, NULL, NULL, b->dtac.sampleNr, 3, 1, 0);
366 if(!ret) ret=liInterpolateForPET(dxp, bii, btac->sampleNr, b->dtac.x1, b->dtac.x2,
367 b->diitac.c[di].y, NULL, NULL, b->dtac.sampleNr, 3, 1, 0);
368 if(!ret) ret=liInterpolateForPET(dx, bd, btac->sampleNr, b->dtac.x1, b->dtac.x2,
369 b->ddtac.c[di].y, NULL, NULL, b->dtac.sampleNr, 3, 1, 0);
370 if(!ret) ret=liInterpolateForPET(dx, bdd, btac->sampleNr, b->dtac.x1, b->dtac.x2,
371 b->dddtac.c[di].y, NULL, NULL, b->dtac.sampleNr, 3, 1, 0);
372 }
373 if(ret) {
374 freeDelayFitData(&ltdata);
375 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE);
377 }
378 }
379 if(verbose>6) {
380 printf("integrated input curve 1:\n");
381 for(int i=0; i<b->dtac.sampleNr; i++)
382 printf("%g %g %g %g\n", b->dtac.x[i], b->dtac.c[0].y[i], b->ditac.c[0].y[i], b->diitac.c[0].y[i]);
383 fflush(stdout);
384 }
385
386
387 /* Allocate memory for linear LSQ */
388 if(verbose>5) {printf(" preparing data for LLSQ\n"); fflush(stdout);}
389 b->llsq_n=3+b->model;
390 b->llsq_m=b->dtac.sampleNr;
391 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OUT_OF_MEMORY);
392 b->llsq_mat=(double*)malloc((b->llsq_n*b->llsq_m)*sizeof(double));
393 if(b->llsq_mat==NULL) {freeDelayFitData(&ltdata); return(TPCERROR_OUT_OF_MEMORY);}
394 b->llsq_a=(double**)malloc(b->llsq_n*sizeof(double*));
395 if(b->llsq_a==NULL) {freeDelayFitData(&ltdata); return(TPCERROR_OUT_OF_MEMORY);}
396 for(int ni=0; ni<b->llsq_n; ni++) b->llsq_a[ni]=b->llsq_mat+ni*b->llsq_m;
397 b->llsq_b=(double*)malloc(b->llsq_m*sizeof(double));
398 b->llsq_x=(double*)malloc(b->llsq_n*sizeof(double));
399 b->llsq_wp=(double*)malloc(b->llsq_n*sizeof(double));
400 b->llsq_zz=(double*)malloc(b->llsq_m*sizeof(double));
401 b->llsq_i=(int*)malloc(b->llsq_n*sizeof(int));
402 if(b->llsq_b==NULL || b->llsq_x==NULL || b->llsq_wp==NULL || b->llsq_zz==NULL || b->llsq_i==NULL) {
403 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OUT_OF_MEMORY);
404 freeDelayFitData(&ltdata); return(TPCERROR_OUT_OF_MEMORY);}
405 }
406
407 /* Integrate tissue curve */
408 {
409 if(verbose>5) {printf(" preparing tissue data\n"); fflush(stdout);}
410 int ti=b->dtac.tacNr-1; // index of tissue curve after the input curves
411 for(int i=0; i<b->dtac.sampleNr; i++) b->dtac.c[ti].y[i]=ttac->c[ci].y[i];
412
413 int ret=liDerivate(b->dtac.x, b->dtac.c[ti].y, b->dtac.sampleNr, b->ddtac.c[ti].y, b->dddtac.c[ti].y, 0);
414 if(b->dtac.isframe==0) {
415 if(!ret) ret=liIntegrate(b->dtac.x, b->dtac.c[ti].y, b->dtac.sampleNr, b->ditac.c[ti].y, 3, 0);
416 if(!ret) ret=liIntegrate(b->dtac.x, b->ditac.c[ti].y, b->dtac.sampleNr, b->diitac.c[ti].y, 3, 0);
417 } else {
418 if(!ret) ret=liIntegrateFE(b->dtac.x1, b->dtac.x2, b->dtac.c[ti].y, b->dtac.sampleNr,
419 b->ditac.c[ti].y, b->diitac.c[ti].y, 0);
420 }
421 if(ret) {
422 freeDelayFitData(&ltdata);
423 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE);
425 }
426
427 if(verbose>10) {
428 printf("integrated tissue curves:\n");
429 for(int i=0; i<b->dtac.sampleNr; i++)
430 printf("%g %g %g %g\n", b->dtac.x[i], b->dtac.c[ti].y[i], b->ditac.c[ti].y[i], b->diitac.c[ti].y[i]);
431 fflush(stdout);
432 }
433 }
434
435
436 /* Multilinear fitting with each delayed input */
437 if(verbose>5) {printf(" LLSQ\n"); fflush(stdout);}
438 double ss, ssmin=nan("");
439 int mini=-1;
440 for(int di=0; di<b->dtac.tacNr-1; di++) {
441 /* Setup data matrix A and vector B */
442 for(int mi=0; mi<b->llsq_m; mi++) {
443 b->llsq_b[mi]=b->dtac.c[b->dtac.tacNr-1].y[mi]; // TTAC
444 b->llsq_mat[mi]=b->dtac.c[di].y[mi]; // BTAC
445 if(mode==1) {
446 b->llsq_mat[mi+1*b->llsq_m]=b->ddtac.c[di].y[mi]; // BTAC derivate
447 b->llsq_mat[mi+2*b->llsq_m]=-b->ddtac.c[b->dtac.tacNr-1].y[mi]; // TTAC derivate
448 if(b->llsq_n>3) b->llsq_mat[mi+3*b->llsq_m]=b->dddtac.c[di].y[mi]; // BTAC derivate
449 if(b->llsq_n>4) b->llsq_mat[mi+4*b->llsq_m]=-b->dddtac.c[b->dtac.tacNr-1].y[mi]; // TTAC derivate
450 } else if(mode==2) {
451 b->llsq_mat[mi+1*b->llsq_m]=b->ditac.c[di].y[mi]; // BTAC integral
452 b->llsq_mat[mi+2*b->llsq_m]=-b->ditac.c[b->dtac.tacNr-1].y[mi]; // TTAC integral
453 if(b->llsq_n>3) b->llsq_mat[mi+3*b->llsq_m]=b->ddtac.c[di].y[mi]; // BTAC derivate
454 if(b->llsq_n>4) b->llsq_mat[mi+4*b->llsq_m]=-b->ddtac.c[b->dtac.tacNr-1].y[mi]; // TTAC derivate
455 } else { // mode 0
456 b->llsq_mat[mi+1*b->llsq_m]=b->ditac.c[di].y[mi]; // BTAC integral
457 b->llsq_mat[mi+2*b->llsq_m]=-b->ditac.c[b->dtac.tacNr-1].y[mi]; // TTAC integral
458 if(b->llsq_n>3) b->llsq_mat[mi+3*b->llsq_m]=b->diitac.c[di].y[mi]; // BTAC 2nd integral
459 if(b->llsq_n>4) b->llsq_mat[mi+4*b->llsq_m]=-b->diitac.c[b->dtac.tacNr-1].y[mi]; // TTAC 2nd integral
460 }
461 b->llsq_mat[mi]=b->dtac.c[di].y[mi]; // BTAC
462 b->llsq_mat[mi+1*b->llsq_m]=b->ditac.c[di].y[mi]; // BTAC integral
463 b->llsq_mat[mi+2*b->llsq_m]=-b->ditac.c[b->dtac.tacNr-1].y[mi]; // TTAC integral
464 if(b->llsq_n>3) b->llsq_mat[mi+3*b->llsq_m]=b->diitac.c[di].y[mi]; // BTAC 2nd integral
465 if(b->llsq_n>4) b->llsq_mat[mi+4*b->llsq_m]=-b->diitac.c[b->dtac.tacNr-1].y[mi]; // TTAC 2nd integral
466 }
467 if(verbose>3) {
468 int failnr=0;
469 for(int mi=0; mi<b->llsq_m; mi++) {
470 if(!isfinite(b->llsq_b[mi])) failnr++;
471 if(!isfinite(b->llsq_mat[mi])) failnr++;
472 if(!isfinite(b->llsq_mat[mi+1*b->llsq_m])) failnr++;
473 if(!isfinite(b->llsq_mat[mi+2*b->llsq_m])) failnr++;
474 if(!isfinite(b->llsq_mat[mi+3*b->llsq_m])) failnr++;
475 if(!isfinite(b->llsq_mat[mi+4*b->llsq_m])) failnr++;
476 }
477 if(failnr>0) printf("%d bad values\n", failnr);
478 }
479 if(verbose>9 && b->llsq_m<100) {
480 printf("---- B x A ----\n");
481 for(int mi=0; mi<b->llsq_m; mi++) {
482 printf(" %g ", b->llsq_b[mi]);
483 for(int ni=0; ni<b->llsq_n; ni++)
484 printf(" %g", b->llsq_mat[mi+ni*b->llsq_m]);
485 printf("\n");
486 }
487 }
488
489 int ret=nnls(b->llsq_a, b->llsq_m, b->llsq_n, b->llsq_b, b->llsq_x, &ss, b->llsq_wp, b->llsq_zz, b->llsq_i);
490 if(ret<2 && isfinite(ss)) {
491 if(!isfinite(ssmin) || ssmin>ss) {ssmin=ss; mini=di;}
492 if(verbose>2) printf(" %d %d %g %g\n", di, mini, ss, ssmin);
493 } else {
494 if(verbose>1) printf(" failed NNLS\n");
495 }
496 }
497 if(mini<0) {
498 if(verbose>1) fprintf(stderr, "Error: all fits failed.\n");
499 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_BAD_FIT);
500 freeDelayFitData(&ltdata); return(TPCERROR_BAD_FIT);
501 }
502 if(dt!=NULL && mini>=0) *dt=b->dtmin+mini*b->dtstep;
503
504 freeDelayFitData(&ltdata); // the local one, not the one possibly given by caller
505 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
506 return(TPCERROR_OK);
507}
508/*****************************************************************************/
509
510/*****************************************************************************/
int tacDelayFit(TAC *btac, TAC *ttac, int ci, double dtmin, double dtmax, double fitend, double dtstep, double *dt, int mode, int model, DELAYFITDATA *tdata, TPCSTATUS *status)
Fit time delay between PET tissue and plasma or blood curve.
Definition delay.c:179
void initDelayFitData(DELAYFITDATA *d)
Before first use, initiate the data structure for delay time estimation.
Definition delay.c:131
void freeDelayFitData(DELAYFITDATA *d)
After last use, free memory in the data structure for delay time estimation.
Definition delay.c:150
int tacDelay(TAC *tac, double dt, int ti, TPCSTATUS *status)
Move TAC y values (concentrations) in time, keeping sample times (x values) intact.
Definition delay.c:29
int liDerivate3(double *x, double *y, const int nr, double *d, double *dd, const int verbose)
Simplistic derivation of PET TAC using regression line over three points.
Definition integrate.c:493
int liIntegrateFE(double *x1, double *x2, double *y, int nr, double *ie, double *iie, const int verbose)
Linear integration of PET TAC to frame end times.
Definition integrate.c:219
int liIntegrate(double *x, double *y, const int nr, double *yi, const int se, const int verbose)
Linear integration of TAC with trapezoidal method.
Definition integrate.c:33
int liDerivate(double *x, double *y, const int nr, double *d, double *dd, const int verbose)
Simplistic derivation of TAC as Δy divided by Δx, in relation to the previous point.
Definition integrate.c:444
int liInterpolate(double *x, double *y, const int nr, double *newx, double *newy, double *newyi, double *newyii, const int newnr, const int se, const int ee, const int verbose)
Linear interpolation and/or integration with trapezoidal method.
int liInterpolateForPET(double *x, double *y, const int nr, double *newx1, double *newx2, double *newy, double *newyi, double *newyii, const int newnr, const int se, const int ee, const int verbose)
Linear TAC interpolation and/or integration to PET frames.
int nnls(double **a, int m, int n, double *b, double *x, double *rnorm, double *wp, double *zzp, int *indexp)
Definition nnls.c:48
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
double dtmin
Definition tpctacmod.h:47
double * llsq_zz
Definition tpctacmod.h:88
unsigned int moveNr
Definition tpctacmod.h:53
double ** llsq_a
Definition tpctacmod.h:80
double * llsq_x
Definition tpctacmod.h:84
double ttac_xmax
Definition tpctacmod.h:39
int * llsq_i
Definition tpctacmod.h:90
double * llsq_wp
Definition tpctacmod.h:86
double dtstep
Definition tpctacmod.h:51
double dtmax
Definition tpctacmod.h:49
unsigned int tNr
Definition tpctacmod.h:35
double btac_xmax
Definition tpctacmod.h:43
double * llsq_mat
Definition tpctacmod.h:78
double * llsq_b
Definition tpctacmod.h:82
double ttac_xmin
Definition tpctacmod.h:37
unsigned int iNr
Definition tpctacmod.h:33
double fitend
Definition tpctacmod.h:45
double btac_xmin
Definition tpctacmod.h:41
double * y
Definition tpctac.h:75
Definition tpctac.h:87
double * x
Definition tpctac.h:97
int sampleNr
Definition tpctac.h:89
int isframe
Definition tpctac.h:95
TACC * c
Definition tpctac.h:117
double * x2
Definition tpctac.h:101
unit tunit
Definition tpctac.h:109
double * x1
Definition tpctac.h:99
int tacNr
Definition tpctac.h:91
int verbose
Verbose level, used by statusPrint() etc.
void tacFree(TAC *tac)
Definition tac.c:106
int tacDuplicate(TAC *tac1, TAC *tac2)
Make a duplicate of TAC structure.
Definition tac.c:356
int tacAllocate(TAC *tac, int sampleNr, int tacNr)
Definition tac.c:130
void tacInit(TAC *tac)
Definition tac.c:24
int tacYNaNs(TAC *tac, const int i)
Definition tacnan.c:47
int tacXNaNs(TAC *tac)
Definition tacnan.c:23
int tacFramesToSteps(TAC *inp, TAC *out, TPCSTATUS *status)
Transform TAC with frames into TAC with frames represented with stepwise changing dot-to-dot data.
Definition tacx.c:942
int tacXRange(TAC *d, double *xmin, double *xmax)
Get the range of x values (times) in TAC structure.
Definition tacx.c:124
Header file for library libtpcextensions.
@ TPCERROR_INVALID_XRANGE
Invalid sample time range.
@ TPCERROR_INVALID_VALUE
Invalid value.
@ TPCERROR_BAD_FIT
Fitting not successful.
@ TPCERROR_FAIL
General error.
@ TPCERROR_OUT_OF_MEMORY
Cannot allocate memory.
@ TPCERROR_INVALID_X
Invalid sample time.
@ TPCERROR_OK
No error.
@ TPCERROR_NO_DATA
File contains no data.
@ TPCERROR_MISSING_DATA
File contains missing values.
Header file for libtpcli.
Header file for libtpclinopt.
Header file for library libtpctac.
Header file for libtpctacmod.