50 int ri, n, ret, ftype=0;
54 if(verbose>0) printf(
"dftReadinput(inp, tis, %s, type, ti1, ti2, %d, status, %d)\n",
55 filename, verifypeak, verbose);
56 if(filetype!=NULL) *filetype=0;
59 if(input==NULL || tissue==NULL || filename==NULL) {
60 if(status!=NULL) strcpy(status,
"program error");
64 if(status!=NULL) strcpy(status,
"no pet data");
74 fp=fopen(filename,
"r");
77 if(verbose>1) printf(
" file can be opened for reading.\n");
78 if(filetype!=NULL) *filetype=1;
84 if(filetype!=NULL) *filetype=0;
85 if(status!=NULL) strcpy(status,
"unknown file format");
88 if(filetype!=NULL) *filetype=3;
89 if(status!=NULL) strcpy(status,
"cannot read fit file");
92 if(verbose>2) printf(
" fileformat=%d\n", ftype);
95 if((ret=
dftRead(filename, &temp))!=0) {
96 if(filetype!=NULL) *filetype=0;
97 if(status!=NULL) sprintf(status,
"cannot read file (%d)", ret);
104 if(ret!=0) {sprintf(status,
"check the units of input and tissue data");}
107 if(ti1!=NULL) *ti1=temp.
x1[0];
108 if(ti2!=NULL) *ti2=temp.
x2[temp.
frameNr-1];
110 if(ti1!=NULL) *ti1=temp.
x[0];
111 if(ti2!=NULL) *ti2=temp.
x[temp.
frameNr-1];
117 if(ret>0) {
dftEmpty(&temp);
return 101;}
127 if(filetype!=NULL) *filetype=5;
131 if(status!=NULL) sprintf(status,
"cannot find region");
134 if(n==tissue->
voiNr) {
135 if(status!=NULL) sprintf(status,
"all regions do match");
139 ret=
dftdup(tissue, input);
if(ret==0) {
140 ri=0; ret=0;
while(ri<input->voiNr && ret==0) {
144 ri=0; ret=0;
while(ri<tissue->voiNr && ret==0) {
150 if(status!=NULL) sprintf(status,
"cannot separate input regions");
155 if(status!=NULL) sprintf(status,
"cannot separate input regions");
160 if(verbose>1) printf(
"selected ref region := %s\n", input->
voi[0].
name);
165 if(ret>0) {
dftEmpty(input);
return 101;}
169 for(ri=0; ri<input->
voiNr; ri++) {
173 if(ti1!=NULL) *ti1=input->
x1[0];
174 if(ti2!=NULL) *ti2=input->
x2[input->
frameNr-1];
178 if(ti1!=NULL) *ti1=input->
x[0];
179 if(ti2!=NULL) *ti2=input->
x[input->
frameNr-1];
182 if(status!=NULL) sprintf(status,
"cannot integrate input");
225 if(verbose>0) printf(
"dftReadReference(tis, %s, type, i, status, %d)\n", filename, verbose);
228 if(tissue==NULL || filename==NULL || strlen(filename)<1) {
229 if(status!=NULL) strcpy(status,
"program error");
233 if(status!=NULL) strcpy(status,
"no pet data");
240 if(filetype!=NULL) *filetype=3;
241 if(status!=NULL) strcpy(status,
"cannot read fit file");
247 fp=fopen(filename,
"r");
252 if((ret=
dftRead(filename, &temp))!=0) {
253 if(status!=NULL) sprintf(status,
"cannot read file (%d)", ret);
256 if(filetype!=NULL) *filetype=1;
262 sprintf(status,
"check the units of reference and tissue data");
267 if(ret!=0) {
dftEmpty(&temp);
return -5;}
270 for(; ri<tissue->
voiNr; ri++) tissue->
voi[ri].
sw=1;
277 sprintf(status,
"cannot select the best reference region");
281 tissue->
voi[ri].
sw=2;
if(ref_index!=NULL) *ref_index=ri;
282 if(verbose>1) printf(
"selected ref region := %s\n", tissue->
voi[ri].
name);
283 if(status!=NULL) sprintf(status,
"%d reference curve(s) read", n);
291 ftype=5;
if(filetype!=NULL) *filetype=ftype;
294 if(verbose>1) printf(
"nr of ref regions := %d/%d\n", n, tissue->
voiNr);
296 if(status!=NULL) sprintf(status,
"cannot find region");
300 if(status!=NULL) sprintf(status,
"all regions do match");
306 if(status!=NULL) sprintf(status,
"cannot select the best reference region");
309 tissue->
voi[ri].
sw=2;
if(ref_index!=NULL) *ref_index=ri;
310 if(verbose>1) printf(
"selected ref region := %s\n", tissue->
voi[ri].
name);
313 for(ri=0; ri<tissue->
voiNr; ri++)
if(tissue->
voi[ri].
sw>0) {
321 if(status!=NULL) sprintf(status,
"cannot integrate input");
326 if(status!=NULL) sprintf(status,
"%d reference curve(s) read", n);
368 int ret, fi, n, first, last, ii, input_nr=0;
370 double f, starttime, endtime;
375 if(loginfo!=NULL && verbose>0) {
376 fprintf(loginfo,
"dftReadModelingData(\n");
377 fprintf(loginfo,
" %s,\n", tissuefile);
378 fprintf(loginfo,
" %s,\n", inputfile1);
379 fprintf(loginfo,
" %s,\n", inputfile2);
380 fprintf(loginfo,
" %s,\n", inputfile3);
381 fprintf(loginfo,
" %g,\n", *fitdur);
382 fprintf(loginfo,
" *fitframeNr, *tis, *inp, *loginfo, %d, *status\n", verbose);
383 fprintf(loginfo,
")\n");
386 if(status!=NULL) sprintf(status,
"program error");
387 if(tis==NULL || inp==NULL)
return -1;
388 if(tissuefile==NULL || strlen(tissuefile)<1)
return -2;
390 if(inputfile1==NULL || strlen(inputfile1)<1)
return -3;
else input_nr++;
391 if(inputfile2!=NULL && strlen(inputfile2)>0) input_nr++;
392 if(inputfile3!=NULL && strlen(inputfile3)>0) {
393 if(input_nr<2)
return -4;
396 if(status!=NULL) sprintf(status,
"arguments validated");
406 if(loginfo!=NULL && verbose>0) fprintf(loginfo,
"reading tissue data in %s\n", tissuefile);
408 if(status!=NULL) sprintf(status,
"cannot read '%s': %s", tissuefile,
dfterrmsg);
413 if(status!=NULL) sprintf(status,
"missing sample(s) in %s", tissuefile);
421 if(loginfo!=NULL && verbose>0)
422 fprintf(loginfo,
"checking frame overlap in %s\n", tissuefile);
425 if(status!=NULL) sprintf(status,
"%s has overlapping frame times", tissuefile);
430 fprintf(wfp,
"Warning: tissue sample time units not known.\n");
436 if(loginfo!=NULL && verbose>0) fprintf(loginfo,
"reading input data in %s\n", inputfile1);
438 if(status!=NULL) sprintf(status,
"cannot read '%s': %s", inputfile1,
dfterrmsg);
445 fprintf(wfp,
"Warning: input sample time units not known.\n");
449 if(status!=NULL) sprintf(status,
"tissue and plasma do have different time units");
454 fprintf(wfp,
"Warning: using only first TAC in %s\n", inputfile1);
458 if(status!=NULL) sprintf(status,
"%s contains too few samples", inputfile1);
467 for(ii=2; ii<=input_nr; ii++) {
468 if(ii==2) fname=inputfile2;
469 else fname=inputfile3;
474 if(status!=NULL) sprintf(status,
"cannot allocate more memory");
480 if(loginfo!=NULL && verbose>0) fprintf(loginfo,
"reading input data in %s\n", fname);
482 if(status!=NULL) sprintf(status,
"cannot read '%s': %s", fname,
dfterrmsg);
486 if(status!=NULL) sprintf(status,
"%s contains too few samples", fname);
493 if(tmpdft.
timeunit==TUNIT_UNKNOWN) {
494 fprintf(wfp,
"Warning: blood sample time units not known.\n");
498 if(status!=NULL) sprintf(status,
"two input data are in different time units");
507 fprintf(wfp,
"Warning: using only first TAC in %s\n", fname);
510 if(loginfo!=NULL && verbose>1)
511 fprintf(loginfo,
"interpolating %d samples into %d samples.\n",
515 if(loginfo!=NULL && verbose>0)
516 fprintf(loginfo,
"dftInterpolateInto() := %d\n", ret);
525 if(loginfo!=NULL && verbose>1)fprintf(loginfo,
"setting time units to min.\n");
527 fprintf(wfp,
"Warning: check that regional data times are in minutes.\n");
529 fprintf(wfp,
"Warning: check that input data times are in minutes.\n");
534 if(loginfo!=NULL && verbose>0) fprintf(loginfo,
"checking input data\n");
536 if(status!=NULL) sprintf(status,
"%s contains too few samples", inputfile1);
541 if(status!=NULL) sprintf(status,
"missing sample(s) in data");
547 fprintf(wfp,
"Warning: you might need to check the sample time units.\n");
550 for(fi=1, n=0, f=inp->
voi[0].
y[0]; fi<inp->frameNr; fi++)
551 if(inp->
voi[0].
y[fi]>=f) {f=inp->
voi[0].
y[fi]; n=fi;}
552 if(n<2) fprintf(wfp,
"Warning: check the first input sample values.\n");
556 if(ret!=0) {fprintf(wfp,
"Note: check the units of input and tissue data.\n");}
561 if(loginfo!=NULL && verbose>0) fprintf(loginfo,
"checking and setting fit time length\n");
563 starttime=0; endtime=*fitdur;
564 *fitframeNr=
fittime_from_dft(tis, &starttime, &endtime, &first, &last, verbose);
565 if(loginfo!=NULL && verbose>1) {
566 fprintf(loginfo,
"tis.frameNr := %d\n", tis->
frameNr);
567 fprintf(loginfo,
"starttime := %g\n", starttime);
568 fprintf(loginfo,
"endtime := %g\n", endtime);
569 fprintf(loginfo,
"first := %d\n", first);
570 fprintf(loginfo,
"last := %d\n", last);
571 fprintf(loginfo,
"fitframeNr := %d\n", *fitframeNr);
578 if(status!=NULL) sprintf(status,
"input TAC is too short");
583 if(loginfo!=NULL && verbose>0) printf(
"Input TAC cutoff at %g min\n", f);
584 for(fi=0; fi<inp->
frameNr; fi++)
if(inp->
x[fi]>f)
break;
585 if(fi<inp->frameNr) fi++;
588 if(status!=NULL) sprintf(status,
"too few samples in specified fit duration.\n");
591 if(loginfo!=NULL && verbose>1) {
592 fprintf(loginfo,
"dft.frameNr := %d\ninp.frameNr := %d\nfitdur := %g\n",
594 fprintf(loginfo,
"fitframeNr := %d\n", *fitframeNr);
597 if(status!=NULL) sprintf(status,
"ok");
632 int ri, fi, i1, i2, s1, s2;
633 double x, x1, x2, y1, y2;
634 int n, runnh, maxrunnh, runns, maxrunns;
636 int run1h, run2h, maxrun1h, maxrun2h, run1s, run2s, maxrun1s, maxrun2s;
639 printf(
"dftRobustMinMaxTAC(dft, %d, minx, maxx, miny, maxy, mini, maxi, mins, maxs, %d)\n",
642 if(dft==NULL)
return(1);
643 if(tacindex>=dft->
voiNr)
return(2);
648 x1=x2=y1=y2=nan(
""); i1=i2=s1=s2=0;
649 for(ri=0; ri<dft->
voiNr; ri++) {
650 if(tacindex>=0 && ri!=tacindex)
continue;
653 for(fi=n=0; fi<dft->
frameNr; fi++) {
654 if(isnan(dft->
voi[ri].
y[fi]))
continue;
656 if(isnan(dft->
x1[fi]) || isnan(dft->
x2[fi]))
continue;}
657 else {
if(isnan(dft->
x[fi]))
continue;}
658 list[n++]=dft->
voi[ri].
y[fi];
661 maxrunnh=maxrunns=dft->
frameNr;
663 maxrun2h=maxrun2s=dft->
frameNr-1;
668 runnh=maxrunnh=run1h=run2h=maxrun1h=maxrun2h=0;
669 runns=maxrunns=run1s=run2s=maxrun1s=maxrun2s=0;
670 for(fi=0; fi<dft->
frameNr; fi++) {
671 if(isnan(dft->
voi[ri].
y[fi]))
continue;
673 if(isnan(dft->
x1[fi]) || isnan(dft->
x2[fi]))
continue;}
674 else {
if(isnan(dft->
x[fi]))
continue;}
676 if(dft->
voi[ri].
y[fi]>ym) {
677 runnh++;
if(runnh==1) {run1h=run2h=fi;}
else {run2h=fi;}
679 if(runnh>maxrunnh) {maxrunnh=runnh; maxrun1h=run1h; maxrun2h=run2h;}
683 if(dft->
voi[ri].
y[fi]<ym) {
684 runns++;
if(runns==1) {run1s=run2s=fi;}
else {run2s=fi;}
686 if(runns>maxrunns) {maxrunns=runns; maxrun1s=run1s; maxrun2s=run2s;}
691 if(runnh>maxrunnh) {maxrunnh=runnh; maxrun1h=run1h; maxrun2h=run2h;}
692 if(runns>maxrunns) {maxrunns=runns; maxrun1s=run1s; maxrun2s=run2s;}
694 if(maxrunnh<2) {maxrunnh=dft->
frameNr; maxrun1h=0; maxrun2h=dft->
frameNr-1;}
695 if(maxrunns<2) {maxrunns=dft->
frameNr; maxrun1s=0; maxrun2s=dft->
frameNr-1;}
698 fprintf(stderr,
"longest run for max: %g - %g\n", dft->
x[maxrun1h], dft->
x[maxrun2h]);
699 fprintf(stderr,
"longest run for min: %g - %g\n", dft->
x[maxrun1s], dft->
x[maxrun2s]);
702 for(fi=maxrun1h; fi<=maxrun2h; fi++) {
703 if(isnan(dft->
voi[ri].
y[fi]))
continue;
705 if(isnan(dft->
x1[fi]) || isnan(dft->
x2[fi]))
continue;
706 x=0.5*(dft->
x1[fi]+dft->
x2[fi]);
708 if(isnan(dft->
x[fi]))
continue;
711 if(isnan(y2) || y2<dft->voi[ri].y[fi]) {y2=dft->
voi[ri].
y[fi]; i2=ri; x2=x; s2=fi;}
714 for(fi=maxrun1s; fi<=maxrun2s; fi++) {
715 if(isnan(dft->
voi[ri].
y[fi]))
continue;
717 if(isnan(dft->
x1[fi]) || isnan(dft->
x2[fi]))
continue;
718 x=0.5*(dft->
x1[fi]+dft->
x2[fi]);
720 if(isnan(dft->
x[fi]))
continue;
723 if(isnan(y1) || y1>dft->
voi[ri].
y[fi]) {y1=dft->
voi[ri].
y[fi]; i1=ri; x1=x; s1=fi;}
728 if(minx!=NULL) {
if(isnan(x1))
return(11);
else *minx=x1;}
729 if(maxx!=NULL) {
if(isnan(x2))
return(12);
else *maxx=x2;}
730 if(miny!=NULL) {
if(isnan(y1))
return(13);
else *miny=y1;}
731 if(maxy!=NULL) {
if(isnan(y2))
return(14);
else *maxy=y2;}
732 if(mini!=NULL) {
if(isnan(y1))
return(13);
else *mini=i1;}
733 if(maxi!=NULL) {
if(isnan(y2))
return(14);
else *maxi=i2;}
734 if(mins!=NULL) {
if(isnan(y1))
return(13);
else *mins=s1;}
735 if(maxs!=NULL) {
if(isnan(y2))
return(14);
else *maxs=s2;}
758 int ri, fi, ret, mini, maxi, starti, warn=0;
759 double minx, maxx, miny, maxy, startx, dif, lowesty;
761 if(verbose>0) printf(
"dftVerifyPeak(dft, %d, %d)\n", index, verbose);
763 if(status!=NULL) strcpy(status,
"program error");
764 if(dft==NULL || dft->
frameNr<1 || dft->
voiNr<1)
return 1;
765 if(index>=dft->
voiNr)
return 1;
769 if(status!=NULL) strcpy(status,
"too few samples");
777 for(ri=0; ri<dft->
voiNr; ri++) {
778 if(index>=0 && index!=ri)
continue;
779 if(verbose>1) printf(
"checking region %d: %s\n", 1+ri, dft->
voi[ri].
name);
782 ret=
dftMinMaxTAC(dft, ri, &minx, &maxx, &miny, &maxy, NULL, NULL, &mini, &maxi);
784 if(verbose>0) printf(
"Error %d in dftMinMaxTAC()\n", ret);
785 if(status!=NULL) strcpy(status,
"invalid TAC");
791 if(verbose>0) printf(
"TAC has no positive values.\n");
792 if(status!=NULL) strcpy(status,
"no positive TAC values");
796 if((-miny)>0.40*maxy) {
797 if(verbose>0) printf(
"TAC has high negative value(s).\n");
798 if(status!=NULL) strcpy(status,
"too high negative TAC values");
801 if((-miny)>0.02*maxy) {
802 if(verbose>1) printf(
"TAC has negative value(s).\n");
808 startx=1.0E+10; starti=dft->
frameNr-1;
809 for(fi=0; fi<dft->
frameNr; fi++) {
810 if(isnan(dft->
voi[ri].
y[fi]))
continue;
812 if(isnan(dft->
x1[fi]))
continue;
813 if(isnan(dft->
x2[fi]))
continue;
814 startx=dft->
x1[fi]; starti=fi;
break;
816 if(isnan(dft->
x[fi]))
continue;
817 startx=dft->
x[fi]; starti=fi;
break;
820 if(verbose>2) printf(
"first time sample at %g\n", startx);
824 if(verbose>2) printf(
"Peak at the first sample.\n");
825 if(status!=NULL) strcpy(status,
"input TAC should start at time zero");
828 dif=dft->
x1[maxi]/(dft->
x2[maxi]-dft->
x1[maxi]);
831 for(fi=maxi+1; fi<dft->
frameNr; fi++)
832 if(!isnan(dft->
x[fi]) && dft->
x[fi]>dft->
x[maxi])
break;
833 if(fi==dft->
frameNr) dif=1.0E+10;
834 else dif=dft->
x[maxi]/(dft->
x[fi]-dft->
x[maxi]);
837 if(verbose>0) printf(
"Peak at the first sample which is not at zero.\n");
838 if(verbose>1) printf(
"dif := %g\n", dif);
844 if(maxy>20.*miny) warn++;
else return 2;
845 if(verbose>1) printf(
"good peak/tail -ratio\n");
846 }
else if(dif>0.3) warn++;
850 lowesty=dft->
voi[ri].
y[starti];
851 for(fi=starti+1; fi<maxi; fi++)
852 if(dft->
voi[ri].
y[fi]<lowesty) lowesty=dft->
voi[ri].
y[fi];
853 if(verbose>2) printf(
"lowest value before peak: %g\n", lowesty);
856 if(maxi>starti && startx>0.001 && startx>0.75*maxx) {
857 if(dft->
voi[ri].
y[starti]>0.66*maxy && lowesty>0.05*maxy && mini>maxi) {
858 if(verbose>0) printf(
"The first sample is relatively late and high.\n");
859 if(status!=NULL) strcpy(status,
"input TAC should start at time zero");
861 printf(
"startx=%g\n", startx);
862 printf(
"starty=%g\n", dft->
voi[ri].
y[starti]);
863 printf(
"maxx=%g\n", maxx);
864 printf(
"maxy=%g\n", maxy);
869 if(maxi>starti && startx>0.001 && startx>0.5*maxx) {
870 if(dft->
voi[ri].
y[starti]>0.5*maxy && lowesty>0.05*maxy && mini>maxi) {
871 if(verbose>1) printf(
"The first sample is relatively late and high.\n");
876 printf(
"startx=%g\n", startx);
877 printf(
"starty=%g\n", dft->
voi[ri].
y[starti]);
878 printf(
"maxx=%g\n", maxx);
879 printf(
"maxy=%g\n", maxy);
885 if(verbose>0) printf(
"TAC does not have a clear peak.\n");
886 if(status!=NULL) strcpy(status,
"input TAC peak missing");
890 if(verbose>1) printf(
"TAC does not have a clear peak.\n");
896 if(verbose>0 && warn>0) printf(
"%d warning(s)\n", warn);
898 if(status!=NULL) strcpy(status,
"input TAC is not optimal");
901 if(status!=NULL) strcpy(status,
"input TAC ok");
int dftMinMaxTAC(DFT *dft, int tacindex, double *minx, double *maxx, double *miny, double *maxy, int *mini, int *maxi, int *mins, int *maxs)
int dftdup(DFT *dft1, DFT *dft2)
int dftDeleteFrameOverlap(DFT *dft)
int dftAddmem(DFT *dft, int voiNr)
int dftMovevoi(DFT *dft, int from, int to)
int dftSortByFrame(DFT *dft)
int dftSelectBestReference(DFT *dft)
int dftDelete(DFT *dft, int voi)
int dft_nr_of_NA(DFT *dft)
int dftSelectRegions(DFT *dft, char *region_name, int reset)
int dftInterpolate(DFT *input, DFT *tissue, DFT *output, char *status, int verbose)
int dftInterpolateInto(DFT *inp, DFT *tis, char *status, int verbose)
int dftRead(char *filename, DFT *data)
int dftFormat(char *fname)
int dftUnitConversion(DFT *dft, int dunit)
int dftTimeunitConversion(DFT *dft, int tunit)
int fittime_from_dft(DFT *dft, double *startTime, double *endTime, int *first, int *last, int verbose)
int petintegral(double *x1, double *x2, double *y, int nr, double *ie, double *iie)
Integrate PET TAC data to frame mid times.
int petintegrate(double *x1, double *x2, double *y, int nr, double *newyi, double *newyii)
int integrate(double *x, double *y, int nr, double *yi)
int interpolate(double *x, double *y, int nr, double *newx, double *newy, double *newyi, double *newyii, int newnr)
Linear interpolation and integration.
#define DFT_TIME_STARTEND
#define DFT_FORMAT_UNKNOWN
int petCunitId(const char *unit)
double dmedian(double *data, int n)
Header file for libtpcmodext.
char unit[MAX_UNITS_LEN+1]
char name[MAX_REGIONNAME_LEN+1]