TPCCLIB
Loading...
Searching...
No Matches
dftint.c File Reference

Functions for interpolating and integrating DFT data. More...

#include "libtpcmodext.h"

Go to the source code of this file.

Functions

int dftInterpolateCheckStart (DFT *input, DFT *output, char *status, int verbose)
 
int dftInterpolateCheckEnd (DFT *input, DFT *output, char *status, int verbose)
 
int dftInterpolate (DFT *input, DFT *tissue, DFT *output, char *status, int verbose)
 
int dftInterpolateInto (DFT *inp, DFT *tis, char *status, int verbose)
 
int dftTimeIntegral (DFT *dft, double t1, double t2, DFT *idft, int calc_mode, char *status, int verbose)
 
int dftDerivative_old (DFT *dft, DFT *deriv, char *status)
 
int dftDerivative (DFT *dft, DFT *deriv, char *status)
 

Detailed Description

Functions for interpolating and integrating DFT data.

Author
Vesa Oikonen

Definition in file dftint.c.

Function Documentation

◆ dftDerivative()

int dftDerivative ( DFT * dft,
DFT * deriv,
char * status )

Calculate simple derivatives from regional PET TACs. This must not be used for any quantitative purpose.

Returns
Returns 0 if successul.
Parameters
dftDFT struct containing the regional tissue TACs
derivAllocated DFT struct for derivatives
statusPointer to allocated string where the status or error message is written; set to NULL if not needed

Definition at line 635 of file dftint.c.

643 {
644 int ri, fi;
645 double fdur;
646
647 /* check input */
648 if(status!=NULL) sprintf(status, "invalid input for dftDerivative()");
649 if(dft==NULL || dft->frameNr<1 || dft->voiNr<1) return 1;
650 if(deriv==NULL || deriv->frameNr<dft->frameNr || deriv->voiNr<dft->voiNr)
651 return 2;
653 if(status!=NULL)
654 sprintf(status, "frame start and end times or mid times are required");
655 return 3;
656 }
657
658 /* calculate frame mid times if necessary */
660 for(fi=0; fi<dft->frameNr; fi++)
661 dft->x[fi]=0.5*(dft->x1[fi]+dft->x2[fi]);
662
663 /* calculate derivative */
664 if(dft->x[0]<=1.0E-20) for(ri=0; ri<dft->voiNr; ri++)
665 deriv->voi[ri].y[0]=0.0;
666 else for(ri=0; ri<dft->voiNr; ri++)
667 deriv->voi[ri].y[0]=dft->voi[ri].y[0]/dft->x[0];
668 for(fi=1; fi<dft->frameNr; fi++) {
669 fdur=dft->x[fi]-dft->x[fi-1];
670 if(fdur<=1.0E-20) for(ri=0; ri<dft->voiNr; ri++)
671 deriv->voi[ri].y[fi]=0.0;
672 else for(ri=0; ri<dft->voiNr; ri++)
673 deriv->voi[ri].y[fi]=(dft->voi[ri].y[fi]-dft->voi[ri].y[fi-1])/fdur;
674 }
675 for(ri=0; ri<dft->voiNr; ri++) for(fi=0; fi<dft->frameNr-1; fi++) {
676 deriv->voi[ri].y[fi]+=deriv->voi[ri].y[fi+1];
677 deriv->voi[ri].y[fi]*=0.5;
678 }
679
680 return 0;
681}
#define DFT_TIME_MIDDLE
#define DFT_TIME_STARTEND
int timetype
Voi * voi
double * x1
int voiNr
double * x2
int frameNr
double * x
double * y

◆ dftDerivative_old()

int dftDerivative_old ( DFT * dft,
DFT * deriv,
char * status )

Calculate simple derivatives from regional PET TACs. Old version. Requires that frame start and end times are known.

Returns
Returns 0 if successul.
Parameters
dftDFT struct containing the regional tissue TACs
derivAllocated DFT struct for derivatives
statusPointer to allocated string where the status or error message is written; set to NULL if not needed

Definition at line 591 of file dftint.c.

