TPCCLIB
Loading...
Searching...
No Matches
imgqntls.c
Go to the documentation of this file.
1
7/*****************************************************************************/
8#include "tpcclibConfig.h"
9/*****************************************************************************/
10#include <stdio.h>
11#include <stdlib.h>
12#include <math.h>
13#include <string.h>
14#include <unistd.h>
15#include <time.h>
16/*****************************************************************************/
17#include "libtpcmisc.h"
18#include "libtpccurveio.h"
19#include "libtpcimgio.h"
20#include "libtpcimgp.h"
21#include "libtpcsvg.h"
22#include "libtpcmodext.h"
23/*****************************************************************************/
24
25/*****************************************************************************/
26static char *info[] = {
27 "Divide the voxel values in static PET image into quantiles.",
28 "PET image file must be in ECAT, NIfTI, or Analyze format.",
29 "User must specify the number of groups, and program writes the group",
30 "cut points (quantiles, nr of groups - 1) into stdout.",
31 " ",
32 "Usage: @P [Options] petfile groupnr",
33 " ",
34 "Options:",
35 " -pos[itive]",
36 " Include only voxels with value > 0.",
37 " -abs[olute]",
38 " Use absolute voxel values.",
39 " -stdoptions", // List standard options like --help, -v, etc
40 " ",
41 "See also: imghist, imginteg, imgpeak, imgthrs, imgcutof, imgmask",
42 " ",
43 "Keywords: image, histogram, threshold",
44 0};
45/*****************************************************************************/
46
47/*****************************************************************************/
48/* Turn on the globbing of the command line, since it is disabled by default in
49 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
50 In Unix&Linux wildcard command line processing is enabled by default. */
51/*
52#undef _CRT_glob
53#define _CRT_glob -1
54*/
55int _dowildcard = -1;
56/*****************************************************************************/
57
58/*****************************************************************************/
59/* Local functions */
60static int statFloatCompAsc(const void *i, const void *j)
61{
62 const float *di = (const float *)i;
63 const float *dj = (const float *)j;
64 return(*di > *dj) - (*di < *dj);
65}
66static int statFloatCompDesc(const void *i, const void *j)
67{
68 const float *di = (const float *)i;
69 const float *dj = (const float *)j;
70 return(*di < *dj) - (*di > *dj);
71}
73
78 float *data,
80 unsigned int n,
82 int order
83) {
84 if(n<2 || data==NULL) return;
85 if(order==0) qsort(data, n, sizeof(float), statFloatCompAsc);
86 else qsort(data, n, sizeof(float), statFloatCompDesc);
87}
89/*****************************************************************************/
90
91/*****************************************************************************/
95int main(int argc, char **argv)
96{
97 int ai, help=0, version=0, verbose=1;
98 char petfile[FILENAME_MAX];
99 int groupNr=0;
100 char *cptr;
101 int ret=0;
102 int positives=0;
103 int absolutes=0;
104
105
106 /*
107 * Get arguments
108 */
109 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
110 petfile[0]=(char)0;
111 /* Get options */
112 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
113 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
114 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
115 if(strncasecmp(cptr, "POSITIVES", 3)==0) {
116 positives=1; continue;
117 } else if(strncasecmp(cptr, "ABSOLUTES", 3)==0) {
118 absolutes=1; continue;
119 }
120 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
121 return(1);
122 } else break;
123
124 /* Print help or version? */
125 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
126 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
127 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
128
129 /* Process other arguments, starting from the first non-option */
130 if(ai<argc) strlcpy(petfile, argv[ai++], FILENAME_MAX);
131 if(ai<argc) groupNr=atoi(argv[ai++]);
132 if(ai<argc) {
133 fprintf(stderr, "Error: invalid argument '%s'.\n", argv[ai]);
134 return(1);
135 }
136 /* Did we get all the information that we need? */
137 if(!petfile[0]) {
138 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
139 return(1);
140 }
141 if(groupNr<2) {
142 fprintf(stderr, "Error: invalid nr of groups.\n");
143 return(1);
144 }
145 if(absolutes && positives) {
146 fprintf(stderr, "Error: invalid combination of options -abs and -pos.\n");
147 return(1);
148 }
149
150 /* In verbose mode print arguments and options */
151 if(verbose>1) {
152 printf("petfile := %s\n", petfile);
153 printf("groupNr := %d\n", groupNr);
154 printf("positives_only := %d\n", positives);
155 printf("absolute_values := %d\n", absolutes);
156 fflush(stdout);
157 }
158
159
160
161 /*
162 * Read PET data
163 */
164 if(verbose>0) fprintf(stdout, "reading %s\n", petfile);
165 IMG img; imgInit(&img);
166 ret=imgRead(petfile, &img);
167 if(ret) {
168 fprintf(stderr, "Error: %s\n", img.statmsg);
169 if(verbose>1) printf("ret=%d\n", ret);
170 imgEmpty(&img); return(2);
171 }
172 if(verbose>1) {
173 printf("image_size := %d x %d x %d\n", img.dimx, img.dimy, img.dimz);
174 if(img.dimt>1) printf("frame_nr := %d\n", img.dimt);
175 }
176 if(img.dimt>1) {
177 fprintf(stderr, "Error: cannot process dynamic images.\n");
178 imgEmpty(&img); return(2);
179 }
180 if(imgNaNs(&img, 1)>0)
181 if(verbose>0) fprintf(stderr, "Warning: missing pixel values.\n");
182
183 /* Copy the pixel values into an array */
184 if(verbose>1) fprintf(stdout, "copying voxel values\n");
185 long long pxlNr=img.dimx*img.dimy*img.dimz;
186 float *pxls=(float*)malloc(pxlNr*sizeof(float));
187 if(pxls==NULL) {
188 fprintf(stderr, "Error: cannot allocate memory.\n");
189 imgEmpty(&img); return(3);
190 }
191 pxlNr=0;
192 for(int zi=0; zi<img.dimz; zi++)
193 for(int yi=0; yi<img.dimy; yi++)
194 for(int xi=0; xi<img.dimx; xi++) {
195 if(positives && img.m[zi][yi][xi][0]<1.0E-010) continue;
196 if(absolutes==0) pxls[pxlNr]=img.m[zi][yi][xi][0];
197 else pxls[pxlNr]=fabsf(img.m[zi][yi][xi][0]);
198 pxlNr++;
199 }
200 if(verbose>1) printf("included_pixel_nr := %lld\n", pxlNr);
201 if(pxlNr<=groupNr) {
202 if(positives) fprintf(stderr, "Error: no positive voxel values.\n");
203 else fprintf(stderr, "Error: more groups than voxels.\n");
204 imgEmpty(&img); free(pxls);
205 return(4);
206 }
207 /* No need for original image */
208 imgEmpty(&img);
209
210 /* Sort pixel values */
211 if(verbose>0) fprintf(stdout, "sorting voxel values\n");
212 statSortFloat(pxls, pxlNr, 1);
213
214 /* Determine the quantiles */
215 int nrPerGroup=pxlNr/groupNr;
216 if(verbose>1) printf("pixels_per_group := %d\n", nrPerGroup);
217 float pxlQuantiles[groupNr-1];
218 for(int i=1; i<groupNr; i++) {
219 pxlQuantiles[i-1]=0.5*(pxls[i*nrPerGroup]+pxls[i*nrPerGroup - 1]);
220 if(verbose>10) printf("quantile[%d] := %g\n", i, pxlQuantiles[i-1]);
221 }
222 /* No need for pixel value list */
223 free(pxls);
224
225 /* Print quantiles in stdout */
226 fflush(stdout);
227 for(int i=1; i<groupNr; i++) {
228 fprintf(stdout, "quantile[%d] := %g\n", i, pxlQuantiles[i-1]);
229 }
230 fflush(stdout);
231
232 return(0);
233}
234/*****************************************************************************/
235
236/*****************************************************************************/
unsigned long long imgNaNs(IMG *img, int fix)
Definition img.c:658
void imgEmpty(IMG *image)
Definition img.c:121
void imgInit(IMG *image)
Definition img.c:60
int imgRead(const char *fname, IMG *img)
Definition imgfile.c:26
void statSortFloat(float *data, unsigned int n, int order)
Definition imgqntls.c:76
Header file for libtpccurveio.
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)
Definition proginfo.c:40
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition strext.c:245
int tpcHtmlUsage(const char *program, char *text[], const char *path)
Definition proginfo.c:213
void tpcPrintBuild(const char *program, FILE *fp)
Definition proginfo.c:383
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
Definition proginfo.c:158
Header file for libtpcmodext.
Header file for libtpcsvg.
unsigned short int dimx
float **** m
unsigned short int dimt
unsigned short int dimz
unsigned short int dimy
const char * statmsg