9#include "tpcclibConfig.h"
25#define LKUP_HIST_NR 25
29static char *info[] = {
30 "Replace the voxel values in PET image or scan file with the values from",
32 "PET image file must be in ECAT, NIfTI, or Analyze format.",
33 "The look-up table must contain two columns: program looks from the first",
34 "column a matching value for the voxel value, and replaces the voxel value",
35 "with the value from the second column of the table.",
36 "Look-up table must be sorted in ascending order.",
38 "Usage: @P [Options] petfile lkupfile outputfile",
42 " If exact match in look-up table is not found, the closest value",
43 " is selected; by default, value is interpolated from the table.",
45 " By default, dynamic PET data is considered as an error, because",
46 " this program is mostly used in autoradiography method with static or",
47 " or integrated PET data; this option enables usage of dynamic data.",
49 " Histogram of the results is written in TAC format in specified file.",
59 "See also: arlkup, imginteg, taclkup, imgcalc, imgunit, img2dft",
61 "Keywords: image, look-up table, autoradiography, ARG, perfusion, radiowater",
80int main(
int argc,
char **argv)
82 int ai, help=0, version=0, verbose=1;
84 char petfile[FILENAME_MAX], lkupfile[FILENAME_MAX], outfile[FILENAME_MAX];
85 char *cptr, hisfile[FILENAME_MAX];
93 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
94 petfile[0]=outfile[0]=lkupfile[0]=hisfile[0]=(char)0;
96 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
98 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
99 if(strncasecmp(cptr,
"CLOSEST", 1)==0) {
100 takeClosest=1;
continue;
101 }
else if(strncasecmp(cptr,
"DYNAMIC", 3)==0) {
102 acceptDynamic=1;
continue;
103 }
else if(strncasecmp(cptr,
"HIS=", 4)==0) {
104 strlcpy(hisfile, cptr+4, FILENAME_MAX);
if(strlen(hisfile)>0)
continue;
106 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
111 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
116 if(ai<argc)
strlcpy(petfile, argv[ai++], FILENAME_MAX);
117 if(ai<argc)
strlcpy(lkupfile, argv[ai++], FILENAME_MAX);
118 if(ai<argc)
strlcpy(outfile, argv[ai++], FILENAME_MAX);
120 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
125 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
128 if(strcasecmp(petfile, outfile)==0) {
129 fprintf(stderr,
"Error: same name for input and output file.\n");
135 printf(
"petfile := %s\n", petfile);
136 printf(
"lkupfile := %s\n", lkupfile);
137 printf(
"outfile := %s\n", outfile);
138 if(hisfile[0]) printf(
"hisfile := %s\n", hisfile);
139 printf(
"takeClosest := %d\n", takeClosest);
140 printf(
"acceptDynamic := %d\n", acceptDynamic);
149 if(verbose>0) printf(
"reading %s\n", lkupfile);
151 if(
dftRead(lkupfile, &table)) {
152 fprintf(stderr,
"Error: %s\n",
dfterrmsg);
157 double *table1=table.
x;
double *table2=table.
voi[0].
y;
158 if(table.
voiNr>1 || tableSize<2) {
159 fprintf(stderr,
"Error: invalid look-up table %s\n", lkupfile);
163 printf(
"Look-up y: %g - %g\n", table2[0], table2[tableSize-1]);
164 printf(
"Look-up x: %g - %g\n", table1[0], table1[tableSize-1]);
172 if(verbose>0) fprintf(stdout,
"reading %s\n", petfile);
176 fprintf(stderr,
"Error: %s\n", img.
statmsg);
177 if(verbose>1) printf(
"ret=%d\n", ret);
182 if(acceptDynamic==0 && img.
dimt>1) {
183 fprintf(stderr,
"Error: file contains more than one frame.\n");
191 if(verbose>1) printf(
"allocating memory for the histogram\n");
195 fprintf(stderr,
"Error: cannot allocate memory for histogram.\n");
202 double histogram_bin=(table2[tableSize-1]-table2[0])/(
double)LKUP_HIST_NR;
203 if(verbose>2) printf(
"histogram_bin_size := %g\n", histogram_bin);
204 hist.
x1[0]=table2[0]; hist.
x2[0]=hist.
x1[0]+histogram_bin;
205 for(
int i=1; i<hist.
frameNr; i++) {
206 hist.
x1[i]=hist.
x2[i-1];
207 hist.
x2[i]=hist.
x1[i]+histogram_bin;
209 for(
int i=0; i<hist.
frameNr; i++) hist.
voi[0].
y[i]=0.0;
217 if(verbose>0) {fprintf(stdout,
"using look-up table\n"); fflush(stdout);}
219 int low, high, mid, n;
221 for(zi=0; zi<img.
dimz; zi++) {
222 for(yi=0; yi<img.
dimy; yi++) {
223 for(xi=0; xi<img.
dimx; xi++) {
224 for(ti=0; ti<img.
dimt; ti++) {
225 v=(double)img.
m[zi][yi][xi][ti];
226 if(isnan(v))
continue;
230 }
else if(v>table1[tableSize-1]) {
231 v=table2[tableSize-1];
234 low=mid=0; high=tableSize-1; ret=1;
237 if(v<table1[mid]) high=mid-1;
238 else if(v>table1[mid]) low=mid+1;
239 else {v=table2[mid]; ret=0;
break;}
243 n=high; high=low; low=n;
245 if(v-table1[low]<table1[high]-v) v=table2[low];
249 (v-table1[low])*(table2[high]-table2[low])
250 /(table1[high]-table1[low]);
255 if(v>=hist.
x1[n] && v<=hist.
x2[n]) {
256 hist.
voi[0].
y[n]+=1.0;
break;
259 img.
m[zi][yi][xi][ti]=(float)v;
264 if(verbose>0 && img.
dimz>2) {fprintf(stdout,
"\n"); fflush(stdout);}
277 if(verbose>1) fprintf(stdout,
"writing %s\n", outfile);
279 fprintf(stderr,
"Error: %s\n", img.
statmsg);
280 if(verbose>1) printf(
"ret=%d\n", ret);
284 if(verbose>0) printf(
"Written %s\n", outfile);
291 if(!hisfile[0] && verbose<=1) {
295 printf(
"\nHistogram:\n"); fflush(stdout);
299 if(verbose>1) printf(
"writing %s\n", hisfile);
301 fprintf(stderr,
"Error in writing '%s': %s\n", hisfile,
dfterrmsg);
304 if(verbose>0) fprintf(stdout,
"Histogram written in %s\n", hisfile);
int dftSetmem(DFT *data, int frameNr, int voiNr)
int dftRead(char *filename, DFT *data)
int dftWrite(DFT *data, char *filename)
void imgEmpty(IMG *image)
int imgRead(const char *fname, IMG *img)
int imgWrite(const char *fname, IMG *img)
Header file for libtpccurveio.
#define DFT_TIME_STARTEND
Header file for libtpcimgio.
Header file for libtpcimgp.
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
int petCunitId(const char *unit)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
int tpcHtmlUsage(const char *program, char *text[], const char *path)
void tpcPrintBuild(const char *program, FILE *fp)
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
char unit[MAX_UNITS_LEN+1]
char name[MAX_REGIONNAME_LEN+1]