599 {
600 int ri, fi;
601 double fdur;
602
603 /* check input */
604 if(status!=NULL) sprintf(status, "invalid input for dftDerivative()");
605 if(dft==NULL || dft->frameNr<1 || dft->voiNr<1) return 1;
606 if(deriv==NULL || deriv->frameNr<dft->frameNr || deriv->voiNr<dft->voiNr)
607 return 2;
608 if(dft->timetype!=3) {
609 if(status!=NULL) sprintf(status, "frame start and end times are required");
610 return 3;
611 }
612
613 /* calculate derivative */
614 for(fi=0; fi<dft->frameNr; fi++) {
615 fdur=dft->x2[fi]-dft->x1[fi];
616 if(fdur<=1.0E-10) {
617 for(ri=0; ri<dft->voiNr; ri++) deriv->voi[ri].y[fi]=0.0;
618 continue;
619 }
620 for(ri=0; ri<dft->voiNr; ri++) {
621 deriv->voi[ri].y[fi]=dft->voi[ri].y[fi];
622 if(fi>0) deriv->voi[ri].y[fi]-=dft->voi[ri].y[fi-1];
623 deriv->voi[ri].y[fi]/=fdur;
624 }
625 }
626 return 0;
627}

◆ dftInterpolate()

int dftInterpolate ( DFT * input,
DFT * tissue,
DFT * output,
char * status,
int verbose )

Interpolate (and integrate) TAC data to sample times that are given with another TAC data. PET frame lengths are taken into account if available in tissue DFT struct.

Input frame lengths are taken into account if the framing is same as with tissue data.

See also
dftInterpolateInto, dftTimeIntegral
Returns
Returns 0 if successful, and <>0 in case of an error.
Parameters
inputData which is interpolated; make sure that time unit is the same as in tissue data; time range is checked to cover the tissue data
tissueData to which (sample times) the interpolation is done
outputPointer to initiated DFT into which interpolated values and integrals will be written
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 162 of file dftint.c.

