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

Functions for processing TAC data in DFT structures. More...

#include "libtpccurveio.h"
#include <unistd.h>

Go to the source code of this file.

Functions

void dftEmpty (DFT *data)
 
void dftInit (DFT *data)
 
int dftSetmem (DFT *data, int frameNr, int voiNr)
 
int dftAddmem (DFT *dft, int voiNr)
 
int dftAdd (DFT *data1, DFT *data2, int voi)
 
int dftSelect (DFT *data, char *name)
 
int dftSelectRegions (DFT *dft, char *region_name, int reset)
 
int dftSelectBestReference (DFT *dft)
 
void dftFrametimes (DFT *data)
 
int dftOverflow (DFT *data)
 
int dftCopyvoi (DFT *data, int from, int to)
 
int dftMovevoi (DFT *dft, int from, int to)
 
int dftDelete (DFT *dft, int voi)
 
int dftCopymainhdr (DFT *dft1, DFT *dft2)
 
int dftCopymainhdr2 (DFT *dft1, DFT *dft2, int ow)
 
int dftCopyvoihdr (DFT *dft1, int from, DFT *dft2, int to)
 
int dftdup (DFT *dft1, DFT *dft2)
 
int dftAllocateWithHeader (DFT *dft, int frameNr, int voiNr, DFT *dft_from)
 
int dftAddnullframe (DFT *data)
 
int dftSort (DFT *data)
 
int dftSortPlane (DFT *data)
 
int dft_nr_of_NA (DFT *dft)
 
int dftNAfill (DFT *dft)
 
int dftMinMax (DFT *dft, double *minx, double *maxx, double *miny, double *maxy)
 
int dftMinMaxTAC (DFT *dft, int tacindex, double *minx, double *maxx, double *miny, double *maxy, int *mini, int *maxi, int *mins, int *maxs)
 
int dftMaxY (DFT *dft, double t1, double t2, double *miny, double *maxy)
 
double dft_kBqMin (DFT *data)
 
double dft_kBqMax (DFT *data)
 
int dftSortByFrame (DFT *dft)
 
int dftDeleteFrameOverlap_old (DFT *dft)
 
int dftDeleteFrameOverlap (DFT *dft)
 
int dftRemoveTimeRange (DFT *dft, double startT, double endT)
 
void dftSetComments (DFT *dft)
 
int dftFillInitialGap (DFT *dft)
 
int dftAddSpaceForFrames (DFT *dft, int nr_to_add)
 
void dftRNameSimplify (DFT *dft, int hemisphere, int place)
 
int dftMeanTAC (DFT *dft, DFT *mean)
 
int dftValidNr (DFT *dft, double tstart, double tstop, int index)
 

Variables

char dfterrmsg [64]
 

Detailed Description

Functions for processing TAC data in DFT structures.

Author
Vesa Oikonen

Definition in file dft.c.

Function Documentation

◆ dft_kBqMax()

double dft_kBqMax ( DFT * data)

Returns the highest activity value in DFT

Parameters
dataPointer to DFT struct

Definition at line 1148 of file dft.c.

1151 {
1152 int i, j;
1153 double max=-1e+99;
1154
1155 if(data==NULL) return(nan(""));
1156 for(i=0; i<data->voiNr ;i++){
1157 for(j=0; j<data->frameNr; j++){
1158 if(!isnan(data->voi[i].y[j]) && data->voi[i].y[j]>max) max=data->voi[i].y[j];
1159 }
1160 }
1161 return(max);
1162}
Voi * voi
int voiNr
int frameNr
double * y

Referenced by dftInterpolateCheckStart().

◆ dft_kBqMin()

double dft_kBqMin ( DFT * data)

Returns the lowest activity value in DFT

Parameters
dataPointer to DFT struct

Definition at line 1129 of file dft.c.

1132 {
1133 int i, j;
1134 double min=1e+99;
1135
1136 if(data==NULL) return(nan(""));
1137 for(i=0; i<data->voiNr ;i++) {
1138 for(j=0; j<data->frameNr; j++) {
1139 if(!isnan(data->voi[i].y[j]) && data->voi[i].y[j]<min) min=data->voi[i].y[j];
1140 }
1141 }
1142 return(min);
1143}

◆ dft_nr_of_NA()

int dft_nr_of_NA ( DFT * dft)

Check DFT for NA's in sample times and values.

Returns
Returns the number of NA's that were found.
Parameters
dftPointer to DFT struct

Definition at line 905 of file dft.c.

908 {
909 int ri, fi, na_nr=0;
910 if(dft==NULL) return 0;
911 for(fi=0; fi<dft->frameNr; fi++) {
912 if(dft->timetype==DFT_TIME_STARTEND) {
913 if(isnan(dft->x1[fi])) na_nr++;
914 if(isnan(dft->x2[fi])) na_nr++;
915 } else {
916 if(isnan(dft->x[fi])) na_nr++;
917 }
918 for(ri=0; ri<dft->voiNr; ri++) if(isnan(dft->voi[ri].y[fi])) na_nr++;
919 }
920 return(na_nr);
921}
#define DFT_TIME_STARTEND
int timetype
double * x1
double * x2
double * x

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

◆ dftAdd()

int dftAdd ( DFT * data1,
DFT * data2,
int voi )

Add the specified voi [0,voiNr-1] from data2 to data1. Allocates memory for additional data VOI, if necessary.

Returns
Returns 0 if ok.
Parameters
data1Pointer to DFT struct data
data2Pointer to DFT struct data
voiIndex of TAC in the 2nd DFT

Definition at line 188 of file dft.c.

195 {
196 int i, n;
197
198 if(data1==NULL || data2==NULL) return 1;
199 /* Check that voi exists */
200 if(data2->voiNr<=voi || voi<0) {
201 strcpy(dfterrmsg, "there is no region to combine"); return 8;}
202
203 /* Check that frame number etc is the same */
204 if(data1->frameNr!=data2->frameNr ||
205 (data1->_type!=DFT_FORMAT_PLAIN && data2->_type!=DFT_FORMAT_PLAIN &&
206 (data1->timeunit!=data2->timeunit || strcasecmp(data1->unit, data2->unit))
207 )) {
208 strcpy(dfterrmsg, "data does not match"); return 8;}
209
210 /* Allocate more memory if necessary */
211 if(data1->_voidataNr==data1->voiNr)
212 if(dftAddmem(data1, 1)) {
213 strcpy(dfterrmsg, "cannot allocate memory"); return 8;}
214
215 /* Copy data */
216 n=data1->voiNr;
217 (void)dftCopyvoihdr(data2, voi, data1, n);
218 for(i=0; i<data1->frameNr; i++) {
219 data1->voi[n].y[i]=data2->voi[voi].y[i];
220 data1->voi[n].y2[i]=data2->voi[voi].y2[i];
221 data1->voi[n].y3[i]=data2->voi[voi].y3[i];
222 }
223 data1->voiNr+=1;
224
225 /* If data2 contains weights and data1 does not, then copy those */
226 if(data2->isweight && !data1->isweight)
227 for(i=0; i<data1->frameNr; i++) data1->w[i]=data2->w[i];
228
229 return 0;
230}
int dftCopyvoihdr(DFT *dft1, int from, DFT *dft2, int to)
Definition dft.c:623
char dfterrmsg[64]
Definition dft.c:6
int dftAddmem(DFT *dft, int voiNr)
Definition dft.c:107
#define DFT_FORMAT_PLAIN
int _type
int timeunit
double * w
int isweight
char unit[MAX_UNITS_LEN+1]
double * y2
double * y3

◆ dftAddmem()

int dftAddmem ( DFT * dft,
int voiNr )

Adds room for additional VOI TAC(s) into DFT data structure.

Old data is left unchanged.

Returns
Returns 0 when successful.
Parameters
dftPointer to DFT data structure
voiNrNr of additional VOI memory blocks

Definition at line 107 of file dft.c.

112 {
113 Voi *voi2;
114 double *data2, *dptr, *newx, *newx1, *newx2, *neww;
115 int ri, fi, dataSize2, voidataNr2;
116
117 /* Check the input */
118 if(dft==NULL || dft->voi==NULL || dft->frameNr<1 || dft->voiNr<1) return 1;
119 if(voiNr<0) return 1; else if(voiNr==0) return 0;
120
121 /* Allocate memory for new set of curve data (plus additional 'frame') */
122 voidataNr2=voiNr+dft->_voidataNr;
123 voi2=(Voi*)calloc(voidataNr2, sizeof(Voi));
124 if(voi2==NULL) return 3;
125 dataSize2=(dft->frameNr+1)*(3*voidataNr2+4);
126 data2=(double*)calloc(dataSize2, sizeof(double)); if(data2==NULL) return 3;
127 /* Set pointers for new curve data */
128 dptr=data2; newx=dptr; newx[dft->frameNr]=0.0;
129 dptr+=dft->frameNr+1; newx1=dptr; newx1[dft->frameNr]=0.0;
130 dptr+=dft->frameNr+1; newx2=dptr; newx2[dft->frameNr]=0.0;
131 dptr+=dft->frameNr+1; neww=dptr; neww[dft->frameNr]=0.0;
132 for(ri=0; ri<voidataNr2; ri++) {
133 dptr+=dft->frameNr+1; voi2[ri].y = dptr;
134 dptr+=dft->frameNr+1; voi2[ri].y2 = dptr;
135 dptr+=dft->frameNr+1; voi2[ri].y3 = dptr;
136 }
137
138 /* Copy the original contents */
139 for(ri=0; ri<dft->voiNr; ri++) {
140 /* Copy Voi header */
141 strcpy(voi2[ri].name, dft->voi[ri].name);
142 strcpy(voi2[ri].voiname, dft->voi[ri].voiname);
143 strcpy(voi2[ri].hemisphere, dft->voi[ri].hemisphere);
144 strcpy(voi2[ri].place, dft->voi[ri].place);
145 voi2[ri].size=dft->voi[ri].size;
146 voi2[ri].sw=dft->voi[ri].sw;
147 voi2[ri].sw2=dft->voi[ri].sw2;
148 voi2[ri].sw3=dft->voi[ri].sw3;
149 /* Copy Voi data */
150 for(fi=0; fi<dft->frameNr; fi++) {
151 voi2[ri].y[fi]=dft->voi[ri].y[fi];
152 voi2[ri].y2[fi]=dft->voi[ri].y2[fi];
153 voi2[ri].y3[fi]=dft->voi[ri].y3[fi];
154 }
155 }
156 for(fi=0; fi<dft->frameNr; fi++) {
157 newx[fi]=dft->x[fi]; newx1[fi]=dft->x1[fi]; newx2[fi]=dft->x2[fi];
158 neww[fi]=dft->w[fi];
159 }
160
161 /* Replace original pointers */
162 free(dft->_data); dft->_data=data2;
163 free(dft->voi); dft->voi=voi2;
164 dft->x=newx; dft->x1=newx1; dft->x2=newx2; dft->w=neww;
165 dft->_voidataNr=voidataNr2; dft->_dataSize=dataSize2;
166
167 /* Initiate values */
168 for(ri=dft->voiNr; ri<dft->_voidataNr; ri++) {
169 strcpy(dft->voi[ri].name, "");
170 strcpy(dft->voi[ri].voiname, "");
171 strcpy(dft->voi[ri].hemisphere, "");
172 strcpy(dft->voi[ri].place, "");
173 dft->voi[ri].size=1.0;
174 dft->voi[ri].sw=dft->voi[ri].sw2=dft->voi[ri].sw3=0;
175 for(fi=0; fi<dft->frameNr+1; fi++)
176 dft->voi[ri].y[fi]=dft->voi[ri].y2[fi]=dft->voi[ri].y3[fi]=0.0;
177 }
178
179 return 0;
180}
double size
char voiname[MAX_REGIONSUBNAME_LEN+1]
char sw
char name[MAX_REGIONNAME_LEN+1]
char hemisphere[MAX_REGIONSUBNAME_LEN+1]
char sw2
char sw3
char place[MAX_REGIONSUBNAME_LEN+1]

