5#include "tpcclibConfig.h"
58 if(verbose>0) printf(
"liIntegrate(x, y, %d, yi, %d)\n", nr, se);
61 if(x==NULL || y==NULL || yi==NULL)
return 1;
71 if(x[0]>0.0) yi[0]+=x[0]*y[0];
74 if(x[0]>0.0 && y[0]>0.0) yi[0]+=0.5*x[0]*y[0];
77 if(x[0]>0.0 && y[0]>0.0) {
78 if(nr<2 || (2.0*x[0]-x[1])<1.0E-10)
83 if(x[0]>0.0 && y[0]>0.0) {
84 if(nr<2 || (2.0*x[0]-x[1])<1.0E-10)
89 yi[0]+=0.5*(x[0]-nx)*y[0];
95 for(
int j=1; j<nr; j++) yi[j]=yi[j-1]+0.5*(y[j]+y[j-1])*(x[j]-x[j-1]);
97 if(verbose>3) printf(
"liIntegrate() ready\n");
138 if(verbose>0) printf(
"liIntegratePET(x1, x2, y, %d, i, ii)\n", nr);
142 if(x1==NULL || x2==NULL || y==NULL)
return(1);
144 if(ie==NULL && iie==NULL)
return(0);
147 double x, xs, fdur, half_fdur, gap, gap_y, midi, midii, fulli;
148 double box_integral=0.0, box_integral2=0.0;
149 double gap_integral=0.0, gap_integral2=0.0;
150 double prev_x2=x1[0], prev_fdur=0.0;
152 for(i=0; i<nr; i++) {
154 fdur=x2[i]-x1[i];
if(!(fdur>=0.0))
return(2);
158 printf(
" x=%g\n", x);
159 printf(
" fdur=%g\n", fdur);
163 if(i>0 && gap>1.0E-10) {
165 gap_y=fdur*y[i]+prev_fdur*(y[i-1]);
166 xs=fdur+prev_fdur;
if(xs>0.0) gap_y/=xs;
167 gap_integral=gap*gap_y;
168 gap_integral2=gap*0.5*(box_integral+box_integral+gap_integral);
170 printf(
" gap=%g\n", gap);
171 printf(
" gap_y=%g\n", gap_y);
172 printf(
" gap_integral=%g\n", gap_integral);
173 printf(
" gap_integral2=%g\n", gap_integral2);
176 box_integral+=gap_integral;
177 box_integral2+=gap_integral2;
181 midii=0.5*(box_integral+box_integral+midi)*half_fdur;
183 printf(
" midframe_integral=%g\n", midi);
184 printf(
" midframe_integral2=%g\n", midii);
186 if(ie!=NULL) ie[i]=box_integral+midi;
187 if(iie!=NULL) iie[i]=box_integral2+midii;
190 box_integral2+=0.5*(box_integral+box_integral+fulli)*fdur;
193 printf(
" box_integral=%g\n", box_integral);
194 printf(
" box_integral2=%g\n", box_integral2);
197 prev_x2=x2[i]; prev_fdur=fdur;
200 if(verbose>3) printf(
"liIntegratePET() ready\n");
237 if(verbose>0) {printf(
"liIntegrateFE(x1, x2, y, %d, i, ii, %d)\n", nr, verbose); fflush(stdout);}
244 double prev_fdur=0.0;
245 double prev_iy=0.0, prev_iiy=0.0;
246 double iy=0.0, iiy=0.0;
247 for(
int i=0; i<nr; i++) {
249 double fdur=x2[i]-x1[i];
251 if(fabs(fdur)<1.0E-10) {
252 if(ie!=NULL) ie[i]=prev_iy;
253 if(iie!=NULL) iie[i]=prev_iiy;
259 double gap=x1[i]-x2[i-1];
264 double gap_y=fdur*y[i]+prev_fdur*(y[i-1]);
265 double xs=fdur+prev_fdur;
if(xs>0.0) gap_y/=xs;
266 double gap_integral=gap*gap_y;
267 double gap_integral2=gap*0.5*(iy+iy+gap_integral);
274 double box_integral=fdur*y[i];
275 double box_integral2=fdur*0.5*(iy+iy+box_integral);
279 if(ie!=NULL) ie[i]=iy;
280 if(iie!=NULL) iie[i]=iiy;
282 prev_fdur=fdur; prev_iy=iy; prev_iiy=iiy;
330 printf(
"liIntegrateHalfFrame(x1, x2, y, %zu, fhi, %d)\n", nr, verbose);
334 if(x1==NULL || x2==NULL || y==NULL || fhi==NULL)
return 1;
338 if(verbose>2) printf(
"just one frame.\n");
339 fhi[0]=y[0]*(x2[0]-x1[0])/2.0;
347 double hfdur[nr], x[nr];
348 for(
size_t i=0; i<nr; i++) {
349 x[i]=0.5*(x1[i]+x2[i]);
350 hfdur[i]=0.5*(x2[i]-x1[i]);
352 if(verbose>0) fprintf(stderr,
"negative frame length.\n");
355 if(i>0 && x[i]<x[i-1]) {
356 if(verbose>0) fprintf(stderr,
"frame times not ascending.\n");
363 if(verbose>2) printf(
"just two frames.\n");
366 if(dx<1.0E-100) {fhi[0]=y[0]*hfdur[0]; fhi[1]=y[1]*hfdur[1];
return 0;}
368 fhi[0]=hfdur[0]*(y[0]-k*0.5*hfdur[0]);
369 fhi[1]=hfdur[1]*(y[1]-k*0.5*hfdur[1]);
375 double A[2][nr], B[nr], xdif;
376 A[0][0]=1.0; A[1][0]=0.0; B[0]=y[0];
377 for(
size_t i=1; i<nr-1; i++) {
379 if(!(hfdur[i]>1.0E-100) || !(xdif>1.0E-100)) {
380 A[0][i]=0.0; A[1][i]=0.0; B[i]=y[i];
382 A[0][i]=4.0*(x[i]-x[i-1])/hfdur[i] - (x[i+1]-x[i-1])/xdif;
383 A[1][i]=(x[i]-x[i-1])/xdif;
384 B[i]=4.0*y[i]*(x[i]-x[i-1])/hfdur[i];
387 A[0][nr-1]=1.0; A[1][nr-1]=0.0; B[nr-1]=y[nr-1];
389 printf(
"A[1]\tA[2]\t\tB\n");
390 for(
size_t i=0; i<nr; i++) printf(
"%g\t%g\t\t%g\n", A[0][i], A[1][i], B[i]);
394 for(
size_t i=1; i<nr-1; i++) {
395 if(fabs(A[0][i])<1.0E-100)
continue;
396 A[0][i]-=A[1][i-1]; B[i]-=B[i-1];
397 A[1][i]/=A[0][i]; B[i]/=A[0][i]; A[0][i]=1.0;
400 printf(
"A[1]\tA[2]\t\tB\n");
401 for(
size_t i=0; i<nr; i++) printf(
"%g\t%g\t\t%g\n", A[0][i], A[1][i], B[i]);
403 fhi[0]=y[0]; fhi[nr-1]=y[nr-1];
404 for(
size_t i=nr-2; i>0; i--) {
405 fhi[i]=B[i]-fhi[i+1]*A[1][i];
406 if(verbose>5) printf(
"X[%zu]=%g\n", i+1, fhi[i]);
409 for(
size_t i=1; i<nr-1; i++)
if(isnan(fhi[i])) fhi[i]=y[i];
411 printf(
"estimated frame mid values:\n");
412 for(
size_t i=0; i<nr; i++) printf(
" %g\n", fhi[i]);
416 double newi, lasty=fhi[0];
418 if(!(dx>1.0E-100)) fhi[0]*=hfdur[0];
419 else fhi[0]=hfdur[0]*(fhi[0]-0.5*hfdur[0]*(fhi[1]-fhi[0])/dx);
420 for(
size_t i=1; i<nr; i++) {
422 if(!(dx>1.0E-100)) newi=fhi[i]*hfdur[0];
423 else newi=hfdur[i]*(fhi[i]-0.5*hfdur[i]*(fhi[i]-lasty)/dx);
424 lasty=fhi[i]; fhi[i]=newi;
427 if(verbose>1) printf(
"liIntegrateHalfFrame() ready\n");
460 if(verbose>0) printf(
"liDerivate(x, y, %d, *d, *dd, %d)\n", nr, verbose);
463 if(x==NULL || y==NULL || d==NULL)
return(1);
468 d[0]=0.0;
if(dd!=NULL) dd[0]=0.0;
469 if(fabs(y[0])>1.0E-20) {
470 dx=x[1]-x[0];
if(!(dx>0.0))
return(2);
471 d[0]=y[0]/dx;
if(!isfinite(d[0]))
return(3);
472 if(dd!=NULL) {dd[0]=d[0]/dx;
if(!isfinite(dd[0]))
return(4);}
476 for(
int i=1; i<nr; i++) {
477 dx=x[i]-x[i-1];
if(!(dx>0.0))
return(2);
478 d[i]=(y[i]-y[i-1])/dx;
if(!isfinite(d[i]))
return(3);
479 if(dd!=NULL) {dd[i]=(d[i]-d[i-1])/dx;
if(!isfinite(dd[i]))
return(4);}
482 if(verbose>3) printf(
"liDerivate() ready\n");
507 if(verbose>0) printf(
"liDerivate3(x, y, %d, *d, *dd, %d)\n", nr, verbose);
510 if(x==NULL || y==NULL || d==NULL)
return(1);
514 if(
linRegr3p(x[i]+x[i]-x[i+1], 0.0, x[i], y[i], x[i+1], y[i+1], &d[i], NULL))
return(2);
516 for(++i; i<nr-1; i++)
517 if(
linRegr3p(x[i-1], y[i-1], x[i], y[i], x[i+1], y[i+1], &d[i], NULL))
return(3);
519 d[i]=(y[i]-y[i-1])/(x[i]-x[i-1]);
520 if(!isfinite(d[i]))
return(4);
527 if(verbose>3) printf(
"liDerivate3() ready\n");
int linRegr3p(double x1, double y1, double x2, double y2, double x3, double y3, double *slope, double *ic)
Linear regression for three (x,y) points.
int liIntegrateHalfFrame(double *x1, double *x2, double *y, const size_t nr, double *fhi, const int verbose)
Calculate the integrals (AUC) of the first halves of PET frames based on dot-to-dot linear interpolat...
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.
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.
int liIntegrate(double *x, double *y, const int nr, double *yi, const int se, const int verbose)
Linear integration of TAC with trapezoidal method.
int liIntegratePET(double *x1, double *x2, double *y, int nr, double *ie, double *iie, const int verbose)
Calculate PET TAC AUC from start to each time frame, as averages during each frame.
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.
Header file for library libtpcextensions.
@ TPCERROR_INVALID_X
Invalid sample time.
@ TPCERROR_NO_DATA
File contains no data.
Header file for libtpcli.