176 {
177 int fi, ri, ret;
178
179 if(verbose>0) printf("dftInterpolate()");
180
181 // Check the input
182 if(input==NULL || tissue==NULL || output==NULL) {
183 if(status!=NULL) sprintf(status, "program error");
184 return 1;
185 }
186
187 // If input and tissue data have the same frame times already, then
188 // copy frame times and timetype into input
189 if(tissue->timetype==DFT_TIME_STARTEND &&
190 check_times_dft_vs_dft(tissue, input, verbose)==1 &&
191 input->frameNr<=tissue->frameNr)
192 {
193 for(fi=0; fi<input->frameNr; fi++) {
194 input->x[fi]=tissue->x[fi];
195 input->x1[fi]=tissue->x1[fi]; input->x2[fi]=tissue->x2[fi];
196 }
197 input->timetype=tissue->timetype;
198 }
199
200 // Check that there is no need for excess extrapolation
201 ret=dftInterpolateCheckEnd(input, tissue, status, verbose);
202 if(ret<0) return 2;
203 ret=dftInterpolateCheckStart(input, tissue, status, verbose);
204 if(ret<0) return 2;
205
206 // Delete any previous output data
207 dftEmpty(output);
208
209 // Allocate memory for interpolated data
210 if(dftSetmem(output, tissue->frameNr, input->voiNr)) {
211 if(status!=NULL) strcpy(status, "memory allocation error");
212 return 3;
213 }
214 output->voiNr=input->voiNr; output->frameNr=tissue->frameNr;
215
216 // Copy header information
217 dftCopymainhdr(input, output);
218 for(ri=0; ri<input->voiNr; ri++) dftCopyvoihdr(input, ri, output, ri);
219
220 // Copy frame information
221 output->isweight=tissue->isweight;
222 for(fi=0; fi<tissue->frameNr; fi++) {
223 output->x[fi]=tissue->x[fi];
224 output->x1[fi]=tissue->x1[fi]; output->x2[fi]=tissue->x2[fi];
225 output->w[fi]=tissue->w[fi];
226 }
227 output->timetype=tissue->timetype;
228
229 // Check if input and tissue data do have the same frame times already
230 if(check_times_dft_vs_dft(tissue, input, verbose)==1 &&
231 input->frameNr>=tissue->frameNr)
232 {
233 // copy the values directly and integrate in place
234 for(ri=0, ret=0; ri<output->voiNr && ret==0; ri++) {
235 for(fi=0; fi<tissue->frameNr; fi++)
236 output->voi[ri].y[fi]=input->voi[ri].y[fi];
237 if(output->timetype==3)
238 ret=petintegral(output->x1, output->x2, output->voi[ri].y,
239 output->frameNr, output->voi[ri].y2, output->voi[ri].y3);
240 else
241 ret=interpolate(output->x, output->voi[ri].y, output->frameNr,
242 output->x, output->voi[ri].y, output->voi[ri].y2,
243 output->voi[ri].y3, output->frameNr);
244 }
245 if(ret) {
246 if(status!=NULL) sprintf(status, "cannot interpolate (%d)", ret);
247 dftEmpty(output); return 5;
248 }
249 return 0; // that's it then
250 }
251
252 // Interpolate and integrate input data to tissue sample times,
253 // taking into account tissue frame lengths if available
254 for(ri=0, ret=0; ri<output->voiNr && ret==0; ri++) {
255 if(output->timetype==DFT_TIME_STARTEND)
256 ret=interpolate4pet(input->x, input->voi[ri].y, input->frameNr,
257 output->x1, output->x2, output->voi[ri].y, output->voi[ri].y2,
258 output->voi[ri].y3, output->frameNr);
259 else
260 ret=interpolate(input->x, input->voi[ri].y, input->frameNr,
261 output->x, output->voi[ri].y, output->voi[ri].y2,
262 output->voi[ri].y3, output->frameNr);
263 }
264 if(ret) {
265 if(status!=NULL) sprintf(status, "cannot interpolate (%d)", ret);
266 dftEmpty(output); return 6;
267 }
268
269 return 0;
270}
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 dftInterpolateCheckStart(DFT *input, DFT *output, char *status, int verbose)
Definition dftint.c:17
int dftInterpolateCheckEnd(DFT *input, DFT *output, char *status, int verbose)
Definition dftint.c:82
int check_times_dft_vs_dft(DFT *dft1, DFT *dft2, int verbose)
Definition fittime.c:169
int petintegral(double *x1, double *x2, double *y, int nr, double *ie, double *iie)
Integrate PET TAC data to frame mid times.
Definition integr.c:771
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
double * w
int isweight
double * y2
double * y3

Referenced by dftReadinput().

◆ dftInterpolateCheckEnd()

int dftInterpolateCheckEnd ( DFT * input,
DFT * output,
char * status,
int verbose )

Verify that data to-be-interpolated does not need too much extrapolation in the end, and that samples are not too sparse.

Time units in DFTs can be different, if specified.

See also
dftInterpolateCheckStart, dftInterpolateInto, dftInterpolate
Returns
Returns 0 if data is fine, 1 if extrapolation can be done, but there may be too few samples, and -1 if extrapolation in the end is impossible.
Parameters
inputData that will be verified for reliable interpolation
outputData containing sample times for interpolated data
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 82 of file dftint.c.