Referenced by dftAdd(), dftInterpolateInto(), dftReadModelingData(), and imgReadModelingData().

◆ dftAddnullframe()

int dftAddnullframe ( DFT * data)

Include a frame with time 0, unless one already exists.

Returns
Returns <> 0 in case of an error.
Parameters
dataPointer to DFT struct

Definition at line 752 of file dft.c.

755 {
756 int i, j, n;
757 DFT temp;
758
759
760 /* Check whether nullframe exists */
761 if(data==NULL) return 1;
762 if(data->frameNr<1 || data->x[0]==0.0) return 0;
763
764 /* Allocate memory for temp data */
765 dftInit(&temp);
766 if(dftSetmem(&temp, data->frameNr, data->voiNr)) return 1;
767 temp.frameNr=data->frameNr; temp.voiNr=data->voiNr;
768
769 /* Copy data to temp */
770 strcpy(temp.studynr, data->studynr);
771 strcpy(temp.unit, data->unit);
772 temp.timeunit=data->timeunit; temp.timetype=data->timetype;
773 temp.isweight=data->isweight; temp._type=data->_type;
774 strcpy(temp.comments, data->comments);
775 for(j=0; j<data->frameNr; j++) {
776 temp.x[j]=data->x[j]; temp.x1[j]=data->x1[j]; temp.x2[j]=data->x2[j];
777 temp.w[j]=data->w[j];
778 for(i=0; i<data->voiNr; i++) {
779 temp.voi[i].y[j]=data->voi[i].y[j];
780 temp.voi[i].y2[j]=data->voi[i].y2[j];
781 temp.voi[i].y3[j]=data->voi[i].y3[j];
782 }
783 }
784 for(i=0; i<data->voiNr; i++) {
785 strcpy(temp.voi[i].name, data->voi[i].name);
786 strcpy(temp.voi[i].voiname, data->voi[i].voiname);
787 strcpy(temp.voi[i].hemisphere, data->voi[i].hemisphere);
788 strcpy(temp.voi[i].place, data->voi[i].place);
789 temp.voi[i].size=data->voi[i].size;
790 temp.voi[i].sw=data->voi[i].sw;
791 temp.voi[i].sw2=data->voi[i].sw2;
792 temp.voi[i].sw3=data->voi[i].sw3;
793 }
794
795 /* Reallocate memory for data */
796 dftEmpty(data);
797 if(dftSetmem(data, temp.frameNr+1, temp.voiNr)) {dftEmpty(&temp); return 2;}
798
799 /* Set nullframe */
800 data->x[0]=data->x1[0]=data->x2[0]=0.0; data->w[0]=0.0;
801 for(i=0; i<temp.voiNr; i++)
802 data->voi[i].y[0]=data->voi[i].y2[0]=data->voi[i].y3[0]=0.0;
803
804 /* Copy data back from temp */
805 strcpy(data->studynr, temp.studynr);
806 data->voiNr=temp.voiNr;
807 strcpy(data->unit, temp.unit);
808 data->timeunit=temp.timeunit; data->timetype=temp.timetype;
809 data->isweight=temp.isweight; data->_type=temp._type;
810 strcpy(data->comments, temp.comments);
811 for(j=0, n=1; j<temp.frameNr; j++) {
812 if(temp.x[j]<0.0) continue;
813 if(n==1) data->x2[0]=temp.x1[j];
814 data->x[n]=temp.x[j]; data->x1[n]=temp.x1[j]; data->x2[n]=temp.x2[j];
815 data->w[n]=temp.w[j];
816 for(i=0; i<temp.voiNr; i++) {
817 data->voi[i].y[n]=temp.voi[i].y[j];
818 data->voi[i].y2[n]=temp.voi[i].y2[j];
819 data->voi[i].y3[n]=temp.voi[i].y3[j];
820 }
821 n++;
822 }
823 data->frameNr=n;
824 for(i=0; i<temp.voiNr; i++) {
825 strcpy(data->voi[i].name, temp.voi[i].name);
826 strcpy(data->voi[i].voiname, temp.voi[i].voiname);
827 strcpy(data->voi[i].hemisphere, temp.voi[i].hemisphere);
828 strcpy(data->voi[i].place, temp.voi[i].place);
829 data->voi[i].size=temp.voi[i].size;
830 data->voi[i].sw=temp.voi[i].sw;
831 data->voi[i].sw2=temp.voi[i].sw2;
832 data->voi[i].sw3=temp.voi[i].sw3;
833 }
834
835 dftEmpty(&temp);
836
837 return 0;
838}
void dftInit(DFT *data)
Definition dft.c:38
int dftSetmem(DFT *data, int frameNr, int voiNr)
Definition dft.c:57
void dftEmpty(DFT *data)
Definition dft.c:20
char studynr[MAX_STUDYNR_LEN+1]
char comments[_DFT_COMMENT_LEN+1]

◆ dftAddSpaceForFrames()

int dftAddSpaceForFrames ( DFT * dft,
int nr_to_add )

Add space for additional frames into DFT, keeping the existing data. frameNr is increased by nr_to_add, but new last frame(s) are empty.

Returns
Returns zero if successful, otherwise <>0.
Parameters
dftAllocated and data-filled DFT where new frame(s) are added to the end
nr_to_addNr of frames to add

Definition at line 1465 of file dft.c.

1470 {
1471 DFT temp;
1472 int ret, ri, fi;
1473
1474 /* Check input */
1475 if(dft==NULL || dft->frameNr<1 || dft->voiNr<1) return 1;
1476 if(nr_to_add<1) return 0;
1477
1478 /* Make a temporary storage of the data */
1479 dftInit(&temp); ret=dftdup(dft, &temp); if(ret!=0) return 10+ret;
1480 /* Delete and reallocate the original data pointer */
1481 dftEmpty(dft); ret=dftSetmem(dft, temp.frameNr+nr_to_add, temp.voiNr);
1482 if(ret!=0) {
1483 dftdup(&temp, dft); dftEmpty(&temp);
1484 return 20+ret;
1485 }
1486 /* Copy data back, leaving last frame(s) empty */
1487 ret=dftCopymainhdr(&temp, dft);
1488 if(ret!=0) {
1489 dftdup(&temp, dft); dftEmpty(&temp);
1490 return 30+ret;
1491 }
1492 dft->voiNr=temp.voiNr; dft->frameNr=nr_to_add+temp.frameNr;
1493 dft->isweight=temp.isweight;
1494 strcpy(dft->comments, temp.comments);
1495 for(ri=0; ri<temp.voiNr; ri++) {
1496 ret=dftCopyvoihdr(&temp, ri, dft, ri);
1497 if(ret!=0) {
1498 dftdup(&temp, dft); dftEmpty(&temp);
1499 return 40+ret;
1500 }
1501 for(fi=0; fi<temp.frameNr; fi++) {
1502 dft->voi[ri].y[fi]=temp.voi[ri].y[fi];
1503 dft->voi[ri].y2[fi]=temp.voi[ri].y2[fi];
1504 dft->voi[ri].y3[fi]=temp.voi[ri].y3[fi];
1505 }
1506 /* Fill in the first frame */
1507 dft->voi[ri].y[0]=0.0;
1508 dft->voi[ri].y2[0]=0.0;
1509 dft->voi[ri].y3[0]=0.0;
1510 }
1511 for(fi=0; fi<temp.frameNr; fi++) {
1512 dft->x1[fi]=temp.x1[fi];
1513 dft->x2[fi]=temp.x2[fi];
1514 dft->x[fi]=temp.x[fi];
1515 dft->w[fi]=temp.w[fi];
1516 }
1517
1518 /* Fill the last frames with NAs */
1519 for(fi=temp.frameNr; fi<dft->frameNr; fi++) {
1520 dft->w[fi]=1.0;
1521 dft->x1[fi]=dft->x2[fi]=dft->x[0]=0.0;
1522 for(ri=0; ri<dft->voiNr; ri++) dft->voi[ri].y[fi]=nan("");
1523 }
1524 dftEmpty(&temp);
1525
1526 return 0;
1527}
int dftdup(DFT *dft1, DFT *dft2)
Definition dft.c:655
int dftCopymainhdr(DFT *dft1, DFT *dft2)
Definition dft.c:561

◆ dftAllocateWithHeader()

int dftAllocateWithHeader ( DFT * dft,
int frameNr,
int voiNr,
DFT * dft_from )

Allocates a DFT structure with specified size, containing no TAC data but header information as available in another DFT struct.

Any existing content of dft2 will be deleted. Dft2 must be initiated.

