TPCCLIB
Loading...
Searching...
No Matches
litac.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 "tpcli.h"
15#include "tpctac.h"
16/*****************************************************************************/
17#include "tpctacmod.h"
18/*****************************************************************************/
19
20/*****************************************************************************/
30 TAC *inp,
33 TAC *out,
35 TPCSTATUS *status
36) {
37 int verbose=0; if(status!=NULL) verbose=status->verbose;
38 if(verbose>0) printf("%s()\n", __func__);
39 if(inp==NULL || out==NULL) {
40 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
41 return TPCERROR_FAIL;
42 }
43 tacFree(out);
44 int ret=TPCERROR_OK;
45 ret=tacDuplicate(inp, out);
46 if(ret!=TPCERROR_OK) {
47 statusSet(status, __func__, __FILE__, __LINE__, ret);
48 return(ret);
49 }
50 if(inp->isframe==0) {
51 for(int i=0; i<inp->tacNr; i++) {
52 ret=liIntegrate(inp->x, inp->c[i].y, inp->sampleNr, out->c[i].y, 3, 0);
53 if(ret!=TPCERROR_OK) break;
54 }
55 } else {
56 for(int i=0; i<inp->tacNr; i++) {
57 ret=liIntegratePET(inp->x1, inp->x2, inp->c[i].y, inp->sampleNr, out->c[i].y, NULL, 0);
58 if(ret!=TPCERROR_OK) break;
59 }
60 }
61 if(ret!=TPCERROR_OK) tacFree(out);
62 statusSet(status, __func__, __FILE__, __LINE__, ret);
63 return(ret);
64}
65/*****************************************************************************/
66
67/*****************************************************************************/
83 TAC *inp,
87 TAC *xinp,
90 TAC *tac,
93 TAC *itac,
96 TAC *iitac,
98 TPCSTATUS *status
99) {
100 int verbose=0; if(status!=NULL) verbose=status->verbose;
101 if(verbose>0) printf("%s()\n", __func__);
102 if(inp==NULL || xinp==NULL || xinp==tac || xinp==itac || xinp==iitac) {
103 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
104 return TPCERROR_FAIL;
105 }
106 if(tac==NULL && itac==NULL && iitac==NULL) { // there's nothing to do
107 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
108 return TPCERROR_OK;
109 }
110 /* Check the function input */
111 if(inp->sampleNr<1 || inp->tacNr<1 || xinp->sampleNr<1) {
112 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
113 return TPCERROR_NO_DATA;
114 }
115
116 /* Check that input does not have any missing values */
117 if(tacNaNs(inp)>0 || tacXNaNs(xinp)>0) {
118 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_MISSING_DATA);
120 }
121
122
123 /* If input data have similar x values as requested already, then
124 copy x1 and x2 into input if available */
125 if(xinp->isframe && tacXMatch(inp, xinp, verbose-2) && inp->sampleNr<=xinp->sampleNr) {
126 for(int i=0; i<inp->sampleNr; i++) {
127 inp->x[i]=xinp->x[i]; inp->x1[i]=xinp->x1[i]; inp->x2[i]=xinp->x2[i];
128 }
129 inp->isframe=xinp->isframe;
130 }
131
132
133 /* Check that there is no need for excess extrapolation */
134 {
135 double start1, end1, start2, end2, range2;
136 if(tacXRange(inp, &start1, &end1) || tacXRange(xinp, &start2, &end2)) {
137 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_X);
138 return TPCERROR_INVALID_X;
139 }
140 range2=end2-start2;
141 if(verbose>2) printf("time ranges: %g - %g vs %g - %g\n", start1, end1, start2, end2);
142 if(start1>start2+0.2*range2 || end1<end2-0.3*range2) {
143 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE);
145 }
146 }
147
148 /* Delete any previous contents in output structs */
149 if(tac!=NULL) tacFree(tac);
150 if(itac!=NULL) tacFree(itac);
151 if(iitac!=NULL) tacFree(iitac);
152
153 /* Allocate memory for output data */
154 int ret=TPCERROR_OK;
155 if(tac!=NULL) ret=tacAllocate(tac, xinp->sampleNr, inp->tacNr);
156 if(ret==TPCERROR_OK && itac!=NULL)
157 ret=tacAllocate(itac, xinp->sampleNr, inp->tacNr);
158 if(ret==TPCERROR_OK && iitac!=NULL)
159 ret=tacAllocate(iitac, xinp->sampleNr, inp->tacNr);
160 if(ret!=TPCERROR_OK) {
161 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OUT_OF_MEMORY);
163 }
164 if(tac!=NULL) {tac->tacNr=inp->tacNr; tac->sampleNr=xinp->sampleNr;}
165 if(itac!=NULL) {itac->tacNr=inp->tacNr; itac->sampleNr=xinp->sampleNr;}
166 if(iitac!=NULL) {iitac->tacNr=inp->tacNr; iitac->sampleNr=xinp->sampleNr;}
167
168
169 /* Copy header information */
170 if(tac!=NULL) {
171 tacCopyHdr(inp, tac);
172 for(int i=0; i<inp->tacNr; i++) tacCopyTacchdr(inp->c+i, tac->c+i);
173 }
174 if(itac!=NULL) {
175 tacCopyHdr(inp, itac);
176 for(int i=0; i<inp->tacNr; i++) tacCopyTacchdr(inp->c+i, itac->c+i);
177 }
178 if(iitac!=NULL) {
179 tacCopyHdr(inp, iitac);
180 for(int i=0; i<inp->tacNr; i++) tacCopyTacchdr(inp->c+i, iitac->c+i);
181 }
182 /* Copy X (time) information */
183 if(tac!=NULL) {
184 tac->isframe=xinp->isframe; tacXCopy(xinp, tac, 0, tac->sampleNr-1);
185 }
186 if(itac!=NULL) {
187 itac->isframe=xinp->isframe; tacXCopy(xinp, itac, 0, itac->sampleNr-1);
188 }
189 if(iitac!=NULL) {
190 iitac->isframe=xinp->isframe; tacXCopy(xinp, iitac, 0, iitac->sampleNr-1);
191 }
192
193 /* Check if TACs have the same frame times already */
194 if(tacXMatch(inp, tac, verbose-2) && inp->sampleNr>=xinp->sampleNr) {
195 if(verbose>2) printf(" same frame times\n");
196 int ret=0, ri, fi;
197 double *i1, *i2;
198 /* copy the values directly and integrate in place, if requested */
199 for(ri=0; ri<inp->tacNr && ret==0; ri++) {
200 if(tac!=NULL)
201 for(fi=0; fi<tac->sampleNr; fi++)
202 tac->c[ri].y[fi]=inp->c[ri].y[fi];
203 /* If integrals not requested then that's it for this TAC */
204 if(itac==NULL && iitac==NULL) continue;
205 /* otherwise set pointers for integrals and then integrate */
206 if(itac!=NULL) i1=itac->c[ri].y; else i1=NULL;
207 if(iitac!=NULL) i2=iitac->c[ri].y; else i2=NULL;
208 if(inp->isframe)
209 ret=liIntegratePET(inp->x1, inp->x2, inp->c[ri].y,
210 xinp->sampleNr, i1, i2, verbose-2);
211 else
212 ret=liInterpolate(inp->x, inp->c[ri].y, inp->sampleNr,
213 xinp->x, NULL, i1, i2, xinp->sampleNr, 4, 1, verbose-2);
214 }
215 if(ret) {
216 if(tac!=NULL) tacFree(tac);
217 if(itac!=NULL) tacFree(itac);
218 if(iitac!=NULL) tacFree(iitac);
219 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
221 }
222 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
223 return(TPCERROR_OK); // that's it then
224 }
225
226 /* Interpolate and/or integrate inp data to tac sample times,
227 taking into account tac frame lengths if available */
228 if(verbose>2) printf(" different frame times\n");
229 ret=0;
230 double *i0, *i1, *i2;
231 for(int ri=0; ri<inp->tacNr && ret==0; ri++) {
232 /* set pointers for output y arrays */
233 if(tac!=NULL) i0=tac->c[ri].y; else i0=NULL;
234 if(itac!=NULL) i1=itac->c[ri].y; else i1=NULL;
235 if(iitac!=NULL) i2=iitac->c[ri].y; else i2=NULL;
236 if(xinp->isframe)
237 ret=liInterpolateForPET(inp->x, inp->c[ri].y, inp->sampleNr,
238 xinp->x1, xinp->x2, i0, i1, i2, xinp->sampleNr, 4, 1, verbose-2);
239 else
240 ret=liInterpolate(inp->x, inp->c[ri].y, inp->sampleNr,
241 xinp->x, i0, i1, i2, xinp->sampleNr, 4, 1, verbose-2);
242 }
243 if(ret) {
244 if(tac!=NULL) tacFree(tac);
245 if(itac!=NULL) tacFree(itac);
246 if(iitac!=NULL) tacFree(iitac);
247 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
249 }
250
251 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
252 return(TPCERROR_OK);
253}
254/*****************************************************************************/
255
256/*****************************************************************************/
271 TAC *inp,
275 TAC *tac,
278 TAC *itac,
281 TAC *iitac,
283 TPCSTATUS *status
284) {
285 int verbose=0; if(status!=NULL) verbose=status->verbose;
286 if(verbose>0) printf("%s()\n", __func__);
287 if(tac==NULL || inp==NULL) {
288 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
289 return TPCERROR_FAIL;
290 }
291
292 /* Check the function input */
293 if(tac->sampleNr<1 || inp->sampleNr<1 || inp->tacNr<1) {
294 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
295 return TPCERROR_NO_DATA;
296 }
297 if(itac!=NULL && itac->sampleNr!=tac->sampleNr) {
298 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_X);
299 return TPCERROR_INVALID_X;
300 }
301 if(iitac!=NULL && iitac->sampleNr!=tac->sampleNr) {
302 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_X);
303 return TPCERROR_INVALID_X;
304 }
305
306
307 /* Check that input does not have any missing values */
308 /* Check that there are no missing sample times in output TACs */
309 if(tacNaNs(inp)>0 || tacXNaNs(tac)>0) {
310 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_MISSING_DATA);
312 }
313
314 /* Check that there is no need for excess extrapolation */
315 {
316 double start1, end1, start2, end2, range2;
317 if(tacXRange(inp, &start1, &end1) || tacXRange(tac, &start2, &end2)) {
318 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_X);
319 return TPCERROR_INVALID_X;
320 }
321 range2=end2-start2;
322 if(verbose>2)
323 printf("time ranges: %g - %g vs %g - %g\n", start1, end1, start2, end2);
324 if(start1>(start2+0.2*range2) || end1<(end2-0.3*range2)) {
325 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE);
327 }
328 }
329
330 /* Allocate memory for interpolated data */
331 if(tacAllocateMore(tac, inp->tacNr)) {
332 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OUT_OF_MEMORY);
334 }
335 /* Copy header information */
336 for(int i=0; i<inp->tacNr; i++) tacCopyTacchdr(inp->c+i, tac->c+tac->tacNr+i);
337 /* Same for the integrals */
338 if(itac!=NULL) {
339 if(tacAllocateMore(itac, inp->tacNr)) {
340 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OUT_OF_MEMORY);
342 }
343 for(int i=0; i<inp->tacNr; i++)
344 tacCopyTacchdr(inp->c+i, itac->c+itac->tacNr+i);
345 }
346 if(iitac!=NULL) {
347 if(tacAllocateMore(iitac, inp->tacNr)) {
348 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OUT_OF_MEMORY);
350 }
351 for(int i=0; i<inp->tacNr; i++) tacCopyTacchdr(inp->c+i, iitac->c+iitac->tacNr+i);
352 }
353
354 /* Check if TACs have the same frame times already */
355 if(tacXMatch(inp, tac, verbose-2) && inp->sampleNr>=tac->sampleNr) {
356 if(verbose>2) printf("same frame times\n");
357 int ret=0, ri, fi;
358 double *i1, *i2;
359 /* copy the values directly and integrate in place, if requested */
360 for(ri=0; ri<inp->tacNr && ret==0; ri++) {
361 for(fi=0; fi<tac->sampleNr; fi++)
362 tac->c[tac->tacNr+ri].y[fi]=inp->c[ri].y[fi];
363 /* If integrals not requested then that's it for this TAC */
364 if(itac==NULL && iitac==NULL) continue;
365 /* otherwise set pointers for integrals and then integrate */
366 if(itac!=NULL) i1=itac->c[itac->tacNr+ri].y; else i1=NULL;
367 if(iitac!=NULL) i2=iitac->c[iitac->tacNr+ri].y; else i2=NULL;
368 if(tac->isframe)
369 ret=liIntegratePET(tac->x1, tac->x2, tac->c[tac->tacNr+ri].y,
370 tac->sampleNr, i1, i2, verbose-2);
371 else
372 ret=liInterpolate(tac->x, tac->c[tac->tacNr+ri].y, tac->sampleNr,
373 tac->x, NULL, i1, i2, tac->sampleNr, 4, 1, verbose-2);
374 }
375 if(ret) {
376 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
378 }
379 tac->tacNr+=inp->tacNr;
380 if(itac!=NULL) itac->tacNr+=inp->tacNr;
381 if(iitac!=NULL) iitac->tacNr+=inp->tacNr;
382 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
383 return(TPCERROR_OK); // that's it then
384 }
385
386 /* Interpolate and, if requested, integrate inp data to tac sample times,
387 taking into account tac frame lengths if available */
388 int ret=0;
389 double *i1, *i2;
390 for(int ri=0; ri<inp->tacNr && ret==0; ri++) {
391 /* set pointers for integrals */
392 if(itac!=NULL) i1=itac->c[itac->tacNr+ri].y; else i1=NULL;
393 if(iitac!=NULL) i2=iitac->c[iitac->tacNr+ri].y; else i2=NULL;
394 if(tac->isframe)
395 ret=liInterpolateForPET(inp->x, inp->c[ri].y, inp->sampleNr,
396 tac->x1, tac->x2, tac->c[tac->tacNr+ri].y,
397 i1, i2, tac->sampleNr, 4, 1, verbose-2);
398 else
399 ret=liInterpolate(inp->x, inp->c[ri].y, inp->sampleNr,
400 tac->x, tac->c[tac->tacNr+ri].y,
401 i1, i2, tac->sampleNr, 4, 1, verbose-2);
402 }
403 if(ret) {
404 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
406 }
407 tac->tacNr+=inp->tacNr;
408 if(itac!=NULL) itac->tacNr+=inp->tacNr;
409 if(iitac!=NULL) iitac->tacNr+=inp->tacNr;
410
411 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
412 return(TPCERROR_OK);
413}
414/*****************************************************************************/
415
416/*****************************************************************************/
426 TAC *inp,
429 double minfdur,
432 double maxfdur,
435 TAC *tac,
437 TPCSTATUS *status
438) {
439 int verbose=0; if(status!=NULL) verbose=status->verbose;
440 if(verbose>0) {printf("%s(tac1, %g, %g, ...)\n", __func__, minfdur, maxfdur); fflush(stdout);}
441 if(tac==NULL || inp==NULL || inp->sampleNr<1 || inp->tacNr<1) {
442 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
443 return TPCERROR_FAIL;
444 }
445 if(minfdur>0.0 && maxfdur>0.0 && minfdur>maxfdur) {
446 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_X);
447 return TPCERROR_INVALID_X;
448 }
449 if(!tacIsX(inp)) {
450 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_X);
451 return TPCERROR_INVALID_X;
452 }
453
454 /* Get the minimum sample interval (that is higher than 0) */
455 double freq=nan("");
456 int ret=tacGetSampleInterval(inp, 1.0E-08, &freq, NULL);
457 //printf("dataset based freq: %g\n", freq);
458 if(ret!=TPCERROR_OK) {statusSet(status, __func__, __FILE__, __LINE__, ret); return(ret);}
459 if(minfdur>0.0 && freq<minfdur) freq=minfdur;
460 if(maxfdur>0.0 && freq>maxfdur) freq=maxfdur;
461 //printf("refined freq: %g\n", freq);
462
463 /* Get the x range */
464 double xmax=nan("");
465 if(tacXRange(inp, NULL, &xmax)!=0) {
466 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE);
468 }
469 //printf("xmax: %g\n", xmax);
470 if(freq>0.5*xmax) {
471 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE);
473 }
474
475
476 /* Calculate the number of required interpolated samples */
477 int nreq=ceil(xmax/freq); //printf("required_n := %d\n", nreq);
478 /* Check that it is not totally stupid */
479 if(nreq<1 || nreq>2E+06) {
480 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_TOO_BIG);
481 return TPCERROR_TOO_BIG;
482 }
483
484 /* Setup the output TAC */
485 if(tacAllocate(tac, nreq, inp->tacNr)!=TPCERROR_OK) {
486 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OUT_OF_MEMORY);
488 }
489 tac->tacNr=inp->tacNr; tac->sampleNr=nreq;
490 /* Copy header information */
491 tacCopyHdr(inp, tac);
492 for(int i=0; i<inp->tacNr; i++) tacCopyTacchdr(inp->c+i, tac->c+i);
493
494 /* Set X (sample time) information */
495 tac->isframe=1;
496 for(int i=0; i<nreq; i++) tac->x1[i]=(double)i*freq;
497 for(int i=0; i<nreq; i++) tac->x2[i]=(double)(i+1)*freq;
498 for(int i=0; i<nreq; i++) tac->x[i]=0.5*(tac->x1[i]+tac->x2[i]);
499
500 /* Calculate mean value during each interval */
501 if(verbose>2) {printf(" interpolating...\n"); fflush(stdout);}
502 for(int i=0; i<inp->tacNr; i++) {
503 if(liInterpolateForPET(inp->x, inp->c[i].y, inp->sampleNr, tac->x1, tac->x2,
504 tac->c[i].y, NULL, NULL, tac->sampleNr, 2, 1, 0)!=0) {
505 tacFree(tac);
506 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE);
508 }
509 }
510 if(verbose>2) {printf(" ... done.\n"); fflush(stdout);}
511
512 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
513 return(TPCERROR_OK);
514}
515/*****************************************************************************/
516
517/*****************************************************************************/
523double tacAUC(
528 TAC *tac,
530 int ti,
532 double t1,
534 double t2,
536 TPCSTATUS *status
537) {
538 int verbose=0; if(status!=NULL) verbose=status->verbose;
539 if(verbose>0) printf("%s(tac, %d, %g, %g)\n", __func__, ti, t1, t2);
540 /* Check the function input */
541 if(tac==NULL || tac->sampleNr<1 || tac->tacNr<1) {
542 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
543 return(nan(""));
544 }
545 if(ti<0 || ti>=tac->tacNr) {
546 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
547 return(nan(""));
548 }
549 if(t1>=t2) {
550 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE);
551 return(nan(""));
552 }
553
554 /* Get and check the x range */
555 double xmin=nan(""), xmax=nan("");
556 if(tacXRange(tac, &xmin, &xmax)!=0 || t1>=xmax || t2<=xmin) {
557 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE);
558 return(nan(""));
559 }
560
561 /* Make temporary x and yi array */
562 double tx[2]; tx[0]=t1; tx[1]=t2;
563 double tyi[2];
564
565 /* If TAC contains just frame mid times, then simple dot-to-dot integration */
566 if(tac->isframe==0) {
567 if(liInterpolate(tac->x, tac->c[ti].y, tac->sampleNr, tx, NULL, tyi, NULL, 2, 3, 1, verbose-10))
568 {
569 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
570 return(nan(""));
571 }
572 /* That's it then */
573 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
574 return(tyi[1]-tyi[0]);
575 }
576
577 /* We have frame start and end times */
578 /* Convert the data into stepwise dot-to-dot data */
579 TAC stac; tacInit(&stac);
580 {
581 int ret=tacFramesToSteps(tac, &stac, NULL);
582 if(ret!=TPCERROR_OK) {
583 tacFree(&stac);
584 statusSet(status, __func__, __FILE__, __LINE__, ret);
585 return(nan(""));
586 }
587 }
588 /* Then simple dot-to-dot integration */
589 if(liInterpolate(stac.x, stac.c[ti].y, stac.sampleNr, tx, NULL, tyi, NULL, 2, 3, 1, verbose-10))
590 {
591 tacFree(&stac);
592 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
593 return(nan(""));
594 }
595 tacFree(&stac);
596
597 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
598 return(tyi[1]-tyi[0]);
599}
600/*****************************************************************************/
601
602/*****************************************************************************/
609 TAC *ttac,
611 const int i,
614 TAC *btac,
616 double Vb,
618 const int simVb,
622 const int petVolume,
624 TPCSTATUS *status
625) {
626 int verbose=0; if(status!=NULL) verbose=status->verbose;
627 if(verbose>0) printf("%s(ttac, %d, btac, %g, %d, %d)\n", __func__, i, Vb, simVb, petVolume);
628 if(ttac==NULL || btac==NULL) {
629 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
630 return TPCERROR_FAIL;
631 }
632 if(ttac->tacNr<1 || btac->tacNr<1 || ttac->sampleNr<1) {
633 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
634 return TPCERROR_NO_DATA;
635 }
636 if(ttac->sampleNr>btac->sampleNr) {
637 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INCOMPATIBLE_DATA);
639 }
640 if(!(Vb>=0.0) || !(Vb<=1.0)) {
641 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
643 }
644 if(Vb==1.0 && petVolume==0 && simVb==0) { // combination would lead to divide by zero
645 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
647 }
648 if(i>=ttac->tacNr) {
649 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
651 }
652
653
654 if(simVb==0) {
655 if(verbose>1) printf("subtracting blood\n");
656 for(int ri=0; ri<ttac->tacNr; ri++) if(i<0 || i==ri) {
657 for(int fi=0; fi<ttac->sampleNr; fi++) {
658 ttac->c[ri].y[fi]-=Vb*btac->c[0].y[fi];
659 if(petVolume==0) ttac->c[ri].y[fi]/=(1.0-Vb);
660 }
661 }
662 } else {
663 if(verbose>1) printf("adding blood\n");
664 for(int ri=0; ri<ttac->tacNr; ri++) if(i<0 || i==ri) {
665 for(int fi=0; fi<ttac->sampleNr; fi++) {
666 if(petVolume==0) ttac->c[ri].y[fi]*=(1.0-Vb);
667 ttac->c[ri].y[fi]+=Vb*btac->c[0].y[fi];
668 }
669 }
670 }
671
672 return(TPCERROR_OK);
673}
674/*****************************************************************************/
675
676/*****************************************************************************/
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 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.
Definition integrate.c:120
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 tacInterpolateToEqualLengthFrames(TAC *inp, double minfdur, double maxfdur, TAC *tac, TPCSTATUS *status)
Definition litac.c:423
int tacVb(TAC *ttac, const int i, TAC *btac, double Vb, const int simVb, const int petVolume, TPCSTATUS *status)
Correct TTACs for vascular blood, or simulate its effect.
Definition litac.c:607
int tacInterpolateInto(TAC *inp, TAC *tac, TAC *itac, TAC *iitac, TPCSTATUS *status)
Add TACs from one TAC structure into another TAC structure, interpolating the input TACs and allocati...
Definition litac.c:266
int tacInterpolate(TAC *inp, TAC *xinp, TAC *tac, TAC *itac, TAC *iitac, TPCSTATUS *status)
Interpolate and/or integrate TACs from one TAC structure into a new TAC structure,...
Definition litac.c:77
int tacIntegrate(TAC *inp, TAC *out, TPCSTATUS *status)
Integrate TACs from one TAC structure into a new TAC structure.
Definition litac.c:27
double tacAUC(TAC *tac, int ti, double t1, double t2, TPCSTATUS *status)
Calculates TAC AUC from t1 to t2.
Definition litac.c:523
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
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
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 tacAllocateMore(TAC *tac, int tacNr)
Definition tac.c:178
int tacCopyTacchdr(TACC *d1, TACC *d2)
Definition tac.c:282
int tacCopyHdr(TAC *tac1, TAC *tac2)
Copy TAC header data from tac1 to tac2.
Definition tac.c:310
int tacNaNs(TAC *tac)
Definition tacnan.c:71
int tacXNaNs(TAC *tac)
Definition tacnan.c:23
int tacXMatch(TAC *d1, TAC *d2, const int verbose)
Check whether sample (frame) times are the same (or very close to) in two TAC structures.
Definition tacx.c:249
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 tacGetSampleInterval(TAC *d, double ilimit, double *minfdur, double *maxfdur)
Get the shortest and longest sampling intervals or frame lengths in TAC structure.
Definition tacx.c:832
int tacXCopy(TAC *tac1, TAC *tac2, int i1, int i2)
Definition tacx.c:24
int tacIsX(TAC *d)
Verify if TAC structure contains reasonable x values (times).
Definition tacx.c:226
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_FAIL
General error.
@ TPCERROR_TOO_BIG
File is too big.
@ 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.
@ TPCERROR_INCOMPATIBLE_DATA
Incompatible data.
Header file for libtpcli.
Header file for library libtpctac.
Header file for libtpctacmod.