92 {
93 int fi, n, itunit;
94 double t1, t2;
95
96 if(verbose>0) printf("dftInterpolateCheckEnd()\n");
97
98 // Check the input
99 if(status!=NULL) sprintf(status, "program error");
100 if(input==NULL || output==NULL) return -1;
101 if(input->frameNr<1 || output->frameNr<1) return -1;
102 if(input->frameNr==1 && output->frameNr>1) {
103 if(status!=NULL) sprintf(status, "too short data for interpolation");
104 return -1;
105 }
106 if(status!=NULL) sprintf(status, "ok");
107
108 /* Try to make sure that time units are the same */
109 dftMatchTimeunits(output, input, &itunit, verbose);
110
111 /* Check that input data extends almost to the end of output range */
112 if(input->timetype==DFT_TIME_STARTEND && output->timetype==DFT_TIME_STARTEND) {
113 t1=input->x2[input->frameNr-1]; t2=output->x2[output->frameNr-1];
114 } else {
115 t1=input->x[input->frameNr-1]; t2=output->x[output->frameNr-1];
116 }
117 if(t1<0.95*t2) {
118 if(status!=NULL) strcpy(status, "too short data for interpolation");
119 if(verbose>1) printf("t1 := %g\nt2 := %g\n", t1, t2);
120 dftTimeunitConversion(input, itunit); // back to original time units
121 return -1;
122 }
123
124 /* Check that input sample frequency is not too low in the end */
125 if(output->frameNr>3) {
126 if(output->timetype==DFT_TIME_STARTEND) {
127 t1=output->x1[output->frameNr-3];
128 t2=output->x2[output->frameNr-1];
129 } else {
130 t1=output->x[output->frameNr-3];
131 t2=output->x[output->frameNr-1];
132 }
133 for(fi=n=0; fi<input->frameNr; fi++)
134 if(input->x[fi]>=t1 && input->x[fi]<=t2) n++;
135 if(n<1 || (n<2 && t2>input->x[input->frameNr-1])) {
136 if(status!=NULL) strcpy(status, "too sparse sampling for interpolation");
137 if(verbose>1) printf("n=%d t1=%g t2=%g\n", n, t1, t2);
138 dftTimeunitConversion(input, itunit); // back to original time units
139 return -1; // Error
140 }
141 if(n<2 || (n<3 && t2>input->x[input->frameNr-1])) {
142 if(status!=NULL) strcpy(status, "too sparse sampling for interpolation");
143 if(verbose>1) printf("n=%d t1=%g t2=%g\n", n, t1, t2);
144 dftTimeunitConversion(input, itunit); // back to original time units
145 return 1; // Warning
146 }
147 }
148 dftTimeunitConversion(input, itunit); // back to original time units
149 return 0;
150}
int dftTimeunitConversion(DFT *dft, int tunit)
Definition dftunit.c:119
int dftMatchTimeunits(DFT *dft1, DFT *dft2, int *tunit2, int verbose)
Definition fittime.c:358

Referenced by dftInterpolate(), dftInterpolateForIMG(), and dftInterpolateInto().

◆ dftInterpolateCheckStart()

int dftInterpolateCheckStart ( DFT * input,
DFT * output,
char * status,
int verbose )

Verify that data to-be-interpolated does not need too much extrapolation in the beginning.

See also
dftInterpolateCheckEnd, dftInterpolate, dftInterpolateInto, dftTimeIntegral
Returns
Returns 0 if data is fine, 1 if it starts late but extrapolation can be done reliably, and -1 if extrapolation in the beginning would be too risky.
Parameters
inputData that will be verified for reliable interpolation
outputData containing sample times for interpolated data
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 17 of file dftint.c.

27 {
28 int ri, itunit;
29 double t1, t2, f;
30
31 if(verbose>0) printf("dftInterpolateCheckStart()\n");
32
33 // Check the input
34 if(status!=NULL) sprintf(status, "program error");
35 if(input==NULL || output==NULL) return -1;
36 if(input->frameNr<1 || output->frameNr<1) return -1;
37 if(input->frameNr==1 && output->frameNr>1) {
38 if(status!=NULL) sprintf(status, "too short data for interpolation");
39 return -1;
40 }
41 if(status!=NULL) sprintf(status, "ok");
42
43 /* Try to make sure that time units are the same */
44 dftMatchTimeunits(output, input, &itunit, verbose);
45
46 /* Check the start */
48 t1=input->x1[0]; t2=output->x1[0];
49 } else {
50 t1=input->x[0]; t2=output->x[0];
51 }
52 if(0.95*t1>t2) {
53 if(verbose>1) printf("t1 := %g\nt2 := %g\n", t1, t2);
54 /* Check that first value is relatively low, so that there will not be any
55 error when the initial part is assumed to be a straight line from
56 (0,0) to the first sample point */
57 f=0.25*dft_kBqMax(input);
58 for(ri=0; ri<input->voiNr; ri++) if(input->voi[ri].y[0] > f) {
59 if(status!=NULL) strcpy(status, "data starts too late");
60 dftTimeunitConversion(input, itunit); // back to original time units
61 return -1;
62 }
63 if(status!=NULL) strcpy(status, "data starts late");
64 dftTimeunitConversion(input, itunit); // back to original time units
65 return 1;
66 }
67 dftTimeunitConversion(input, itunit); // back to original time units
68 return 0;
69}
double dft_kBqMax(DFT *data)
Definition dft.c:1148