Returns
Returns 0 if ok.
Parameters
dftPointer to initiated DFT struct which will be allocated here; any previous contents will be deleted.
frameNrNr of frames to be allocated
voiNrNr of planes to be allocated
dft_fromPointer to DFT struct where header contents will be copied from

Definition at line 702 of file dft.c.

712 {
713 int ri, fi, ret;
714
715 /* Check the input */
716 if(dft==NULL || dft_from==NULL || frameNr<1 || voiNr<0) return 1;
717 /* Empty the new data */
718 dftEmpty(dft);
719 /* Allocate memory for dft */
720 ret=dftSetmem(dft, frameNr, voiNr); if(ret) return(ret);
721 dft->voiNr=voiNr; dft->frameNr=frameNr;
722 /* Copy the contents */
723 ret=dftCopymainhdr(dft_from, dft); if(ret) return(ret);
724 if(dft->voiNr==dft_from->voiNr) {
725 for(ri=0; ri<dft->voiNr; ri++) {
726 ret=dftCopyvoihdr(dft_from, ri, dft, ri); if(ret) return(ret);
727 if(dft->frameNr==dft_from->frameNr) {
728 for(fi=0; fi<dft->frameNr; fi++) {
729 dft->voi[ri].y[fi]=dft_from->voi[ri].y[fi];
730 dft->voi[ri].y2[fi]=dft_from->voi[ri].y2[fi];
731 dft->voi[ri].y3[fi]=dft_from->voi[ri].y3[fi];
732 }
733 }
734 }
735 }
736 if(dft->frameNr==dft_from->frameNr) {
737 for(fi=0; fi<dft->frameNr; fi++) {
738 dft->x[fi]=dft_from->x[fi];
739 dft->x1[fi]=dft_from->x1[fi]; dft->x2[fi]=dft_from->x2[fi];
740 dft->w[fi]=dft_from->w[fi];
741 }
742 dft->isweight=dft_from->isweight;
743 }
744 return(0);
745}

Referenced by dftInterpolateForIMG(), dftMeanTAC(), and dftTimeIntegral().

◆ dftCopymainhdr()

int dftCopymainhdr ( DFT * dft1,
DFT * dft2 )

Copy main header info from dft1 to dft2.

Returns
Returns <> 0 in case of an error.
Parameters
dft1Pointer to DFT struct from where information is copied
dft2Pointer to DFT struct into which information is copied to

Definition at line 561 of file dft.c.

566 {
567 if(dft1==NULL || dft2==NULL) return 1;
568 strcpy(dft2->studynr, dft1->studynr);
569 strcpy(dft2->unit, dft1->unit);
570 dft2->timeunit=dft1->timeunit; dft2->timetype=dft1->timetype;
571 strcpy(dft2->comments, dft1->comments);
572 strcpy(dft2->radiopharmaceutical, dft1->radiopharmaceutical);
573 strcpy(dft2->isotope, dft1->isotope);
574 strcpy(dft2->scanStartTime, dft1->scanStartTime);
575 strcpy(dft2->injectionTime, dft1->injectionTime);
576 dft2->decayCorrected=dft1->decayCorrected;
577 dft2->_type=dft1->_type;
578 return 0;
579}
char scanStartTime[20]
char decayCorrected
char injectionTime[20]
char isotope[8]
char radiopharmaceutical[32]

Referenced by dftAddSpaceForFrames(), dftAllocateWithHeader(), dftAutointerpolate(), dftDivideFrames(), dftDoubleFrames(), dftdup(), dftFillInitialGap(), dftInterpolate(), extrapolate_monoexp(), and plotdata_as_dft().

◆ dftCopymainhdr2()

int dftCopymainhdr2 ( DFT * dft1,
DFT * dft2,
int ow )

Copy main header info from dft1 to dft2. Comments are not copied, because those may contain outdated units and other information.

Returns
Returns <> 0 in case of an error.
Parameters
dft1Pointer to DFT struct from where information is copied
dft2Pointer to DFT struct into which information is copied to
owExisting header field content is overwritten (1) or kept (0)

Definition at line 587 of file dft.c.

594 {
595 if(dft1==NULL || dft2==NULL) return 1;
596 if(ow || (strlen(dft2->studynr)<1 && strcmp(dft2->studynr, ".")==0))
597 strcpy(dft2->studynr, dft1->studynr);
598 if(ow || dftUnitId(dft2->unit)==CUNIT_UNKNOWN)
599 strcpy(dft2->unit, dft1->unit);
600 if(ow || dft2->timeunit==TUNIT_UNKNOWN)
601 dft2->timeunit=dft1->timeunit;
602 dft2->timetype=dft1->timetype;
603 if(ow || strlen(dft2->radiopharmaceutical)<1)
604 strcpy(dft2->radiopharmaceutical, dft1->radiopharmaceutical);
605 if(ow || strlen(dft2->isotope)<1)
606 strcpy(dft2->isotope, dft1->isotope);
607 if(ow || strlen(dft2->scanStartTime)<1)
608 strcpy(dft2->scanStartTime, dft1->scanStartTime);
609 if(ow || strlen(dft2->injectionTime)<1)
610 strcpy(dft2->injectionTime, dft1->injectionTime);
611 if(ow || dft2->decayCorrected==DFT_DECAY_UNKNOWN)
612 dft2->decayCorrected=dft1->decayCorrected;
613 if(ow)
614 dft2->_type=dft1->_type;
615 return 0;
616}
#define DFT_DECAY_UNKNOWN

Referenced by bfIrr2TCM(), and bfRadiowater().

◆ dftCopyvoi()

int dftCopyvoi ( DFT * data,
int from,
int to )

Copy VOI data inside DFT data structure from one place to another.

Parameters
dataPointer to DFT struct
fromTAC index
toTAC index

Definition at line 472 of file dft.c.

479 {
480 int i;
481
482 /* Check that required data exists */
483 if(data==NULL || to>=data->_voidataNr || from>=data->_voidataNr) return 1;
484 if(from==to) return 0;
485
486 /* Copy VOI info */
487 strcpy(data->voi[to].name, data->voi[from].name);
488 strcpy(data->voi[to].voiname, data->voi[from].voiname);
489 strcpy(data->voi[to].hemisphere, data->voi[from].hemisphere);
490 strcpy(data->voi[to].place, data->voi[from].place);
491 data->voi[to].size=data->voi[from].size;
492 data->voi[to].sw=data->voi[from].sw;
493 data->voi[to].sw2=data->voi[from].sw2;
494 data->voi[to].sw3=data->voi[from].sw3;
495 /* Copy VOI curves */
496 for(i=0; i<data->frameNr; i++) {
497 data->voi[to].y[i]=data->voi[from].y[i];
498 data->voi[to].y2[i]=data->voi[from].y2[i];
499 data->voi[to].y3[i]=data->voi[from].y3[i];
500 }
501
502 return 0;
503}

Referenced by dftRead().

◆ dftCopyvoihdr()

int dftCopyvoihdr ( DFT * dft1,
int from,
DFT * dft2,
int to )

Copy voi header info from dft1.voi[from] to dft2.voi[to].

Returns
Returns <> 0 in case of an error.
Parameters
dft1Pointer to DFT struct
fromTAC index
dft2Pointer to DFT struct
toTAC index

Definition at line 623 of file dft.c.

632 {
633 /* Check that required data exists */
634 if(dft1==NULL || dft2==NULL) return 1;
635 if(to>=dft2->_voidataNr || from>=dft1->_voidataNr) return 1;
636
637 /* Copy VOI info */
638 strcpy(dft2->voi[to].name, dft1->voi[from].name);
639 strcpy(dft2->voi[to].voiname, dft1->voi[from].voiname);
640 strcpy(dft2->voi[to].hemisphere, dft1->voi[from].hemisphere);
641 strcpy(dft2->voi[to].place, dft1->voi[from].place);
642 dft2->voi[to].size=dft1->voi[from].size;
643 dft2->voi[to].sw=dft1->voi[from].sw;
644 dft2->voi[to].sw2=dft1->voi[from].sw2;
645 dft2->voi[to].sw3=dft1->voi[from].sw3;
646
647 return 0;
648}

Referenced by dftAdd(), dftAddSpaceForFrames(), dftAllocateWithHeader(), dftAutointerpolate(), dftDivideFrames(), dftDoubleFrames(), dftdup(), dftFillInitialGap(), dftInterpolate(), dftInterpolateInto(), extrapolate_monoexp(), and plotdata_as_dft().

◆ dftDelete()

int dftDelete ( DFT * dft,
int voi )

Delete specified TAC (0..voiNr-1) from the DFT structure.

Returns
Returns 0 if ok.
Parameters
dftPointer to DFT struct
voiTAC index

Definition at line 538 of file dft.c.

543 {
544 int ret;
545
546 /* Check that region exists */
547 if(dft==NULL || voi>dft->voiNr-1 || voi<0) return(1);
548 /* If it is the last one, then just decrease the voiNr */
549 if(voi==dft->voiNr-1) {dft->voiNr--; return(0);}
550 /* Otherwise move it to the last position, and then decrease voiNr */
551 ret=dftMovevoi(dft, voi, dft->voiNr-1); if(ret) return(10+ret);
552 dft->voiNr--;
553 return(0);
554}
int dftMovevoi(DFT *dft, int from, int to)
Definition dft.c:508

Referenced by csv2dft_a(), and dftReadinput().

◆ dftDeleteFrameOverlap()

int dftDeleteFrameOverlap ( DFT * dft)

Correct frame start and end times if frames are slightly overlapping or have small gaps in between. Gap before the first time frame is not corrected. Large gap is not corrected and it does not lead to an error.

See also
dftFillInitialGap
Returns
If overlap is considerable (>20%), or another error is encountered, function returns a non-zero value. Otherwise 0 is returned.
Parameters
dftPointer to DFT data. Data must be sorted by increasing time. Time unit does not need to be set. Timetype must be DFT_TIME_STARTEND, i.e. both frame start and end time must be present; if not, then return value is always 0 (passed).

Definition at line 1237 of file dft.c.

