TPCCLIB
Loading...
Searching...
No Matches
extrapolate.c
Go to the documentation of this file.
1
5/*****************************************************************************/
6
7/*****************************************************************************/
8#include "libtpcmodext.h"
9/*****************************************************************************/
10
11/*****************************************************************************/
24 DFT *dft,
30 double *fittime,
36 int *min_nr,
39 int max_nr,
44 double mintime,
46 double extr_to,
49 DFT *ext,
52 FILE *loginfo,
55 char *status
56) {
57 int fi, ret, n, to, from, to_min, from_min, orig_max_nr;
58 int fitNr, snr;
59 double kel, c0=0.0, *cx, *cy;
60 double slope, slope_sd, ic, ic_sd, r, f, adj_r2, adj_r2_max;
61 double extr_sampl;
62
63
64 /* Check the input */
65 if(status!=NULL) sprintf(status, "program error");
66 if(dft==NULL || ext==NULL) return -1;
67 if(*min_nr<2) *min_nr=3; // Setting erroneous value to a recommended value
68 if(max_nr>-1 && max_nr<*min_nr) return -2;
69 orig_max_nr=max_nr;
70
71 /* Set the last sample to be fitted */
72 fitNr=dft->frameNr;
73 if(*fittime>0.0) {
74 while(dft->x[fitNr-1]>*fittime && fitNr>0) fitNr--;
75 if(loginfo!=NULL) fprintf(loginfo, "fitNr := %d\nTime range := %g - %g\n",
76 fitNr, dft->x[0], dft->x[fitNr-1]);
77 }
78 *fittime=dft->x[fitNr-1];
79 /* Check that there are at least 3 samples */
80 if(fitNr<3) { /* min_nr is checked later */
81 if(status!=NULL) sprintf(status, "too few samples for extrapolation");
82 return(2);
83 }
84
85 /* If mintime was set, then get min_nr based on that */
86 if(mintime>0.0) {
87 fi=0; while(dft->x[fi]<(*fittime-mintime) && fi<fitNr) fi++;
88 if(--fi<=0) {
89 if(status!=NULL) sprintf(status, "required minimum fit range too large");
90 return(2);
91 }
92 *min_nr=((fitNr-fi)>*min_nr?fitNr-fi:*min_nr);
93 }
94 if(loginfo!=NULL) fprintf(loginfo, "final_min_nr := %d\n", *min_nr);
95
96
97 /*
98 * Initiate data for extrapolated data
99 */
100 /* Determine the sampling time for extrapolated range */
101 extr_sampl=0.5*(dft->x[dft->frameNr-1]-dft->x[dft->frameNr-3]);
102 if(loginfo!=NULL) fprintf(loginfo, "extr_sampl=%g\n", extr_sampl);
103 if(extr_sampl<1.0E-8) {
104 if(status!=NULL) sprintf(status, "check sample times");
105 return(2);
106 }
107 /* Determine the nr of extrapolated samples */
108 f=extr_to-dft->x[dft->frameNr-1];
109 if(f<=0.0) {
110 if(status!=NULL) sprintf(status, "no extrapolation is needed");
111 return(2);
112 }
113 n=ceil(f/extr_sampl);
114 if(loginfo!=NULL) fprintf(loginfo, " extr_sampl=%g n=%d\n", extr_sampl, n);
115 /* Allocate memory */
116 dftEmpty(ext);
117 ret=dftSetmem(ext, dft->frameNr+n, dft->voiNr);
118 if(ret) {
119 if(status!=NULL) sprintf(status, "error in memory allocation.\n");
120 return(4);
121 }
122 ext->frameNr=dft->frameNr+n; ext->voiNr=dft->voiNr;
123 /* Set sample times */
124 for(fi=0; fi<dft->frameNr; fi++) {
125 ext->x[fi]=dft->x[fi]; ext->x1[fi]=dft->x1[fi]; ext->x2[fi]=dft->x2[fi];}
126 if(dft->timetype==DFT_TIME_MIDDLE) {
127 for(; fi<ext->frameNr; fi++) {
128 ext->x[fi]=ext->x[fi-1]+extr_sampl;
129 ext->x1[fi]=ext->x2[fi-1]; ext->x2[fi]=ext->x[fi]+0.5*extr_sampl;
130 }
131 } else {
132 for(; fi<ext->frameNr; fi++) {
133 ext->x1[fi]=ext->x2[fi-1]; ext->x2[fi]=ext->x1[fi]+extr_sampl;
134 ext->x[fi]=0.5*(ext->x1[fi]+ext->x2[fi]);
135 }
136 }
137 /* Copy "header" information */
138 dftCopymainhdr(dft, ext);
139 for(int ri=0; ri<dft->voiNr; ri++) dftCopyvoihdr(dft, ri, ext, ri);
140 /* Copy existing values */
141 for(int ri=0; ri<dft->voiNr; ri++)
142 for(int fi=0; fi<dft->frameNr; fi++)
143 ext->voi[ri].y[fi]=dft->voi[ri].y[fi];
144
145
146 /*
147 * Make ln transformation for TACs
148 */
149 if(loginfo!=NULL) fprintf(loginfo, "ln transformation\n");
150 for(int ri=0; ri<dft->voiNr; ri++)
151 for(int fi=0; fi<dft->frameNr; fi++) {
152 if(!isnan(dft->voi[ri].y[fi]) && dft->voi[ri].y[fi]>0.0)
153 dft->voi[ri].y2[fi]=log(dft->voi[ri].y[fi]);
154 else
155 dft->voi[ri].y2[fi]=nan("");
156 }
157
158
159 /*
160 * Compute best linear fit to the end of ln transformed TACs
161 */
162 if(loginfo!=NULL) fprintf(loginfo, "linear fitting\n");
163 cx=(double*)malloc(2*fitNr*sizeof(double)); if(cx==NULL) {
164 if(status!=NULL) sprintf(status, "out of memory");
165 return(6);
166 }
167 cy=cx+fitNr;
168 for(int ri=0; ri<dft->voiNr; ri++) {
169 kel=0.0; max_nr=orig_max_nr;
170 /* Print TAC name, if more than one was found */
171 if(dft->voiNr>1 && loginfo!=NULL)
172 fprintf(loginfo, "%s :\n", dft->voi[ri].name);
173
174 /* Copy appropriate TAC data */
175 for(fi=n=0; fi<fitNr; fi++)
176 if(dft->x[fi]>0.0 && !isnan(dft->voi[ri].y2[fi])) {
177 cx[n]=dft->x[fi]; cy[n++]=dft->voi[ri].y2[fi];}
178 if(n<*min_nr) {
179 if(status!=NULL) sprintf(status, "check the datafile (%d<%d)", n, *min_nr);
180 free(cx); return(7);
181 }
182 if(max_nr<=0) max_nr=n;
183 /* Search the plot range that gives the max adjusted R^2 */
184 from_min=to_min=-1; adj_r2_max=-9.99E+99;
185 for(from=n-max_nr, to=n-1; from<1+n-*min_nr; from++) {
186 snr=(to-from)+1;
187 /* Calculation of linear regression using pearson() */
188 ret=pearson(
189 cx+from, cy+from, snr, &slope, &slope_sd, &ic, &ic_sd, &r, &f
190 );
191 if(ret==0) {
192 adj_r2= 1.0 - ((1.0-r*r)*(double)(snr-1)) / (double)(snr-2);
193 } else {
194 adj_r2=-9.99E+99;
195 }
196 //if(cv<cv_min) {
197 if(adj_r2>adj_r2_max+0.0001) {
198 adj_r2_max=adj_r2; from_min=from; to_min=to; kel=-slope; c0=exp(ic);
199 }
200 if(loginfo!=NULL)
201 fprintf(loginfo, " adj_r2=%g from=%d (%g)\n", adj_r2, from, *(cx+from) );
202 }
203 if(from_min<0) {
204 if(status!=NULL) sprintf(status, "check the datafile");
205 free(cx); return(7);
206 }
207 /* Check the sign of slope */
208 if(kel>=0.0) {
209 /* negative slope i.e. positive kel is ok */
210 if(loginfo!=NULL)
211 fprintf(loginfo, " k(el)=%g adj_r2=%g C(0)=%g; %d data points.\n",
212 kel, adj_r2_max, c0, (to_min-from_min)+1 );
213 /* Calculate the extrapolated values */
214 for(fi=fitNr; fi<ext->frameNr; fi++) {
215 ext->voi[ri].y[fi]=c0*exp(-kel*ext->x[fi]);
216 }
217 } else {
218 /* If slope is positive, then extrapolate with line f(x)=b+0*t */
219 for(fi=fitNr-1, f=0.0, n=0; fi>=0 && n<3; fi--)
220 if(!isnan(dft->voi[ri].y[fi])) {f+=dft->voi[ri].y[fi]; n++;}
221 if(n>0) f/=(double)n;
222 if(status!=NULL)
223 sprintf(status, "curve end is not descending; extrapolation with horizontal line determined as avg of %d samples", n);
224 /* Calculate the extrapolated values */
225 for(fi=fitNr; fi<ext->frameNr; fi++) {
226 ext->voi[ri].y[fi]=f;
227 }
228 }
229 } /* next curve */
230 free(cx);
231
232 if(status!=NULL) sprintf(status, "ok");
233 return 0;
234}
235/*****************************************************************************/
236
237/*****************************************************************************/
245 DFT *dft,
248 DFT *dft2,
250 double endtime,
252 int verbose
253) {
254 int i, newnr, maxNr=10000;
255 double t, dt;
256
257
258 if(verbose>0) printf("dftAutointerpolate(dft1, dft2, %g)\n", endtime);
259 /* Check the arguments */
260 if(dft->frameNr<1 || dft->voiNr<1) return 1;
261 if(endtime<1.0 || endtime>1.0E12) return 2;
263 return 10;
264
265 /* Calculate the number of interpolated data points */
266 t=0.0; dt=0.02; newnr=1;
267 while(t+dt<endtime && newnr<maxNr-1) {
268 t+=dt; dt*=1.05; newnr++;
269 }
270 dt=endtime-t; t=endtime; newnr++;
271 if(verbose>1) printf("newnr := %d\n", newnr);
272
273 /* Allocate memory for interpolated data */
274 dftEmpty(dft2); if(dftSetmem(dft2, newnr, dft->voiNr)) return 3;
275 /* Copy header info */
276 (void)dftCopymainhdr(dft, dft2); dft2->voiNr=dft->voiNr;
277 for(i=0; i<dft->voiNr; i++) if(dftCopyvoihdr(dft, i, dft2, i)) return 4;
278
279 /* Set times */
280 if(dft->timetype==DFT_TIME_STARTEND) {
281
283 t=0.0; dt=0.02; i=0;
284 if(verbose>1) printf("%05d: %12.5f %10.5f\n", i, t, dt);
285 dft2->x1[i]=t; dft2->x2[i]=t+dt; dft2->x[i]=0.5*(dft2->x1[i]+dft2->x2[i]);
286 i++;
287 while((t+2.5*dt)<endtime && newnr<maxNr-2) {
288 t+=dt; dt*=1.05;
289 if(verbose>1) printf("%05d: %12.5f %10.5f\n", i, t, dt);
290 dft2->x1[i]=t; dft2->x2[i]=t+dt; dft2->x[i]=0.5*(dft2->x1[i]+dft2->x2[i]);
291 i++;
292 }
293 t+=dt; dt=endtime-t;
294 if(verbose>1) printf("%05d: %12.5f %10.5f\n", i, t, dt);
295 dft2->x1[i]=t; dft2->x2[i]=t+dt; dft2->x[i]=0.5*(dft2->x1[i]+dft2->x2[i]);
296 i++; dft2->frameNr=i;
297
298 /* Interpolate */
299 for(i=0; i<dft->voiNr; i++)
300 if(interpolate4pet(dft->x, dft->voi[i].y, dft->frameNr,
301 dft2->x1, dft2->x2, dft2->voi[i].y, NULL, NULL, dft2->frameNr)) {
302 dftEmpty(dft2); return 5;
303 }
304
305 } else if(dft->timetype==DFT_TIME_MIDDLE) {
306
308 t=0.0; dt=0.02; i=0;
309 if(verbose>1) printf("%05d: %12.5f %10.5f\n", i, t, dt);
310 dft2->x1[i]=t; dft2->x2[i]=t+dt; dft2->x[i]=0.5*(dft2->x1[i]+dft2->x2[i]);
311 i++;
312 while((t+2.5*dt)<endtime && newnr<maxNr-2) {
313 t+=dt; dt*=1.05;
314 if(verbose>1) printf("%05d: %12.5f %10.5f\n", i, t, dt);
315 dft2->x1[i]=t; dft2->x2[i]=t+dt; dft2->x[i]=0.5*(dft2->x1[i]+dft2->x2[i]);
316 i++;
317 }
318 t+=dt; dt=endtime-t;
319 if(verbose>1) printf("%05d: %12.5f %10.5f\n", i, t, dt);
320 dft2->x1[i]=t; dft2->x2[i]=t+2.0*dt;
321 dft2->x[i]=0.5*(dft2->x1[i]+dft2->x2[i]);
322 i++; dft2->frameNr=i;
323
324 /* Interpolate */
325 for(i=0; i<dft->voiNr; i++)
326 if(interpolate4pet(dft->x, dft->voi[i].y, dft->frameNr,
327 dft2->x1, dft2->x2, dft2->voi[i].y, NULL, NULL, dft2->frameNr)) {
328 dftEmpty(dft2); return 5;
329 }
330
331 }
332
333 return 0;
334}
335/*****************************************************************************/
336
337/*****************************************************************************/
345 DFT *dft,
348 DFT *dft2
349) {
350 int ri, fi, fj, ret;
351 double f;
352
353
354 /* Check the arguments */
355 if(dft==NULL || dft2==NULL) return 1;
356 if(dft->frameNr<1 || dft->voiNr<1) return 2;
357 if(dft->timetype!=DFT_TIME_STARTEND && dft->x[0]<0.0) return 3;
358
359 /* Allocate memory for interpolated data */
360 dftEmpty(dft2); if(dftSetmem(dft2, 2*dft->frameNr, dft->voiNr)) return 11;
361 /* Copy header info */
362 (void)dftCopymainhdr(dft, dft2);
363 dft2->voiNr=dft->voiNr; dft2->frameNr=2*dft->frameNr;
364 for(ri=0; ri<dft->voiNr; ri++) if(dftCopyvoihdr(dft, ri, dft2, ri)) return 12;
365
366 /* Set new time frames and interpolate */
367 if(dft->timetype==DFT_TIME_STARTEND) {
368 for(fi=fj=0; fi<dft->frameNr; fi++, fj+=2) {
369 f=0.5*(dft->x1[fi]+dft->x2[fi]);
370 dft2->x1[fj]=dft->x1[fi]; dft2->x2[fj]=f;
371 dft2->x[fj]=0.5*(dft2->x1[fj]+dft2->x2[fj]);
372 dft2->x1[fj+1]=f; dft2->x2[fj+1]=dft->x2[fi];
373 dft2->x[fj+1]=0.5*(dft2->x1[fj+1]+dft2->x2[fj+1]);
374 for(ri=0; ri<dft->voiNr; ri++)
375 dft2->voi[ri].y[fj]=dft2->voi[ri].y[fj+1]=dft->voi[ri].y[fi];
376 }
377 ret=0;
378 } else {
379 for(fi=fj=0; fi<dft->frameNr; fi++) {
380 if(dft->x[fi]<=0.0) {
381 /* just copy, no doubles */
382 dft2->x[fj++]=dft->x[fi]; continue;
383 }
384 if(fi==0) f=0.5*dft->x[fi];
385 else f=0.5*(dft->x[fi-1]+dft->x[fi]);
386 dft2->x[fj++]=f; dft2->x[fj++]=dft->x[fi];
387 }
388 dft2->frameNr=fj;
389 for(ri=0, ret=0; ri<dft->voiNr; ri++) {
390 ret=interpolate(dft->x, dft->voi[ri].y, dft->frameNr,
391 dft2->x, dft2->voi[ri].y, NULL, NULL, dft2->frameNr);
392 if(ret) break;
393 }
394 }
395 if(ret) return 20+ret;
396 return 0;
397}
398/*****************************************************************************/
399
400/*****************************************************************************/
408 DFT *dft,
410 int voi_index,
413 int add_nr,
417 DFT *dft2,
419 int verbose
420) {
421 int ret, fi, fj, i, new_frameNr=0, new_voiNr=0;
422 double fdur;
423
424 if(verbose>0) {
425 printf("dftDivideFrames(*dft, %d, %d, *dft2)\n", voi_index, add_nr);
426 fflush(stdout);
427 }
428 /* Check the arguments */
429 if(dft==NULL || dft2==NULL) return 1;
430 if(dft->frameNr<1 || dft->voiNr<1) return 2;
431 if(add_nr<1 || add_nr>100) return 3;
432 if(voi_index>=dft->voiNr) return 4;
433
434 /* Calculate how many frames and TACs will be needed */
435 if(dft->timetype==DFT_TIME_STARTEND) new_frameNr=(add_nr+1)*dft->frameNr;
436 else new_frameNr=(add_nr+1)*dft->frameNr-1;
437 if(voi_index<0) new_voiNr=dft->voiNr; else new_voiNr=1;
438 if(verbose>1) {
439 printf("new_frameNr := %d\n", new_frameNr);
440 printf("new_voiNr := %d\n", new_voiNr);
441 fflush(stdout);
442 }
443
444 /* Allocate memory for interpolated data if necessary */
445 if(new_frameNr>dft2->frameNr || new_voiNr>dft2->_voidataNr) {
446 if(verbose>1) {
447 printf("deleting old data and allocating new\n"); fflush(stdout);}
448 dftEmpty(dft2);
449 if(dftSetmem(dft2, new_frameNr, dft->voiNr)) return 11;
450 }
451
452 /* Copy header info */
453 ret=dftCopymainhdr(dft, dft2); if(ret!=0) return 12;
454 dft2->voiNr=new_voiNr; dft2->frameNr=new_frameNr;
455 if(voi_index>=0) ret=dftCopyvoihdr(dft, voi_index, dft2, 0);
456 else {
457 for(int ri=0; ri<dft->voiNr; ri++) {
458 ret=dftCopyvoihdr(dft, ri, dft2, ri); if(ret!=0) break;}
459 }
460 if(ret!=0) return 13;
461
462 /* Set new frame times and interpolate */
463 ret=0;
464 if(dft->timetype==DFT_TIME_STARTEND) {
465 for(fi=0, fj=0; fi<dft->frameNr; fi++) {
466 fdur=(dft->x2[fi]-dft->x1[fi])/(double)(add_nr+1);
467 for(i=0; i<add_nr+1; i++) {
468 fj=fi*(add_nr+1)+i;
469 dft2->x1[fj]=dft->x1[fi]+fdur*(double)i;
470 dft2->x2[fj]=dft2->x1[fj]+fdur;
471 dft2->x[fj]=0.5*(dft2->x1[fj]+dft2->x2[fj]);
472 if(voi_index>=0)
473 dft2->voi[0].y[fj]=dft->voi[voi_index].y[fi];
474 else
475 for(int ri=0; ri<dft->voiNr; ri++) dft2->voi[ri].y[fj]=dft->voi[ri].y[fi];
476 }
477 }
478 dft2->frameNr=fj+1;
479 } else {
480 dft2->x[0]=dft->x[0];
481 for(fi=1, fj=0; fi<dft->frameNr; fi++) {
482 fdur=(dft->x[fi]-dft->x[fi-1])/(double)(add_nr+1);
483 for(i=0; i<add_nr+1; i++) {
484 fj=(fi-1)*(add_nr+1) + i + 1;
485 dft2->x[fj]=dft->x[fi-1]+fdur*(double)(i+1);
486 }
487 }
488 dft2->frameNr=fj+1;
489 if(voi_index>=0) {
490 ret=interpolate(dft->x, dft->voi[voi_index].y, dft->frameNr,
491 dft2->x, dft2->voi[0].y, NULL, NULL, dft2->frameNr);
492 } else {
493 for(int ri=0; ri<dft->voiNr; ri++) {
494 ret=interpolate(dft->x, dft->voi[ri].y, dft->frameNr,
495 dft2->x, dft2->voi[ri].y, NULL, NULL, dft2->frameNr);
496 if(ret) break;
497 }
498 }
499 }
500 if(ret!=0) return 21;
501
502 return 0;
503}
504/*****************************************************************************/
505
506/*****************************************************************************/
516 DFT *dft,
522 double *fittime,
528 int *min_nr,
531 int max_nr,
536 double mintime,
541 int check_impr,
545 FIT *fit,
548 FILE *loginfo,
551 char *status
552) {
553 int fi, ret, n, to, from, to_min, from_min, orig_max_nr;
554 int fitNr, snr;
555 double *cx, *cy;
556 double adj_r2, slope, slope_sd, ic, ic_sd, r, f, ySD_min;
557 double adj_r2_max, adj_r2_prev=-10.0, ic_min, slope_min;
558
559
560 /* Check the input */
561 if(status!=NULL) sprintf(status, "program error");
562 if(dft==NULL || fit==NULL) return -1;
563 if(*min_nr<2) *min_nr=3; // Setting erroneous value to a recommended value
564 if(max_nr>-1 && max_nr<*min_nr) return -2;
565 orig_max_nr=max_nr;
566
567 /* Set the last sample to be fitted */
568 fitNr=dft->frameNr;
569 if(*fittime>0.0) {
570 while(dft->x[fitNr-1]>*fittime && fitNr>0) fitNr--;
571 if(loginfo!=NULL) fprintf(loginfo, "fitNr := %d\nTime range := %g - %g\n",
572 fitNr, dft->x[0], dft->x[fitNr-1]);
573 }
574 *fittime=dft->x[fitNr-1];
575 /* Check that there are at least 3 samples */
576 if(fitNr<3) { /* min_nr is checked later */
577 if(status!=NULL) sprintf(status, "too few samples for linear fit");
578 return(2);
579 }
580
581 /* If mintime was set, then get min_nr based on that */
582 if(mintime>0.0) {
583 fi=0; while(dft->x[fi]<(*fittime-mintime) && fi<fitNr) fi++;
584 if(--fi<=0) {
585 if(status!=NULL) sprintf(status, "required minimum fit range too large");
586 return(2);
587 }
588 *min_nr=((fitNr-fi)>*min_nr?fitNr-fi:*min_nr);
589 }
590 if(loginfo!=NULL) fprintf(loginfo, "final_min_nr := %d\n", *min_nr);
591
592 /* Allocate data for fits */
593 if((ret=fit_allocate_with_dft(fit, dft))!=0) {
594 if(loginfo!=NULL) fprintf(loginfo, "Error %d: cannot allocate memory for fits.\n", ret);
595 if(status!=NULL) sprintf(status, "cannot allocate memory for fits");
596 return 4;
597 }
598 /* and for x,y data to be fitted */
599 cx=(double*)malloc(2*fitNr*sizeof(double)); if(cx==NULL) {
600 if(status!=NULL) sprintf(status, "out of memory");
601 return(6);
602 }
603 cy=cx+fitNr;
604
605 /* Fit each TAC */
606 if(loginfo!=NULL) fprintf(loginfo, "linear fitting\n");
607 for(int ri=0; ri<dft->voiNr; ri++) {
608 max_nr=orig_max_nr;
609 /* Print TAC name, if more than one was found */
610 if(dft->voiNr>1 && loginfo!=NULL)
611 fprintf(loginfo, "%s :\n", dft->voi[ri].name);
612 /* Set header */
613 fit->voi[ri].parNr=2;
614 fit->voi[ri].type=101;
615 /* Copy appropriate TAC data */
616 for(fi=n=0; fi<fitNr; fi++)
617 if(dft->x[fi]>0.0 && !isnan(dft->voi[ri].y[fi])) {
618 cx[n]=dft->x[fi]; cy[n++]=dft->voi[ri].y[fi];}
619 if(n<*min_nr) {
620 if(status!=NULL) sprintf(status, "check the datafile (%d<%d)", n, *min_nr);
621 free(cx); return(7);
622 }
623 if(max_nr<=0) max_nr=n;
624 /* Search the plot range that gives the max adjusted R^2 */
625 from_min=to_min=-1; adj_r2_max=-9.99E+99; ic_min=slope_min=0.0; ySD_min=0.0;
626 for(from=n-*min_nr, to=n-1; from>=n-max_nr; from--) {
627 snr=(to-from)+1;
628 /* Calculation of linear regression using pearson() */
629 ret=pearson(
630 cx+from, cy+from, snr, &slope, &slope_sd, &ic, &ic_sd, &r, &f
631 );
632 if(ret==0) {
633 adj_r2= 1.0 - ((1.0-r*r)*(double)(snr-1)) / (double)(snr-2);
634 if(adj_r2<0.0 && loginfo!=NULL)
635 fprintf(loginfo, " r=%g; snr=%d\n", r, snr);
636 } else {
637 adj_r2=-9.99E+99;
638 }
639 if(adj_r2>adj_r2_max-0.0001) {
640 adj_r2_max=adj_r2; from_min=from; to_min=to;
641 ic_min=ic; slope_min=slope; ySD_min=f;
642 }
643 if(loginfo!=NULL)
644 fprintf(loginfo, " adj_r2=%g from=%d (%g)\n",
645 adj_r2, from, *(cx+from) );
646 /* check for improvement, if required */
647 if(check_impr!=0 && adj_r2_prev>-1.0 && adj_r2>0.0 && adj_r2<adj_r2_prev)
648 break;
649
650 adj_r2_prev=adj_r2;
651 }
652 if(from_min<0) {
653 if(status!=NULL) sprintf(status, "check the datafile");
654 free(cx); return(7);
655 }
656 if(loginfo!=NULL) fprintf(loginfo, " adj_r2_max=%g.\n", adj_r2_max );
657 /* Set fit line parameters */
658 fit->voi[ri].p[0]=ic_min;
659 fit->voi[ri].p[1]=slope_min;
660 fit->voi[ri].p[2]=adj_r2_max;
661 fit->voi[ri].wss=ySD_min;
662 fit->voi[ri].start=cx[from_min]; fit->voi[ri].end=cx[to_min];
663 fit->voi[ri].dataNr=(to_min-from_min)+1;
664 } // next curve
665
666
667 free(cx);
668 if(status!=NULL) sprintf(status, "ok");
669 return 0;
670}
671/******************************************************************************/
672
673/******************************************************************************/
679 DFT *dft1,
682 DFT *dft2
683) {
684 DFT *out;
685
686 if(dft1==NULL || dft1->voiNr<1 || dft1->frameNr<1) return 1;
687 if(dft2!=NULL) out=dft2; else out=dft1;
688
689 int ok_nr=0;
690 for(int ri=0; ri<dft1->voiNr; ri++) for(int fi=0; fi<dft1->frameNr; fi++) {
691 if(!isnan(dft1->voi[ri].y[fi]) && dft1->voi[ri].y[fi]>0.0) {
692 out->voi[ri].y[fi]=log(dft1->voi[ri].y[fi]); ok_nr++;
693 } else {
694 out->voi[ri].y[fi]=nan("");
695 }
696 }
697 if(ok_nr>0) return 0; else return 2;
698}
699/******************************************************************************/
700
701/******************************************************************************/
702
int dftCopyvoihdr(DFT *dft1, int from, DFT *dft2, int to)
Definition dft.c:623
int dftSetmem(DFT *data, int frameNr, int voiNr)
Definition dft.c:57
void dftEmpty(DFT *data)
Definition dft.c:20
int dftCopymainhdr(DFT *dft1, DFT *dft2)
Definition dft.c:561
int dft_end_line(DFT *dft, double *fittime, int *min_nr, int max_nr, double mintime, int check_impr, FIT *fit, FILE *loginfo, char *status)
int extrapolate_monoexp(DFT *dft, double *fittime, int *min_nr, int max_nr, double mintime, double extr_to, DFT *ext, FILE *loginfo, char *status)
Definition extrapolate.c:22
int dftDivideFrames(DFT *dft, int voi_index, int add_nr, DFT *dft2, int verbose)
int dftDoubleFrames(DFT *dft, DFT *dft2)
int dft_ln(DFT *dft1, DFT *dft2)
int dftAutointerpolate(DFT *dft, DFT *dft2, double endtime, int verbose)
int fit_allocate_with_dft(FIT *fit, DFT *dft)
Definition fitres.c:14
int interpolate(double *x, double *y, int nr, double *newx, double *newy, double *newyi, double *newyii, int newnr)
Linear interpolation and integration.
Definition integr.c:28
int interpolate4pet(double *x, double *y, int nr, double *newx1, double *newx2, double *newy, double *newyi, double *newyii, int newnr)
Interpolate and integrate TAC to PET frames.
Definition integr.c:510
#define DFT_TIME_MIDDLE
#define DFT_TIME_STARTEND
int pearson(double *x, double *y, int nr, double *k, double *kSD, double *b, double *bSD, double *r, double *ySD)
Definition pearson.c:14
Header file for libtpcmodext.
int timetype
Voi * voi
double * x1
int voiNr
double * x2
int frameNr
double * x
FitVOI * voi
double wss
double end
double start
double p[MAX_FITPARAMS]
double * y2
double * y
char name[MAX_REGIONNAME_LEN+1]