Referenced by dftInterpolate(), dftInterpolateForIMG(), and dftInterpolateInto().

◆ dftInterpolateInto()

int dftInterpolateInto ( DFT * inp,
DFT * tis,
char * status,
int verbose )

Interpolate (and integrate) TAC data to sample times that are given with another TAC data. New TAC is written into existing TAC data. PET frame lengths are taken into account if available in tissue DFT struct. Input frame lengths are taken into account if the framing is same as with tissue data.

See also
dftTimeIntegral, dftInterpolate, dftInterpolateCheckStart, dftInterpolateCheckEnd
Returns
Returns 0 if successful, and <>0 in case of an error.
Parameters
inpData which is interpolated; make sure that time unit is the same as in tissue data; time range is checked to cover the tissue data
tisData into which the interpolation is done
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 281 of file dftint.c.

292 {
293 int fi, ri, ret;
294
295 if(verbose>0) printf("dftInterpolateInto()\n");
296
297 // Check the input
298 if(inp==NULL || tis==NULL) {
299 if(status!=NULL) sprintf(status, "program error");
300 return 1;
301 }
302 ret=dft_nr_of_NA(inp); if(ret>0) {
303 if(status!=NULL) sprintf(status, "missing sample(s)");
304 return 2;
305 }
306
307 // Check that there is no need for excess extrapolation
308 ret=dftInterpolateCheckEnd(inp, tis, status, verbose);
309 if(ret<0) return 3;
310 ret=dftInterpolateCheckStart(inp, tis, status, verbose);
311 if(ret<0) return 4;
312
313 // Allocate memory for interpolated data
314 if(dftAddmem(tis, inp->voiNr)) {
315 if(status!=NULL) strcpy(status, "memory allocation error");
316 return 5;
317 }
318
319 // Copy header information
320 for(ri=0; ri<inp->voiNr; ri++)
321 dftCopyvoihdr(inp, ri, tis, tis->voiNr+ri);
322
323 // Check if input and tissue data do have the same frame times already
324 if(check_times_dft_vs_dft(inp, tis, verbose)==1 &&
325 inp->frameNr>=tis->frameNr)
326 {
327 // copy the values directly and integrate in place
328 for(ri=0, ret=0; ri<inp->voiNr && ret==0; ri++) {
329 for(fi=0; fi<tis->frameNr; fi++)
330 tis->voi[tis->voiNr+ri].y[fi]=inp->voi[ri].y[fi];
332 ret=petintegral(tis->x1, tis->x2, tis->voi[tis->voiNr+ri].y,
333 tis->frameNr, tis->voi[tis->voiNr+ri].y2,
334 tis->voi[tis->voiNr+ri].y3);
335 else
336 ret=interpolate(tis->x, tis->voi[tis->voiNr+ri].y, tis->frameNr,
337 tis->x, tis->voi[tis->voiNr+ri].y,
338 tis->voi[tis->voiNr+ri].y2,
339 tis->voi[tis->voiNr+ri].y3, tis->frameNr);
340 }
341 if(ret) {
342 if(status!=NULL) sprintf(status, "cannot interpolate (%d)", ret);
343 dftEmpty(tis); return 7;
344 }
345 tis->voiNr+=inp->voiNr;
346 return 0; // that's it then
347 }
348
349 // Interpolate and integrate input data to tissue sample times,
350 // taking into account tissue frame lengths if available
351 for(ri=0, ret=0; ri<inp->voiNr && ret==0; ri++) {
353 ret=interpolate4pet(inp->x, inp->voi[ri].y, inp->frameNr,
354 tis->x1, tis->x2, tis->voi[tis->voiNr+ri].y,
355 tis->voi[tis->voiNr+ri].y2,
356 tis->voi[tis->voiNr+ri].y3, tis->frameNr);
357 else
358 ret=interpolate(inp->x, inp->voi[ri].y, inp->frameNr,
359 tis->x, tis->voi[tis->voiNr+ri].y,
360 tis->voi[tis->voiNr+ri].y2,
361 tis->voi[tis->voiNr+ri].y3, tis->frameNr);
362 }
363 if(ret) {
364 if(status!=NULL) sprintf(status, "cannot interpolate (%d)", ret);
365 return 9;
366 }
367 tis->voiNr+=inp->voiNr;
368
369 return 0;
370}
int dftAddmem(DFT *dft, int voiNr)
Definition dft.c:107
int dft_nr_of_NA(DFT *dft)
Definition dft.c:905