1243 {
1244 int fi;
1245 double overlap, overlap_limit=0.0, flen1, flen2;
1246
1247 if(dft==NULL) return(1);
1248 if(dft->timetype!=DFT_TIME_STARTEND) return(0);
1249 for(fi=0; fi<dft->frameNr-1; fi++) {
1250 overlap=dft->x2[fi] - dft->x1[fi+1];
1251 if(overlap==0.0) continue; // no gap or overlap
1252 /* Calculate the frame length of current frame and the next frame */
1253 flen1=dft->x2[fi]-dft->x1[fi]; flen2=dft->x2[fi+1]-dft->x1[fi+1];
1254 if(flen1<0.0 || flen2<0.0) return(1);
1255 /* Set the limit */
1256 if(flen1<flen2) overlap_limit=0.2*flen1; else overlap_limit=0.2*flen2;
1257 /* Check if gap or overlap is too large to be fixed automatically */
1258 if(overlap<-overlap_limit) continue; // gap is too large, then do nothing
1259 if(overlap>overlap_limit) return(2); // overlap is too large: error
1260 /* Correct the small gap/overlap by making frame durations more similar */
1261 if(overlap>0.0) { // overlap
1262 if(flen1>flen2) dft->x2[fi]=dft->x1[fi+1]; else dft->x1[fi+1]=dft->x2[fi];
1263 } else { // gap
1264 if(flen1>flen2) dft->x1[fi+1]=dft->x2[fi]; else dft->x2[fi]=dft->x1[fi+1];
1265 }
1266 }
1267 return(0);
1268}

Referenced by dftReadModelingData().

◆ dftDeleteFrameOverlap_old()

int dftDeleteFrameOverlap_old ( DFT * dft)

Correct frame start and end times if frames are slightly overlapping or have small gaps in between. Large gap is not corrected and it does not lead to an error.

Returns
If overlap is considerable (>1 s), or another error is encountered, function returns a non-zero value. Otherwise 0 is returned.
Parameters
dftPointer to DFT data. Time unit must be set, otherwise no checking is done. Timetype must be DFT_TIME_STARTEND, i.e. both frame start and end time must be present.

Definition at line 1200 of file dft.c.

1204 {
1205 int fi;
1206 double overlap, overlap_limit=1.8, flen1, flen2;
1207
1208 if(dft==NULL) return(1);
1209 if(dft->timetype!=DFT_TIME_STARTEND) return(0);
1210 if(dft->timeunit!=TUNIT_MIN && dft->timeunit!=TUNIT_SEC) return(0);
1211 if(dft->timeunit==TUNIT_MIN) overlap_limit/=60.0;
1212 for(fi=0; fi<dft->frameNr-1; fi++) {
1213 overlap=dft->x2[fi] - dft->x1[fi+1];
1214 if(overlap==0.0) continue; // no gap or overlap
1215 else if(overlap<-overlap_limit) continue; // gap is large, then do nothing
1216 else if(overlap>overlap_limit) return(2); // overlap is large: error
1217 /* Correct the small gap/overlap by making frame durations more similar */
1218 flen1=dft->x2[fi]-dft->x1[fi]; flen2=dft->x2[fi+1]-dft->x1[fi+1];
1219 if(overlap>0.0) { // overlap
1220 if(flen1>flen2) dft->x2[fi]=dft->x1[fi+1]; else dft->x1[fi+1]=dft->x2[fi];
1221 } else { // gap
1222 if(flen1>flen2) dft->x1[fi+1]=dft->x2[fi]; else dft->x2[fi]=dft->x1[fi+1];
1223 }
1224 }
1225 return(0);
1226}

◆ dftdup()

int dftdup ( DFT * dft1,
DFT * dft2 )

Makes a duplicate of DFT structure pointed to by dft1 into dft2.

Returns
Returns 0 if ok.
Parameters
dft1Pointer to DFT struct
dft2Pointer to initiated DFT struct; any existing content of dft2 will be deleted.

Definition at line 655 of file dft.c.

661 {
662 int ri, fi, ret;
663
664 if(dft1==NULL || dft2==NULL) return 1;
665 /* Empty the new data */
666 dftEmpty(dft2);
667 /* Is that it? Is there any contents in dft1? */
668 if(dft1->voiNr==0 && dft1->frameNr==0) {
669 ret=dftCopymainhdr(dft1, dft2); return(ret);
670 }
671 /* Allocate memory for dft2 */
672 ret=dftSetmem(dft2, dft1->frameNr, dft1->voiNr); if(ret) return(ret);
673 dft2->voiNr=dft1->voiNr; dft2->frameNr=dft1->frameNr;
674 /* Copy the contents */
675 ret=dftCopymainhdr(dft1, dft2); if(ret) return(ret);
676 for(ri=0; ri<dft1->voiNr; ri++) {
677 ret=dftCopyvoihdr(dft1, ri, dft2, ri); if(ret) return(ret);
678 for(fi=0; fi<dft1->frameNr; fi++) {
679 dft2->voi[ri].y[fi]=dft1->voi[ri].y[fi];
680 dft2->voi[ri].y2[fi]=dft1->voi[ri].y2[fi];
681 dft2->voi[ri].y3[fi]=dft1->voi[ri].y3[fi];
682 }
683 }
684 for(fi=0; fi<dft1->frameNr; fi++) {
685 dft2->x[fi]=dft1->x[fi];
686 dft2->x1[fi]=dft1->x1[fi]; dft2->x2[fi]=dft1->x2[fi];
687 dft2->w[fi]=dft1->w[fi];
688 }
689 dft2->isweight=dft1->isweight;
690 return(0);
691}

Referenced by dftAddSpaceForFrames(), dftFillInitialGap(), dftReadinput(), and imgReadModelingData().

◆ dftEmpty()

void dftEmpty ( DFT * data)

Free memory allocated for DFT. All data is cleared.

Parameters
dataPointer to initiated DFT struct data

Definition at line 20 of file dft.c.

23 {
24 if(data==NULL) return;
25 if(data->_voidataNr>0) free((char*)(data->voi));
26 if(data->_dataSize>0) free((char*)(data->_data));
27 data->_dataSize=data->_voidataNr=0;
28 data->frameNr=data->voiNr=0;
29 data->studynr[0]=data->comments[0]=data->unit[0]=(char)0;
30 data->radiopharmaceutical[0]=data->isotope[0]=data->decayCorrected=(char)0;
31 data->scanStartTime[0]=data->injectionTime[0]=(char)0;
32 data->timeunit=data->timetype=0;
33}

Referenced by bfIrr2TCM(), bfRadiowater(), clusterTACs(), cptReadOne(), csv2dft_a(), csv2dft_b(), csv2dft_linkset(), csv2dft_mat(), dftAddnullframe(), dftAddSpaceForFrames(), dftAllocateWithHeader(), dftAutointerpolate(), dftDivideFrames(), dftDoubleFrames(), dftdup(), dftFillInitialGap(), dftInterpolate(), dftInterpolateForIMG(), dftInterpolateInto(), dftMeanTAC(), dftRead(), dftReadinput(), dftReadModelingData(), dftReadReference(), dftSetmem(), extrapolate_monoexp(), idwcRead(), ifRead(), img_k1_using_ki(), img_logan(), img_patlak(), imgMaskPixelTACs(), imgReadModelingData(), noiseSD4SimulationFromDFT(), plotdata_as_dft(), roikbqRead(), and simMyocDiameterCurve().

◆ dftFillInitialGap()

int dftFillInitialGap ( DFT * dft)

Check if there is a time gap between time zero and first sample time; if gap does not exist, then nothing is done; if gap exists, then gap is filled with an extra frame.

See also
dftDeleteFrameOverlap
Returns
Returns zero if successful, otherwise <>0.
Parameters
dftPointer to DFT struct

Definition at line 1385 of file dft.c.

1388 {
1389 DFT temp;
1390 int ret, ri, fi;
1391
1392 /* Check input */
1393 if(dft==NULL) return 1;
1394 if(dft->frameNr<1 || dft->voiNr<1) return 0;
1395
1396 /* Is there an initial gap? If not then we can finish here */
1397 if(dft->timetype==DFT_TIME_STARTEND) {
1398 if(dft->x1[0]<=0.0) return 0;
1399 } else {
1400 if(dft->x[0]<=0.0) return 0;
1401 }
1402
1403 /* Make a temporary storage of the data */
1404 dftInit(&temp); ret=dftdup(dft, &temp); if(ret!=0) return 10+ret;
1405 /* Delete and reallocate the original data pointer */
1406 dftEmpty(dft); ret=dftSetmem(dft, temp.frameNr+1, temp.voiNr);
1407 if(ret!=0) {
1408 dftdup(&temp, dft); dftEmpty(&temp);
1409 return 20+ret;
1410 }
1411 /* Copy data back, leaving first frame empty */
1412 ret=dftCopymainhdr(&temp, dft);
1413 if(ret!=0) {
1414 dftdup(&temp, dft); dftEmpty(&temp);
1415 return 30+ret;
1416 }
1417 dft->voiNr=temp.voiNr; dft->frameNr=1+temp.frameNr;
1418 dft->isweight=temp.isweight;
1419 strcpy(dft->comments, temp.comments);
1420 for(ri=0; ri<temp.voiNr; ri++) {
1421 ret=dftCopyvoihdr(&temp, ri, dft, ri);
1422 if(ret!=0) {
1423 dftdup(&temp, dft); dftEmpty(&temp);
1424 return 40+ret;
1425 }
1426 for(fi=0; fi<temp.frameNr; fi++) {
1427 dft->voi[ri].y[fi+1]=temp.voi[ri].y[fi];
1428 dft->voi[ri].y2[fi+1]=temp.voi[ri].y2[fi];
1429 dft->voi[ri].y3[fi+1]=temp.voi[ri].y3[fi];
1430 }
1431 /* Fill in the first frame */
1432 dft->voi[ri].y[0]=0.0;
1433 dft->voi[ri].y2[0]=0.0;
1434 dft->voi[ri].y3[0]=0.0;
1435 }
1436 for(fi=0; fi<temp.frameNr; fi++) {
1437 dft->x1[fi+1]=temp.x1[fi];
1438 dft->x2[fi+1]=temp.x2[fi];
1439 dft->x[fi+1]=temp.x[fi];
1440 dft->w[fi+1]=temp.w[fi];
1441 }
1442 dftEmpty(&temp);
1443
1444 /* Fill the first frame */
1445 dft->w[0]=1.0;
1446 if(dft->timetype==DFT_TIME_STARTEND) {
1447 dft->x1[0]=0.0;
1448 dft->x2[0]=dft->x1[1];
1449 dft->x[0]=0.5*(dft->x1[0]+dft->x2[0]);
1450 } else {
1451 dft->x1[0]=0.0;
1452 dft->x2[0]=dft->x1[1];
1453 dft->x[0]=0.0;
1454 }
1455
1456 return 0;
1457}

