TPCCLIB
Loading...
Searching...
No Matches
imginteg.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 <unistd.h>
13#include <string.h>
14#include <math.h>
15#include <time.h>
16/*****************************************************************************/
17#include "libtpcmisc.h"
18#include "libtpcmodel.h"
19#include "libtpccurveio.h"
20#include "libtpcimgio.h"
21#include "libtpcimgp.h"
22#include "libtpcmodext.h"
23/*****************************************************************************/
24
25/*****************************************************************************/
26static char *info[] = {
27 "Calculates AUC (integral over time) image from PET image in",
28 "in ECAT 6.3, 7.x, NIfTI-1, or Analyze 7.5 format.",
29 "Analyze and NIfTI image must have SIF in the same folder.",
30 "In case of a static image, the matrix values are simply multiplied by the",
31 "frame duration.",
32 "The pixel values of resulting integral image will be in units of",
33 "radioactivity concentration times sec.",
34 " ",
35 "Usage: @P [Options] image starttime duration aucimage",
36 " ",
37 "AUC start time and duration (not stop time) must be entered in seconds;",
38 "program will automatically set the integration start time or duration",
39 "based on the time range in the image, if either is set to zero.",
40 " ",
41 "Options:",
42 " -avg",
43 " Average during specified range is calculated instead of AUC.",
44 " -min",
45 " AUC times are given in minutes instead of seconds.",
46 " -stdoptions", // List standard options like --help, -v, etc
47 " ",
48 "Example 1: calculate integral image between 32 and 302 seconds after",
49 "scan start with command",
50 " @P s5998dy1.v 32 270 s5998int.v",
51 " ",
52 "Example 2: integrate a static or dynamic image from the start time of",
53 "the first frame to the end of the last frame:",
54 " @P a773dy1.v 0 0 a773int.v",
55 " ",
56 "Example 3: integrate a dynamic image from 600 seconds to the end of",
57 "the last frame:",
58 " @P a773dy1.v 600 0 a773int.v",
59 " ",
60 "See also: imgunit, ecattime, ecatsum, imgsuv, imgledif, imgfur, imglkup",
61 " ",
62 "Keywords: image, AUC, modelling, autoradiography, perfusion, SUV",
63 0};
64/*****************************************************************************/
65
66/*****************************************************************************/
67/* Turn on the globbing of the command line, since it is disabled by default in
68 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
69 In Unix&Linux wildcard command line processing is enabled by default. */
70/*
71#undef _CRT_glob
72#define _CRT_glob -1
73*/
74int _dowildcard = -1;
75/*****************************************************************************/
76
77/*****************************************************************************/
81int main(int argc, char **argv)
82{
83 int ai, help=0, version=0, verbose=1;
84 int ret, isStat=0;
85 int calc_avg=0; // 0=integral, 1=average
86 int times_in_min=0; // 0=sec, 1=min
87 char petfile[FILENAME_MAX], intfile[FILENAME_MAX];
88 char *cptr, tmp[512];
89 IMG pet, rout;
90 float tstart, tstop, tdur;
91
92
93
94 /*
95 * Get arguments
96 */
97 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
98 petfile[0]=intfile[0]=(char)0;
99 tstart=tdur=tstop=-1.0;
100 imgInit(&pet); imgInit(&rout);
101 /* Get options */
102 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
103 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
104 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
105 if(strcasecmp(cptr, "AVG")==0 || strcasecmp(cptr, "MEAN")==0) {
106 calc_avg=1; continue;
107 } else if(strncasecmp(cptr, "MINUTES", 3)==0) {
108 times_in_min=1; continue;
109 } else if(strncasecmp(cptr, "SECONDS", 3)==0) {
110 times_in_min=0; continue;
111 }
112 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
113 return(1);
114 } else break;
115
116 /* Print help or version? */
117 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
118 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
119 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
120
121 /* Process other arguments, starting from the first non-option */
122 if(ai<argc) {strlcpy(petfile, argv[ai], FILENAME_MAX); ai++;}
123 if(ai<argc) {tstart=atof_dpi(argv[ai]); ai++;}
124 if(ai<argc) {tdur=atof_dpi(argv[ai]); tstop=tstart+tdur; ai++;}
125 if(ai<argc) {strlcpy(intfile, argv[ai], FILENAME_MAX); ai++;}
126 if(ai<argc) {fprintf(stderr, "Error: invalid argument '%s'.\n", argv[ai]); return(1);}
127
128 /* Did we get all the information that we need? */
129 if(!intfile[0]) {
130 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
131 return(1);
132 }
133 if(strcasecmp(intfile, petfile)==0) {
134 fprintf(stderr, "Error: check the output file name.\n");
135 return(1);
136 }
137 if(tstop<tstart || tstart<0.0) {
138 fprintf(stderr, "Error: invalid time range arguments.\n");
139 return(1);
140 }
141 /* Convert AUC times to seconds, if necessary */
142 if(times_in_min==1) {tstart*=60.0; tstop*=60.0; tdur*=60.0;}
143
144
145 /* In verbose mode print arguments and options */
146 if(verbose>1) {
147 printf("petfile := %s\n", petfile);
148 printf("intfile := %s\n", intfile);
149 printf("calc_avg := %d\n", calc_avg);
150 printf("times_in_min := %d\n", times_in_min);
151 }
152 if(verbose>9) IMG_TEST=verbose-9; else IMG_TEST=0;
153
154
155 /*
156 * Read image
157 */
158 if(verbose>0) fprintf(stdout, "reading image %s\n", petfile);
159 ret=imgRead(petfile, &pet);
160 if(ret) {
161 fprintf(stderr, "Error: %s\n", pet.statmsg); if(verbose>1) imgInfo(&pet);
162 return(2);
163 }
164 /* Check if PET data is raw or image */
165 if(pet.type!=IMG_TYPE_IMAGE) {
166 fprintf(stderr, "Error: %s is not an image.\n", petfile);
167 imgEmpty(&pet); return(2);
168 }
169 if(pet.dimt<2) {
170 isStat=1;
171 fprintf(stderr, "Warning: %s is assumed to be a static image.\n", petfile);
172 }
173 if(verbose>1) printf("isStat := %d\n", isStat);
174
175 /* Check that frame times are available */
176 if(!imgExistentTimes(&pet)) {
177 fprintf(stderr, "Error: image does not contain frame times.\n");
178 imgEmpty(&pet); return(2);
179 }
180
181 /* Make sure that there is no overlap in image frames */
182 if(pet.dimt>1) {
183 if(verbose>1) fprintf(stdout, "checking frame overlap in %s\n", petfile);
184 ret=imgDeleteFrameOverlap(&pet);
185 if(ret) {
186 fprintf(stderr, "Error: image %s has overlapping frame times.\n", petfile);
187 imgEmpty(&pet); return(2);
188 }
189 }
190
191 /* If both integration start time and duration were set to zero, then take these from the image */
192 if(tstart<1.0E-03 && tdur<1.0E-02) {
193 tstart=pet.start[0]; tstop=pet.end[pet.dimt-1]; tdur=tstop-tstart;
194 } else if(tdur<1.0E-02) {
195 /* If duration was set to zero, then take it from the image */
196 tstop=pet.end[pet.dimt-1]; tdur=tstop-tstart;
197 }
198 if(verbose>1) {
199 printf("tstart := %g\n", tstart);
200 printf("tstop := %g\n", tstop);
201 printf("tdur := %g\n", tdur);
202 }
203
204
205 /*
206 * Calculate the integral image (or average)
207 */
208 if(verbose>1) fprintf(stdout, "calculating integral image\n");
209 ret=imgTimeIntegral(&pet, tstart, tstop, &rout, calc_avg, tmp, verbose-2);
210 if(ret!=0) {
211 fprintf(stderr, "Error: %s.\n", tmp);
212 imgEmpty(&pet); imgEmpty(&rout); return(6);
213 }
214 if(verbose>0) fprintf(stdout, "%s.\n", tmp);
215 imgEmpty(&pet);
216
217
218 /*
219 * Save parametric image(s)
220 */
221 if(verbose>1) fprintf(stdout, "writing integral image\n");
222 ret=imgWrite(intfile, &rout);
223 if(ret) {
224 fprintf(stderr, "Error: %s\n", rout.statmsg);
225 imgEmpty(&rout); return(11);
226 }
227 if(verbose>0) {
228 if(calc_avg) fprintf(stdout, "mean image written in %s\n", intfile);
229 else fprintf(stdout, "integral image written in %s\n", intfile);
230 }
231 imgEmpty(&rout);
232
233 return(0);
234}
235/*****************************************************************************/
236
237/*****************************************************************************/
double atof_dpi(char *str)
Definition decpoint.c:59
int IMG_TEST
Definition img.c:6
int imgExistentTimes(IMG *img)
Definition img.c:613
void imgInfo(IMG *image)
Definition img.c:359
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
int imgWrite(const char *fname, IMG *img)
Definition imgfile.c:136
int imgDeleteFrameOverlap(IMG *img)
Definition imgframe.c:77
Header file for libtpccurveio.
Header file for libtpcimgio.
#define IMG_TYPE_IMAGE
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 libtpcmodel.
Header file for libtpcmodext.
int imgTimeIntegral(IMG *img, float t1, float t2, IMG *iimg, int calc_mode, char *status, int verbose)
Definition misc_model.c:147
char type
unsigned short int dimt
float * start
float * end
const char * statmsg