Referenced by dftReadModelingData(), dftReadReference(), and imgReadModelingData().

◆ dftTimeIntegral()

int dftTimeIntegral ( DFT * dft,
double t1,
double t2,
DFT * idft,
int calc_mode,
char * status,
int verbose )

Integration of regional TAC data from time1 to time2, i.e. AUC(t1,t2).

You may want to test the time range before applying this routine, because this function accepts relatively large extrapolation large.

See also
dftInterpolateInto, dftInterpolate, dftInterpolateCheckStart, dftInterpolateCheckEnd
Returns
Returns 0 when call was successful, and >0 in case of an error.
Parameters
dftRegional TAC data in DFT struct. Number of samples must be at least one. If only one sample, then the integration time range must match with the possible frame start and times. Frames do not have to be continuous in time.
t1Time where to start integration (same unit as in TACs)
t2Time to stop integration (same unit as in TACs); must be higher than t1, except that t1=t2 is acceptable when calc_mode=average
idftPointer to initiated but empty AUC DFT data (output)
calc_modeCalculate integral or average: 0=integral, 1=average
statusPointer to a string (allocated for at least 128 chars) where error message or other execution status will be written; enter NULL, if not needed
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 382 of file dftint.c.

402 {
403 int ri, fi, ret, f1, f2;
404 double fdur, aucroi, t[2], auc[2];
405 double accept_tdif=1.0; // in seconds
406
407 if(verbose>0)
408 printf("dftTimeIntegral(dft, %g, %g, idft, %d, status, %d)\n", t1, t2, calc_mode, verbose);
409
410 /* Check the arguments */
411 if(status!=NULL) sprintf(status, "program error");
412 if(dft==NULL || idft==NULL || t1<0.0 || t2<0.0) return STATUS_FAULT;
413 fdur=t2-t1; if(fdur<0.0) return STATUS_FAULT;
414 if(fdur==0.0 && (calc_mode!=1 || dft->frameNr>1)) return STATUS_FAULT;
415 if(dft->frameNr<1 || dft->voiNr<1) return STATUS_FAULT;
416
417 /* Set time unit based things */
418 if(dft->timeunit==TUNIT_MIN) accept_tdif/=60.0;
419
420 /* Create the DFT struct for AUC values */
421 ret=dftAllocateWithHeader(idft, 1, dft->voiNr, dft);
422 if(ret!=0) {
423 if(status!=NULL) sprintf(status, "cannot setup AUC data (%d)", ret);
424 return STATUS_FAULT;
425 }
426 /* 'frame' start and end time are taken from integration time */
428 if(calc_mode==1 && fdur==0.0) idft->timetype=DFT_TIME_MIDDLE;
430 /* Initially integral is zero */
431 for(ri=0; ri<idft->voiNr; ri++) idft->voi[ri].y[0]=0.0;
432 //dftPrint(dft);
433
434 /* Different paths if frame start and end times are taken into account or not */
435 if(dft->timetype==DFT_TIME_STARTEND) {
436
437 /* Check that time range matches with pet frame */
438 if(dft->frameNr==1) { // static data (one frame only)
439 /* check that specified times match with frame times, but
440 accept 1 s differences */
441 if(fabs(dft->x2[0]-t2)>accept_tdif || fabs(dft->x1[0]-t1)>accept_tdif) {
442 if(status!=NULL) {
443 strcpy(status, "for static data the integration time range must");
444 strcat(status, " be exactly as long as the scan");
445 }
446 return STATUS_FAULT;
447 }
448 /* Set the times, in case there was a small difference */
449 dft->x2[0]=t2; dft->x1[0]=t1;
450 } else { // Dynamic data (more than one frame)
451 /* First frame must start before 1/3 of the integration time */
452 /* Last frame must end after 2/3 of integration time */
453 if(dft->x1[0]>(0.66*t1+0.34*t2) ||
454 dft->x2[dft->frameNr-1]<(0.34*t1+0.66*t2)) {
455 if(status!=NULL)
456 strcpy(status, "integration time range oversteps data range");
457 return STATUS_FAULT;
458 }
459 }
460
461 /* Get the first and last frame index that resides inside integration time*/
462 if(dft->frameNr==1) {
463 f1=f2=0;
464 } else {
465 for(fi=0, f1=f2=-1; fi<dft->frameNr; fi++) {
466 if(f1<0) {if(dft->x1[fi]>=t1 && dft->x2[fi]<=t2) f1=f2=fi;}
467 if(f1>=0) {if(t2>=dft->x2[fi]) f2=fi;}
468 }
469 }
470 if(verbose>1) printf("f1=%d f2=%d\n", f1, f2);
471 if(f1>=0 && f2>=0) {
472 /* Integrate over the frames that are included in time range as a whole */
473 fi=f1;
474 for(ri=0; ri<dft->voiNr; ri++) {
475 idft->voi[ri].y[0]+=(dft->x2[fi]-dft->x1[fi])*dft->voi[ri].y[fi];
476 }
477 for(fi=f1+1; fi<=f2; fi++) {
478 for(ri=0; ri<dft->voiNr; ri++) {
479 idft->voi[ri].y[0]+=(dft->x2[fi]-dft->x1[fi])*dft->voi[ri].y[fi];
480 }
481 /* Check whether frames are contiguous */
482 if(dft->x1[fi]==dft->x2[fi-1]) continue;
483 /* When not, calculate the area of an imaginary frame */
484 double x, a;
485 x=(dft->x1[fi]+dft->x2[fi-1])/2.0;
486 for(ri=0; ri<dft->voiNr; ri++) {
487 a=(dft->x1[fi]-dft->x2[fi-1])*
488 (dft->voi[ri].y[fi]-(dft->voi[ri].y[fi]-dft->voi[ri].y[fi-1])
489 *(dft->x2[fi]+dft->x1[fi]-2.0*x)
490 /(dft->x2[fi]+dft->x1[fi]-dft->x2[fi-1]-dft->x1[fi-1]));
491 idft->voi[ri].y[0]+=a;
492 }
493 }
494
495 /* If necessary, add the partial integrals */
496 if(dft->x1[f1]>t1) {
497 t[0]=t1; t[1]=dft->x1[f1];
498 if(verbose>5) printf("t[0]=%g t[1]=%g\n", t[0], t[1]);
499 for(ri=0; ri<dft->voiNr; ri++) {
500 ret=interpolate(dft->x, dft->voi[ri].y, dft->frameNr, t, NULL, auc, NULL, 2);
501 if(ret) aucroi=0.0; else aucroi=auc[1]-auc[0];
502 idft->voi[ri].y[0]+=aucroi;
503 }
504 }
505 if(t2>dft->x2[f2]) {
506 t[0]=dft->x2[f2]; t[1]=t2;
507 if(verbose>5) printf("t[0]=%g t[1]=%g\n", t[0], t[1]);
508 for(ri=0; ri<dft->voiNr; ri++) {
509 ret=interpolate(dft->x, dft->voi[ri].y, dft->frameNr, t, NULL, auc, NULL, 2);
510 if(ret) aucroi=0.0; else aucroi=auc[1]-auc[0];
511 idft->voi[ri].y[0]+=aucroi;
512 }
513 }
514
515 } else { // no full frames inside integration range
516
517 t[0]=t1; t[1]=t2;
518 for(ri=0; ri<dft->voiNr; ri++) {
519 ret=interpolate(dft->x, dft->voi[ri].y, dft->frameNr, t, NULL, auc, NULL, 2);
520 if(ret) aucroi=0.0; else aucroi=auc[1]-auc[0];
521 idft->voi[ri].y[0]+=aucroi;
522 }
523
524 }
525
526 /* Set output image time frame */
527 idft->x2[0]=t2; idft->x1[0]=t1; idft->x[0]=0.5*(t1+t2);
528
529 } else if(dft->timetype==DFT_TIME_MIDDLE) { // do not consider frame lengths
530
531 /* If average calculation was required, and sample times match the required
532 time range, then directly take the values; otherwise, calculate AUC */
533 if(calc_mode==1 && dft->x[0]==t1 && dft->x[0]==t2 && dft->frameNr==1) {
534 for(ri=0; ri<dft->voiNr; ri++)
535 idft->voi[ri].y[0]=dft->voi[ri].y[0];
536 } else {
537
538 /* First sample time must be before 1/3 of the integration time */
539 /* Last sample time must end after 2/3 of integration time */
540 if(dft->x[0]>(0.66*t1+0.34*t2) ||
541 dft->x[dft->frameNr-1]<(0.34*t1+0.66*t2)) {
542 if(status!=NULL) sprintf(status, "integration time range oversteps data range");
543 return STATUS_FAULT;
544 }
545
546 t[0]=t1; t[1]=t2;
547 if(verbose>5) printf("t[0]=%g t[1]=%g\n", t[0], t[1]);
548 for(ri=0; ri<dft->voiNr; ri++) {
549 ret=interpolate(dft->x, dft->voi[ri].y, dft->frameNr, t, NULL, auc, NULL, 2);
550 if(ret) idft->voi[ri].y[0]=0.0; else idft->voi[ri].y[0]=auc[1]-auc[0];
551 }
552 }
553 /* Set output image time frame */
554 idft->x2[0]=t2; idft->x1[0]=t1; idft->x[0]=0.5*(t1+t2);
555
556 } else {
557 if(status!=NULL)
558 sprintf(status, "frame mid times or start and end times required");
559 return STATUS_FAULT;
560 }
561
562 /* If required, then calculate average by dividing integral with time */
563 /* Set units accordingly */
564 if(calc_mode!=0) { // average
565 if(fdur>0.0)
566 for(ri=fi=0; ri<idft->voiNr; ri++)
567 idft->voi[ri].y[fi]/=fdur;
568 if(status!=NULL) sprintf(status, "average TAC [%g,%g] calculated", t1, t2);
569 } else { // integral
570 int unit;
571 unit=petCunitId(idft->unit);
572 strcpy(idft->unit, dftUnit(CUNIT_UNKNOWN));
573 if(unit==CUNIT_KBQ_PER_ML) {
574 if(idft->timeunit==TUNIT_MIN)
575 strcpy(idft->unit, dftUnit(CUNIT_MIN_KBQ_PER_ML));
576 else if(idft->timeunit==TUNIT_SEC)
577 strcpy(idft->unit, dftUnit(CUNIT_SEC_KBQ_PER_ML));
578 }
579 if(status!=NULL) sprintf(status, "TAC integral [%g,%g] calculated", t1, t2);
580 }
581
582 return(0);
583}
int dftAllocateWithHeader(DFT *dft, int frameNr, int voiNr, DFT *dft_from)
Definition dft.c:702
#define DFT_FORMAT_STANDARD
int petCunitId(const char *unit)
Definition petunits.c:74
int _type
int timeunit
char unit[MAX_UNITS_LEN+1]