Referenced by dftFixPeak().

◆ dftFrametimes()

void dftFrametimes ( DFT * data)

Calculate frame mid or start and end times. Timetype is not changed.

Parameters
dataPointer to DFT struct

Definition at line 340 of file dft.c.

343 {
344 int i, j;
345 double f, fs;
346
347 if(data==NULL) return;
348 /* If data is told to contain frame start and end times, then check
349 that those really are there, or set to middle times, if necessary */
350 if(data->timetype==DFT_TIME_STARTEND) {
351 for(i=j=0; i<data->frameNr; i++) {
352 fs=data->x2[i]-data->x1[i]; if(fs>1.0E-10) {j=1; break;}
353 }
354 if(j==0) {
355 for(i=0; i<data->frameNr; i++) data->x[i]=0.5*(data->x1[i]+data->x2[i]);
357 }
358 }
359
360 /* Decide what to do, and get it done */
361 if(data->timetype==DFT_TIME_MIDDLE) {
362 /* frame start and end times from mid times */
363 /* Easy, if only one frame */
364 if(data->frameNr==1) {
365 if(data->x[0]<=0.0) {data->x1[0]=data->x[0]; data->x2[0]=0.0;}
366 else {data->x1[0]=0.0; data->x2[0]=2.0*data->x[0];}
367 return;
368 }
369 /* Fill start and end times with -999 */
370 for(i=0; i<data->frameNr; i++) data->x1[i]=data->x2[i]=-999.;
371 /* Search for sequences of nearly same frame lengths */
372 for(i=1; i<data->frameNr-1; i++) {
373 f=data->x[i]-data->x[i-1]; fs=data->x[i+1]-data->x[i];
374 if((f+fs)<=0.0 && fabs(fs-f)>=2.0) continue;
375 if((f+fs)>0.0 && (2.0*fabs(fs-f)/(f+fs))>0.1) continue;
376 //if(fabs(f-fs)>=2.0) continue;
377 f=(f+fs)/2.0;
378 data->x1[i-1]=data->x[i-1]-f/2.0; data->x2[i-1]=data->x[i-1]+f/2.0;
379 data->x1[i]=data->x[i]-f/2.0; data->x2[i]=data->x[i]+f/2.0;
380 data->x1[i+1]=data->x[i+1]-f/2.0; data->x2[i+1]=data->x[i+1]+f/2.0;
381 /* Check for negatives */
382 for(j=i-1; j<i+2; j++) {
383 if(data->x1[j]<0.0) data->x1[j]=0.0;
384 if(data->x2[j]<0.0) data->x2[j]=0.0;
385 }
386 }
387 /* If out-of-sequence frames were left out, fill those to the nearest one */
388 i=0; /* first frame */
389 if(data->x1[i]<0) {
390 if(data->x1[i+1]>0) data->x2[i]=data->x1[i+1];
391 else data->x2[i]=(data->x[i+1]+data->x[i])/2.0;
392 data->x1[i]=2.0*data->x[i]-data->x2[i];
393 }
394 i=data->frameNr-1; /* last frame */
395 if(data->x1[i]<0) {
396 if(data->x2[i-1]>0) data->x1[i]=data->x2[i-1];
397 else data->x1[i]=(data->x[i-1]+data->x[i])/2.0;
398 data->x2[i]=2.0*data->x[i]-data->x1[i];
399 }
400 /* other frames */
401 for(i=1; i<data->frameNr-1; i++) if(data->x1[i]<0.0) {
402 /* which frame is nearest? */
403 if(data->x[i]-data->x[i-1] <= data->x[i+1]-data->x[i]) { /* last one */
404 if(data->x2[i-1]>0) data->x1[i]=data->x2[i-1];
405 else data->x1[i]=(data->x[i-1]+data->x[i])/2.0;
406 data->x2[i]=2.*data->x[i]-data->x1[i];
407 } else { /* next one */
408 if(data->x1[i+1]>0) data->x2[i]=data->x1[i+1];
409 else data->x2[i]=(data->x[i+1]+data->x[i])/2.0;
410 data->x1[i]=2.0*data->x[i]-data->x2[i];
411 }
412 }
413 /* Check for negatives */
414 for(i=0; i<data->frameNr; i++) {
415 if(data->x1[i]<0.0) data->x1[i]=0.0;
416 if(data->x2[i]<0.0) data->x2[i]=data->x1[i];
417 }
418 /* Check for overlapping and very small gaps */
419 for(i=1; i<data->frameNr; i++) {
420 f=data->x1[i]-data->x2[i-1];
421 if(f<0.0) {
422 if(data->x[i]>data->x2[i-1]) data->x1[i]=data->x2[i-1];
423 else if(data->x[i-1]<data->x1[i]) data->x2[i-1]=data->x1[i];
424 else data->x1[i]=data->x2[i-1]=(data->x[i]+data->x[i-1])/2.0;
425 } else if(f>0.0 && f<1.0) {
426 data->x1[i]=data->x2[i-1]=(data->x1[i]+data->x2[i-1])/2.0;
427 }
428 }
429 } else if(data->timetype==DFT_TIME_STARTEND) {
430 /* mid times from frame start and end times */
431 for(i=0; i<data->frameNr; i++) data->x[i]=0.5*(data->x1[i]+data->x2[i]);
432 } else if(data->timetype==DFT_TIME_START) {
433 /* frame start times -> end and mid times */
434 for(i=0; i<data->frameNr-1; i++) data->x2[i]=data->x1[i+1];
435 data->x2[data->frameNr-1]=data->x1[data->frameNr-1]+
436 (data->x2[data->frameNr-2]-data->x1[data->frameNr-2]);
437 for(i=0; i<data->frameNr; i++) data->x[i]=0.5*(data->x1[i]+data->x2[i]);
438 } else if(data->timetype==DFT_TIME_END) {
439 /* frame end times -> start and mid times */
440 data->x1[0]=0.0;
441 for(i=1; i<data->frameNr; i++) data->x1[i]=data->x2[i-1];
442 for(i=0; i<data->frameNr; i++) data->x[i]=0.5*(data->x1[i]+data->x2[i]);
443 }
444
445 return;
446}
#define DFT_TIME_MIDDLE
#define DFT_TIME_END
#define DFT_TIME_START

Referenced by csv2dft_a(), dftRead(), and idwcRead().

◆ dftInit()

void dftInit ( DFT * data)

Initiate DFT structure. This should be called once before use.

Parameters
dataPointer to initiated DFT struct data

Definition at line 38 of file dft.c.

41 {
42 if(data==NULL) return;
43 memset(data, 0, sizeof(DFT));
44 data->_voidataNr=data->_dataSize=0;
45 data->frameNr=data->voiNr=0;
46 data->studynr[0]=data->comments[0]=data->unit[0]=(char)0;
47 data->radiopharmaceutical[0]=data->isotope[0]=data->decayCorrected=(char)0;
48 data->scanStartTime[0]=data->injectionTime[0]=(char)0;
49 data->timeunit=data->timetype=data->isweight=0;
50}

Referenced by dftAddnullframe(), dftAddSpaceForFrames(), dftFillInitialGap(), dftReadinput(), dftReadModelingData(), dftReadReference(), img_k1_using_ki(), img_logan(), img_patlak(), imgReadModelingData(), noiseSD4SimulationFromDFT(), and plotdata_as_dft().

◆ dftMaxY()

int dftMaxY ( DFT * dft,
double t1,
double t2,
double * miny,
double * maxy )

Search the min and max values of DFT TAC data inside specified time range.

Data may contain NA's.

Returns
Returns 0 if successful.
Parameters
dftPointer to the DFT TAC data to search
t1Start time
t2End time
minyPointer to min Y; set to NULL if not needed
maxyPointer to max Y; set to NULL if not needed

Definition at line 1090 of file dft.c.

1101 {
1102 int ri, fi;
1103 double x1, x2, y1, y2;
1104
1105 if(dft==NULL) return(1);
1106 y1=y2=nan("");
1107 for(fi=0; fi<dft->frameNr; fi++) {
1108 if(dft->timetype==DFT_TIME_STARTEND) {
1109 if(!isfinite(dft->x1[fi]) || !isfinite(dft->x2[fi])) continue;
1110 x1=dft->x1[fi]; x2=dft->x2[fi];
1111 } else {
1112 if(!isfinite(dft->x[fi])) continue;
1113 x1=x2=dft->x[fi];
1114 }
1115 if(x2<t1 || x1>t2) continue; // outside time range
1116 for(ri=0; ri<dft->voiNr; ri++) if(!isnan(dft->voi[ri].y[fi])) {
1117 if(isnan(y1) || y1>dft->voi[ri].y[fi]) y1=dft->voi[ri].y[fi];
1118 if(isnan(y2) || y2<dft->voi[ri].y[fi]) y2=dft->voi[ri].y[fi];
1119 }
1120 }
1121 if(miny!=NULL) {if(isnan(y1)) return(5); else *miny=y1;}
1122 if(maxy!=NULL) {if(isnan(y2)) return(6); else *maxy=y2;}
1123 return(0);
1124}

Referenced by plot_fitrange_svg().

◆ dftMeanTAC()

int dftMeanTAC ( DFT * dft,
DFT * mean )

Calculates mean TAC of all TACs in DFT struct. Mean is NOT weighted by VOI sizes. Also SD and CV for each sample time are calculated.

Returns
Returns 0 if successful.
Parameters
dftPointer to TAC data from which mean TAC is calculated; missing values (NaN) are allowed
meanPointer to initialized or pre-allocated DFT struct in where mean, SD, and CV will be written in y, y2, and y3, respectively.

Definition at line 1580 of file dft.c.

1587 {
1588 int ret, fi, ri, n;
1589 double sum, ssum;
1590
1591 if(dft==NULL || mean==NULL) return(1);
1592 if(dft->voiNr<1 || dft->frameNr<1) return(2);
1593
1594 /* Allocate memory for mean data, if necessary */
1595 if(mean->voiNr<1 || mean->frameNr!=dft->frameNr) {
1596 dftEmpty(mean); ret=dftAllocateWithHeader(mean, dft->frameNr, 1, dft);
1597 if(ret!=0) return(100+ret);
1598 }
1599 strcpy(mean->voi[0].name, "Mean");
1600 strcpy(mean->voi[0].voiname, mean->voi[0].name);
1601
1602 /* Calculate the mean TAC */
1603 ret=0;
1604 for(fi=0; fi<dft->frameNr; fi++) {
1605 sum=ssum=0.0; n=0;
1606 for(ri=0; ri<dft->voiNr; ri++) if(!isnan(dft->voi[ri].y[fi])) {
1607 sum+=dft->voi[ri].y[fi];
1608 ssum+=dft->voi[ri].y[fi]*dft->voi[ri].y[fi];
1609 n++;
1610 }
1611 if(n==0) {
1612 mean->voi[0].y[fi]=mean->voi[0].y2[fi]=mean->voi[0].y3[fi]=nan("");
1613 } else {
1614 mean->voi[0].y[fi]=sum/(double)n;
1615 if(n==1) {
1616 mean->voi[0].y2[fi]=mean->voi[0].y3[fi]=0.0;
1617 } else {
1618 mean->voi[0].y2[fi]=sqrt((ssum-sum*sum/(double)n)/(double)(n-1));
1619 if(fabs(mean->voi[0].y[fi])>1.0E-25)
1620 mean->voi[0].y3[fi]=fabs(mean->voi[0].y2[fi]/mean->voi[0].y[fi]);
1621 else
1622 mean->voi[0].y3[fi]=0.0;
1623 }
1624 }
1625 if(n>0) ret++;
1626 }
1627 /* Check that at least half of frames contained acceptable data */
1628 if(2*ret<dft->frameNr) {dftEmpty(mean); return(10);}
1629
1630 return(0);
1631}
int dftAllocateWithHeader(DFT *dft, int frameNr, int voiNr, DFT *dft_from)
Definition dft.c:702
int mean(double *x, double *y, int nr, double *xmean, double *xsd, double *ymean, double *ysd)
Definition pearson.c:341

Referenced by noiseSD4SimulationFromDFT().

◆ dftMinMax()

int dftMinMax ( DFT * dft,
double * minx,
double * maxx,
double * miny,
double * maxy )

Search the min and max values of DFT TAC data. Data may contain NA's.

Note that minx and maxx are the smallest and highest x values in data, not the x values at y minimum and maximum; use dftMinMaxTAC() for that.

See also
dftMinMaxTAC, dftRobustMinMaxTAC
Returns
Returns 0 if successful.
Parameters
dftPointer to the DFT TAC data to search
minxPointer to min X; set to NULL if not needed
maxxPointer to max X; set to NULL if not needed
minyPointer to min Y; set to NULL if not needed
maxyPointer to max Y; set to NULL if not needed

Definition at line 974 of file dft.c.

985 {
986 int ri, fi, n;
987 double x1, x2, y1, y2;
988
989 if(dft==NULL) return(1);
990 x1=x2=y1=y2=nan("");
991 for(fi=0; fi<dft->frameNr; fi++) {
992 for(ri=0, n=0; ri<dft->voiNr; ri++) if(!isnan(dft->voi[ri].y[fi])) {
993 if(isnan(y1) || y1>dft->voi[ri].y[fi]) y1=dft->voi[ri].y[fi];
994 if(isnan(y2) || y2<dft->voi[ri].y[fi]) y2=dft->voi[ri].y[fi];
995 n++;
996 }
997 if(n==0) continue; // no true y values, thus do not use x either
998 if(dft->timetype==DFT_TIME_STARTEND) {
999 if(!isnan(dft->x1[fi])) {
1000 if(isnan(x1) || x1>dft->x1[fi]) x1=dft->x1[fi];
1001 }
1002 if(!isnan(dft->x2[fi])) {
1003 if(isnan(x2) || x2<dft->x2[fi]) x2=dft->x2[fi];
1004 }
1005 } else if(!isnan(dft->x[fi])) {
1006 if(isnan(x1) || x1>dft->x[fi]) x1=dft->x[fi];
1007 if(isnan(x2) || x2<dft->x[fi]) x2=dft->x[fi];
1008 }
1009 }
1010 if(minx!=NULL) {if(isnan(x1)) return(3); else *minx=x1;}
1011 if(maxx!=NULL) {if(isnan(x2)) return(4); else *maxx=x2;}
1012 if(miny!=NULL) {if(isnan(y1)) return(5); else *miny=y1;}
1013 if(maxy!=NULL) {if(isnan(y2)) return(6); else *maxy=y2;}
1014 return(0);
1015}

Referenced by plot_fit_svg(), and plot_fitrange_svg().

◆ dftMinMaxTAC()

int dftMinMaxTAC ( DFT * dft,
int tacindex,
double * minx,
double * maxx,
double * miny,
double * maxy,
int * mini,
int * maxi,
int * mins,
int * maxs )

Search the min and max values of DFT TAC data. Data may contain NA's. This is not a replacement of dftMinMax() which is needed e.g. in plotting functions.

See also
dftMinMax, dftRobustMinMaxTAC
Returns
Returns 0 if successful.
Parameters
dftPointer to the DFT TAC data to search
tacindexIndex of the only TAC which is searched for min and max; <0 if all
minxPointer to X at TAC min; set to NULL if not needed
maxxPointer to X at TAC max; set to NULL if not needed
minyPointer to min Y; set to NULL if not needed
maxyPointer to max Y; set to NULL if not needed
miniIndex of min TAC; set to NULL if not needed
maxiIndex of max TAC; set to NULL if not needed
minsIndex of min sample; set to NULL if not needed
maxsIndex of max sample; set to NULL if not needed

Definition at line 1024 of file dft.c.

1045 {
1046 int ri, fi, i1, i2, s1, s2;
1047 double x, x1, x2, y1, y2;
1048
1049 if(dft==NULL) return(1);
1050 if(tacindex>=dft->voiNr) return(2);
1051 if(dft->voiNr<1 || dft->frameNr<1) return(3);
1052
1053 x1=x2=y1=y2=nan(""); i1=i2=s1=s2=0;
1054 for(fi=0; fi<dft->frameNr; fi++) {
1055 if(dft->timetype==DFT_TIME_STARTEND) {
1056 if(isnan(dft->x1[fi])) continue;
1057 if(isnan(dft->x2[fi])) continue;
1058 x=0.5*(dft->x1[fi]+dft->x2[fi]);
1059 } else {
1060 if(isnan(dft->x[fi])) continue;
1061 x=dft->x[fi];
1062 }
1063 for(ri=0; ri<dft->voiNr; ri++) if(!isnan(dft->voi[ri].y[fi])) {
1064 if(tacindex>=0 && ri!=tacindex) continue;
1065 if(isnan(y1) || y1>dft->voi[ri].y[fi]) {
1066 y1=dft->voi[ri].y[fi]; i1=ri; x1=x; s1=fi;}
1067 if(isnan(y2) || y2<dft->voi[ri].y[fi]) {
1068 y2=dft->voi[ri].y[fi]; i2=ri; x2=x; s2=fi;}
1069 }
1070 }
1071 if(minx!=NULL) {if(isnan(x1)) return(11); else *minx=x1;}
1072 if(maxx!=NULL) {if(isnan(x2)) return(12); else *maxx=x2;}
1073 if(miny!=NULL) {if(isnan(y1)) return(13); else *miny=y1;}
1074 if(maxy!=NULL) {if(isnan(y2)) return(14); else *maxy=y2;}
1075 if(mini!=NULL) {if(isnan(y1)) return(13); else *mini=i1;}
1076 if(maxi!=NULL) {if(isnan(y2)) return(14); else *maxi=i2;}
1077 if(mins!=NULL) {if(isnan(y1)) return(13); else *mins=s1;}
1078 if(maxs!=NULL) {if(isnan(y2)) return(14); else *maxs=s2;}
1079 return(0);
1080}

Referenced by dftFixPeak(), and dftVerifyPeak().

◆ dftMovevoi()

int dftMovevoi ( DFT * dft,
int from,
int to )

Move VOI in DFT structure from one position to another.

Parameters
dftPointer to DFT struct
fromTAC index
toTAC index

Definition at line 508 of file dft.c.

515 {
516 int ri;
517 size_t voisize;
518 Voi voi;
519
520 if(dft==NULL || from<0 || to<0) return(1);
521 if(from+1>dft->_voidataNr || to+1>dft->_voidataNr) return(2);
522 if(from==to) return(0);
523 voisize=sizeof(Voi);
524 memcpy(&voi, dft->voi+from, voisize);
525 if(from>to) for(ri=from; ri>to; ri--)
526 memcpy(dft->voi+ri, dft->voi+(ri-1), voisize);
527 else for(ri=from; ri<to; ri++)
528 memcpy(dft->voi+ri, dft->voi+(ri+1), voisize);
529 memcpy(dft->voi+ri, &voi, voisize);
530 return(0);
531}

Referenced by dftDelete(), and dftReadinput().

◆ dftNAfill()

int dftNAfill ( DFT * dft)

Replace NA's in basic DFT data with interpolated values. If extrapolation is necessary, then the values (0,0) and (Infinity,last measured) are assumed.

Returns
Returns 0, if NA's could be filled with sensible values.
Parameters
dftPointer to DFT struct

Definition at line 930 of file dft.c.

933 {
934 int ri, fi, fj;
935 double x1, x2, y1, y2, x, y;
936
937 if(dft==NULL || dft->voiNr<1 || dft->frameNr<1) return(1);
938 for(ri=0; ri<dft->voiNr; ri++) for(fi=0; fi<dft->frameNr; fi++) {
939 if(isnan(dft->x[fi])) return(2);
940 if(isnan(dft->voi[ri].y[fi])) {
941 /* NA's before zero time are always replaced with 0 */
942 if(dft->x[fi]<0.0) {dft->voi[ri].y[fi]=0.0; continue;}
943 x=dft->x[fi];
944 /* Get the previous data that is not NA */
945 for(x1=y1=nan(""), fj=fi-1; fj>=0; fj--) if(!isnan(dft->voi[ri].y[fj])) {
946 x1=dft->x[fj]; y1=dft->voi[ri].y[fj]; break;
947 }
948 if(isnan(x1) || isnan(y1)) x1=y1=0.0;
949 /* Get the following data that is not NA */
950 for(x2=y2=nan(""), fj=fi+1; fj<dft->frameNr; fj++) if(!isnan(dft->voi[ri].y[fj])) {
951 x2=dft->x[fj]; y2=dft->voi[ri].y[fj]; break;
952 }
953 if(isnan(x2) || isnan(y2)) for(fj=fi-1; fj>=0; fj--) if(!isnan(dft->voi[ri].y[fj])) {
954 x2=dft->x[fj]; y2=dft->voi[ri].y[fj]; break;
955 }
956 if(isnan(x2) || isnan(y2)) return(2);
957 /* Calculate new value */
958 if(x2==x1) y=0.5*(y1+y2); else y=y2-(x2-x)*(y2-y1)/(x2-x1);
959 dft->voi[ri].y[fi]=y;
960 }
961 }
962 return(0);
963}

◆ dftOverflow()

int dftOverflow ( DFT * data)

Check for overflows in data structure. Returns 0, if ok.

Parameters
dataPointer to DFT struct

Definition at line 451 of file dft.c.

454 {
455 int i;
456
457 if(data==NULL || data->frameNr<1 || data->voiNr<1) return 0;
458 if(data->x[data->frameNr]!=0.0) return 1;
459 if(data->x1[data->frameNr]!=0.0) return 2;
460 if(data->x2[data->frameNr]!=0.0) return 3;
461 for(i=0; i<data->voiNr; i++) {
462 if(data->voi[i].y[data->frameNr]!=0.0) return 4;
463 if(data->voi[i].y2[data->frameNr]!=0.0) return 5;
464 if(data->voi[i].y3[data->frameNr]!=0.0) return 6;
465 }
466 return 0;
467}

◆ dftRemoveTimeRange()

int dftRemoveTimeRange ( DFT * dft,
double startT,
double endT )

Extract specified sample time interval from TAC data.

Returns
Returns 0 when successful, otherwise <>0.
Parameters
dftPointer to DFT struct from where samples outside time range will be removed. Data must be sorted to increasing frame times before calling this function.
startTStart time of data that is preserved (in same units as in DFT)
endTEnd time of data that is preserved (in same units as in DFT)

Definition at line 1275 of file dft.c.

1284 {
1285 int i, j, voi, first, origNr;
1286
1287 if(dft==NULL || dft->frameNr<1 || dft->voiNr<1) return(1);
1288 if(endT<startT) return(2);
1289 if(startT<=dft->x[0] && endT>=dft->x[dft->frameNr-1]) return(0);
1290 origNr=dft->frameNr;
1291
1292 /* Delete end frames which are collected later than the end time */
1293 for(j=dft->frameNr-1; j>=0; j--) if(dft->x[j]<=endT) break;
1294 dft->frameNr=j+1;
1295
1296 /* Find the first frame that has been collected later than start time */
1297 for(j=0, first=-1; j<dft->frameNr; j++)
1298 if(dft->x[j]>=startT) {first=j; break;}
1299 if(first<0) {
1300 dft->frameNr=origNr; // undelete the end data
1301 return(3);
1302 }
1303
1304 /* Delete first frames */
1305 if(first>0) for(j=first, i=0; j<dft->frameNr; j++, i++) {
1306 dft->x[i]=dft->x[j]; dft->x1[i]=dft->x1[j]; dft->x2[i]=dft->x2[j];
1307 dft->w[i]=dft->w[j];
1308 for(voi=0; voi<dft->voiNr; voi++) {
1309 dft->voi[voi].y[i]=dft->voi[voi].y[j];
1310 dft->voi[voi].y2[i]=dft->voi[voi].y2[j];
1311 dft->voi[voi].y3[i]=dft->voi[voi].y3[j];
1312 }
1313 }
1314 dft->frameNr-=first;
1315
1316 return(0);
1317}

◆ dftRNameSimplify()

void dftRNameSimplify ( DFT * dft,
int hemisphere,
int place )

Simplify TAC names in DFT struct: empty hemisphere and/or place field in case those are the same in all TACs.

Parameters
dftPointer to DFT struct
hemisphereIs hemisphere field simplified (1) or not (0), when possible
placeIs place field simplified (1) or not (0), when possible

Definition at line 1534 of file dft.c.

1541 {
1542 int ri, n;
1543
1544 if(dft==NULL || dft->voiNr<1) return;
1545 if(hemisphere==0 && place==0) return;
1546
1547 /* Check if all TACs have the same field content: if yes, then
1548 delete the field content */
1549 if(hemisphere!=0) {
1550 for(ri=n=1; ri<dft->voiNr; ri++)
1551 if(strcasecmp(dft->voi[0].hemisphere, dft->voi[ri].hemisphere)==0) n++;
1552 if(n==dft->voiNr)
1553 for(ri=0; ri<dft->voiNr; ri++)
1554 strcpy(dft->voi[ri].hemisphere, "");
1555 }
1556 if(place!=0) {
1557 for(ri=n=1; ri<dft->voiNr; ri++)
1558 if(strcasecmp(dft->voi[0].place, dft->voi[ri].place)==0) n++;
1559 if(n==dft->voiNr)
1560 for(ri=0; ri<dft->voiNr; ri++)
1561 strcpy(dft->voi[ri].place, "");
1562 }
1563
1564 /* Construct combined TAC names */
1565 for(ri=0; ri<dft->voiNr; ri++)
1567 dft->voi[ri].voiname, dft->voi[ri].hemisphere,
1568 dft->voi[ri].place, '_');
1569 /* Ready */
1570 return;
1571}
int rnameCatenate(char *rname, int max_rname_len, char *name1, char *name2, char *name3, char space)
Definition rname.c:189
#define MAX_REGIONNAME_LEN
Definition libtpcmisc.h:154

◆ dftSelect()

int dftSelect ( DFT * data,
char * name )

Select VOIs (sets sw=1), whose names are matching specified string. If no string is specified, then all VOIs are selected. This function is to replaced by dftSelectRegions().

Returns
Returns the number of matches, or <0, if an error occurred.
Parameters
dataPointer to DFT struct
nameString to search in TAC name fields

Definition at line 239 of file dft.c.

244 {
245 unsigned int i, j, n;
246 char *p, n1[128], n2[128], n3[128], tmp[128], sname[1024];
247
248 if(data==NULL) return -1;
249 /* Select all, if no string was specified */
250 if(name==NULL || strlen(name)==0) {
251 for(i=0; i<(unsigned int)data->voiNr; i++) data->voi[i].sw=1;
252 return data->voiNr;
253 }
254 /* Make a copy of 'name' and use it */
255 strcpy(sname, name);
256 /* Check if string contains several substrings (hemisphere and place) */
257 n1[0]=n2[0]=n3[0]=(char)0;
258 p=strtok(sname, " ,;\n\t|"); if(p!=NULL) strcpy(n1, p); else return -1;
259 p=strtok(NULL, " ,;\n\t|"); if(p!=NULL) {
260 strcpy(n2, p); p=strtok(NULL, " ,;\n\t|"); if(p!=NULL) strcpy(n3, p);}
261 /* Convert strings to lowercase */
262 for(i=0; i<strlen(n1); i++) n1[i]=tolower(n1[i]);
263 for(i=0; i<strlen(n2); i++) n2[i]=tolower(n2[i]);
264 for(i=0; i<strlen(n3); i++) n3[i]=tolower(n3[i]);
265 /* Search through the data */
266 for(i=0, n=0; i<(unsigned int)data->voiNr; i++) {
267 data->voi[i].sw=0;
268 snprintf(tmp, 128, "%s%s%s", data->voi[i].voiname, data->voi[i].hemisphere,
269 data->voi[i].place);
270 for(j=0; j<strlen(tmp); j++) tmp[j]=tolower(tmp[j]);
271 if(strstr(tmp, n1)==NULL) continue;
272 if(n2[0] && strstr(tmp, n2)==NULL) continue;
273 if(n3[0] && strstr(tmp, n3)==NULL) continue;
274 data->voi[i].sw=1; n++;
275 }
276 return n;
277}

◆ dftSelectBestReference()

int dftSelectBestReference ( DFT * dft)

Select the best reference region in case that several were found with dftSelectRegions.

Returns
Returns the index of best region, or <0 in case of an error.
Parameters
dftPointer to DFT struct, after using dftSelectRegions()

Definition at line 314 of file dft.c.

317 {
318 int ri, len, min_len, i;
319
320 if(dft==NULL || dft->voiNr<1) return -1;
321 for(ri=0, i=-1, min_len=9999; ri<dft->voiNr; ri++) if(dft->voi[ri].sw) {
322 len=strlen(dft->voi[ri].voiname);
323 if(strcmp(dft->voi[ri].hemisphere, ".")!=0 &&
324 strcasecmp(dft->voi[ri].hemisphere, "AVG")!=0 &&
325 strcasecmp(dft->voi[ri].hemisphere, "MEAN")!=0)
326 len+=1+strlen(dft->voi[ri].hemisphere);
327 if(strcmp(dft->voi[ri].place, ".")!=0 &&
328 strcasecmp(dft->voi[ri].place, "ALL")!=0 &&
329 strcasecmp(dft->voi[ri].place, "AVG")!=0 &&
330 strcasecmp(dft->voi[ri].place, "MEAN")!=0)
331 len+=1+strlen(dft->voi[ri].place);
332 if(len<min_len) {min_len=len; i=ri;}
333 }
334 if(i<0) return -2; else return i;
335}

Referenced by dftReadinput(), and dftReadReference().

◆ dftSelectRegions()

int dftSelectRegions ( DFT * dft,
char * region_name,
int reset )

Select the VOIs that have matching region name or number. Sets sw=1 or sw=0. This function will replace dftSelect().

Returns
Returns the number of selected VOIs, or <0 in case of an error.
Parameters
dftPointer to DFT data where VOIs are selected
region_nameName or VOI number which is searched
reset1=Non-matching VOIs are deselected, 0=Old selections are preserved

Definition at line 285 of file dft.c.

292 {
293 int ri, match_nr=0;
294
295 /* Check the input */
296 if(dft==NULL || dft->voiNr<1 || strlen(region_name)<1) return(-1);
297 /* Reset all selections if required */
298 if(reset!=0) for(ri=0; ri<dft->voiNr; ri++) dft->voi[ri].sw=0;
299 /* Check each VOI */
300 for(ri=0; ri<dft->voiNr; ri++) {
301 if(rnameMatch(dft->voi[ri].name, ri+1, region_name)!=0) {
302 dft->voi[ri].sw=1; match_nr++;
303 }
304 }
305 return(match_nr);
306}
int rnameMatch(char *rname, int rnr, char *test_str)
Definition rname.c:144

Referenced by dftReadinput(), and dftReadReference().

◆ dftSetComments()

void dftSetComments ( DFT * dft)

Overwrites DFT comments with information in current DFT header.

If DFT format specifies that titles are to be saved, that information is not included in comments.

Parameters
dftPointer to DFT struct

Definition at line 1326 of file dft.c.

1329 {
1330 char tmp[512];
1331
1332 if(dft==NULL) return;
1333 strcpy(dft->comments, "");
1334 /* Write in comments the information that will not be included in titles */
1335 if(dft->scanStartTime[0]) {
1336 sprintf(tmp, "# scan_start_time := %s\n", dft->scanStartTime);
1337 strcat(dft->comments, tmp);
1338 }
1339 if(dft->injectionTime[0]) {
1340 sprintf(tmp, "# injection_time := %s\n", dft->injectionTime);
1341 strcat(dft->comments, tmp);
1342 }
1343 strcpy(tmp, "# decay_correction := ");
1344 if(dft->decayCorrected==DFT_DECAY_CORRECTED) strcat(tmp, "Yes\n");
1345 else if(dft->decayCorrected==DFT_DECAY_NOTCORRECTED) strcat(tmp, "No\n");
1346 else strcat(tmp, "Unknown\n");
1347 if(dft->decayCorrected!=DFT_DECAY_UNKNOWN) strcat(dft->comments, tmp);
1348 if(dft->isotope[0]) {
1349 sprintf(tmp, "# isotope := %s\n", dft->isotope);
1350 strcat(dft->comments, tmp);
1351 }
1352 if(dft->radiopharmaceutical[0]) {
1353 sprintf(tmp, "# radiopharmaceutical := %s\n", dft->radiopharmaceutical);
1354 strcat(dft->comments, tmp);
1355 }
1356 /* If titles are set to be saved, then there's no need to put more in comments */
1357 if(dft->_type==DFT_FORMAT_STANDARD || dft->_type==DFT_FORMAT_PMOD) return;
1358
1359 /* Ok then, lets write even title information in comments */
1360 if(dft->studynr[0]) {
1361 sprintf(tmp, "# study_number := %s\n", dft->studynr);
1362 strcat(dft->comments, tmp);
1363 }
1364 if(dft->timeunit!=TUNIT_UNKNOWN) {
1365 sprintf(tmp, "# timeunit := %s\n", petTunit(dft->timeunit) );
1366 strcat(dft->comments, tmp);
1367 }
1368 if(petCunitId(dft->unit)!=CUNIT_UNKNOWN) {
1369 sprintf(tmp, "# unit := %s\n", dft->unit );
1370 strcat(dft->comments, tmp);
1371 }
1372 // Region names and volumes are not saved in comments because of space limit
1373
1374 return;
1375}
#define DFT_DECAY_NOTCORRECTED
#define DFT_FORMAT_PMOD
#define DFT_FORMAT_STANDARD
#define DFT_DECAY_CORRECTED
int petCunitId(const char *unit)
Definition petunits.c:74
char * petTunit(int tunit)
Definition petunits.c:226

Referenced by dftRead().

◆ dftSetmem()

int dftSetmem ( DFT * data,
int frameNr,
int voiNr )

Allocate memory for DFT data and sets data pointers.

Returns
Returns <> 0 in case of an error.
Parameters
dataPointer to initiated DFT structure data; any old contents are deleted.
frameNrNr of time frames (samples) to allocate
voiNrNr of concentration arrays (regional TACs) to allocate

Definition at line 57 of file dft.c.

64 {
65 int i, n;
66 double *d;
67
68
69 if(data==NULL) return 1;
70 /* Clear previous data */
71 dftEmpty(data);
72
73 /* Allocate memory for curves */
74 data->voi=(Voi*)calloc(voiNr, sizeof(Voi));
75 if(data->voi==NULL) return 1;
76 data->_voidataNr=voiNr;
77
78 /* Allocate memory for frames */
79 /* For 3 axes, weights, and for curves (3 for each VOI) */
80 /* And one extra 'frame' for overflow testing */
81 n=(frameNr+1)*(3+1+3*voiNr);
82 data->_data=(double*)calloc(n, sizeof(double));
83 if(data->_data==NULL) return 1;
84 data->_dataSize=n;
85
86 /* Set pointers for curve data */
87 d=data->_data; data->x = d;
88 d += frameNr + 1; data->x1 = d;
89 d += frameNr + 1; data->x2 = d;
90 d += frameNr + 1; data->w = d;
91 for(i=0; i<voiNr; i++) {
92 d += frameNr + 1; data->voi[i].y = d;
93 d += frameNr + 1; data->voi[i].y2 = d;
94 d += frameNr + 1; data->voi[i].y3 = d;
95 }
96
97 return 0;
98}

Referenced by bf_srtm(), bfIrr2TCM(), bfRadiowater(), clusterTACs(), cptReadOne(), csv2dft_a(), csv2dft_b(), csv2dft_linkset(), csv2dft_mat(), dftAddnullframe(), dftAddSpaceForFrames(), dftAllocateWithHeader(), dftAllocateWithIMG(), dftAutointerpolate(), dftDivideFrames(), dftDoubleFrames(), dftdup(), dftFillInitialGap(), dftInterpolate(), dftRead(), extrapolate_monoexp(), idwcRead(), ifRead(), img_k1_using_ki(), img_logan(), img_patlak(), plotdata_as_dft(), roikbqRead(), sif2dft(), simMyocDiameterCurve(), tsvRead(), and xelRead().

◆ dftSort()

int dftSort ( DFT * data)

Sort DFT regions in alphabetical order by their name.

Returns
Returns <> 0 in case of an error.
Parameters
dataPointer to DFT struct

Definition at line 845 of file dft.c.

848 {
849 if(data==NULL) return(1);
850 if(data->voiNr<=1) return(0);
851 qsort(data->voi, data->voiNr, sizeof(Voi), dftQSortName);
852 return(0);
853}

◆ dftSortByFrame()

int dftSortByFrame ( DFT * dft)

Sorts TAC frames by increasing sample time.

Returns
Returns 0 if ok.
Parameters
dftPointer to DFT struct

Definition at line 1169 of file dft.c.

1172 {
1173 int ri, fi, fj;
1174 double d;
1175
1176 if(dft==NULL || dft->voiNr<1 || dft->frameNr<1) return(1);
1177 for(fi=0; fi<dft->frameNr-1; fi++) for(fj=fi+1; fj<dft->frameNr; fj++) {
1178 if(dft->x[fj]>=dft->x[fi]) continue;
1179 d=dft->x[fi]; dft->x[fi]=dft->x[fj]; dft->x[fj]=d;
1180 d=dft->x1[fi]; dft->x1[fi]=dft->x1[fj]; dft->x1[fj]=d;
1181 d=dft->x2[fi]; dft->x2[fi]=dft->x2[fj]; dft->x2[fj]=d;
1182 d=dft->w[fi]; dft->w[fi]=dft->w[fj]; dft->w[fj]=d;
1183 for(ri=0; ri<dft->voiNr; ri++) {
1184 d=dft->voi[ri].y[fi]; dft->voi[ri].y[fi]=dft->voi[ri].y[fj]; dft->voi[ri].y[fj]=d;
1185 d=dft->voi[ri].y2[fi]; dft->voi[ri].y2[fi]=dft->voi[ri].y2[fj]; dft->voi[ri].y2[fj]=d;
1186 d=dft->voi[ri].y3[fi]; dft->voi[ri].y3[fi]=dft->voi[ri].y3[fj]; dft->voi[ri].y3[fj]=d;
1187 }
1188 }
1189 return(0);
1190}

Referenced by dftReadModelingData(), and dftVerifyPeak().

◆ dftSortPlane()

int dftSortPlane ( DFT * data)

Sort DFT regions in alphabetical order by their plane.

Returns
Returns <> 0 in case of an error.
Parameters
dataPointer to DFT struct

Definition at line 875 of file dft.c.

878 {
879 if(data==NULL) return(1);
880 if(data->voiNr<=1) return(0);
881 qsort(data->voi, data->voiNr, sizeof(Voi), dftQSortPlane);
882 return(0);
883}

Referenced by cptWrite().

◆ dftValidNr()

int dftValidNr ( DFT * dft,
double tstart,
double tstop,
int index )

Determine the nr of valid data points inside the given time range.

Returns
The number of valid data points.
Parameters
dftPointer to DFT struct
tstartTime range start
tstopTime range stop
indexIndex of TAC to use; enter <0 to use all, in which case the minimum number of valid points is returned.

Definition at line 1638 of file dft.c.

1648 {
1649 if(dft==NULL || dft->voiNr<0 || dft->frameNr<0) return(0);
1650 if(index>dft->voiNr-1) return(0);
1651 if(index>=0) { // TAC index given
1652 int n=0;
1653 double x;
1654 for(int i=0; i<dft->frameNr; i++) {
1655 if(dft->timetype!=DFT_TIME_STARTEND) x=dft->x[i];
1656 else x=0.5*(dft->x1[i]+dft->x2[i]);
1657 if(isnan(x) || !isfinite(x)) continue;
1658 if(x<tstart || x>tstop) continue;
1659 if(isnan(dft->voi[index].y[i]) || !isfinite(dft->voi[index].y[i]))
1660 continue;
1661 n++;
1662 }
1663 return(n);
1664 }
1665 /* Get min nr of all TACs */
1666 int n=0, minn=0;
1667 minn=dftValidNr(dft, tstart, tstop, 0);
1668 for(int j=1; j<dft->voiNr; j++) {
1669 n=dftValidNr(dft, tstart, tstop, j);
1670 if(n<minn) minn=n;
1671 }
1672 return(minn);
1673}
int dftValidNr(DFT *dft, double tstart, double tstop, int index)
Definition dft.c:1638

Referenced by dftValidNr().

Variable Documentation

◆ dfterrmsg

char dfterrmsg[64]