TPCCLIB
Loading...
Searching...
No Matches
ecat2ana.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 <time.h>
15#include <sys/stat.h>
16#include <unistd.h>
17/*****************************************************************************/
18#include "libtpcmisc.h"
19#include "libtpcimgio.h"
20#include "libtpcimgp.h"
21/*****************************************************************************/
22
23/*****************************************************************************/
24static char *info[] = {
25 "Converts ECAT 6.3 images or ECAT 7 image volumes to Analyze 7.5 image format.",
26 " ",
27 "The resulting Analyze database consists of two files, Analyze image (*.img)",
28 "and header file (*.hdr).",
29 "Analyze image format does not contain information on the frame times.",
30 "Frame times can be retrieved from SIF file, which can be created optionally.",
31 "SIF can also be created using other software.",
32 " ",
33 "By default, data is saved in big endian byte order (Sun Sparc).",
34 " ",
35 "Usage: @P [Options] ecatfile(s)",
36 " ",
37 "Options:",
38 " -Little or -pc or -intel",
39 " Data is saved in little endian (PC Intel) byte order.",
40 " -Big or -sun or -sparc",
41 " Data is saved in big endian (Sun Sparc, Motorola, PowerPC) byte order",
42 " (default).",
43 " -O=<output path>",
44 " Data directory for Analyze files; by default the output directory",
45 " ana_unix_files or ana_pc_files is created under input directory.",
46 " -flip=<y|n>",
47 " Override the default and environment variable ANALYZE_FLIP setting",
48 " by always flipping/not flipping image in z-direction (planes).",
49 " If environment variable is not set, then default is y.",
50 " Images are always flipped in x,y-directions.",
51 " -sif",
52 " SIF is saved with Analyze files; note that existing SIF will be",
53 " overwritten.",
54 " -frames",
55 " Time frames are saved as separate Analyze files.",
56 " -stdoptions", // List standard options like --help, -v, etc
57 " ",
58 "Example:",
59 " @P -o=anal *.v",
60 " ",
61 "Specific extensions to Analyze 7.5 format:",
62 " -Scale factor to retain quantitation in image_dimension.funused1",
63 " -Isotope halflife (sec) in image_dimension.funused3;",
64 " this does not imply whether data is corrected for decay or not.",
65 " -String in data_history.descrip tells whether data is corrected for decay;",
66 " 'Decay corrected.' or 'No decay correction.'",
67 " ",
68 "See also: ana2ecat, anabyteo, ana_lhdr, eframe, img2flat, ecat2nii",
69 " ",
70 "Keywords: image, format conversion, ECAT, Analyze",
71 0};
72/*****************************************************************************/
73
74/*****************************************************************************/
75/* Turn on the globbing of the command line, since it is disabled by default in
76 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
77 In Unix&Linux wildcard command line processing is enabled by default. */
78/*
79#undef _CRT_glob
80#define _CRT_glob -1
81*/
82int _dowildcard = -1;
83/*****************************************************************************/
84
85/*****************************************************************************/
89int main(int argc, char **argv)
90{
91 int ai, help=0, version=0, verbose=1;
92 int ret, errorNr=0, flipping, fi=0, ffi=0, fileNr=0;
93 int ana_order=1; /* 0=little (intel), 1=big endian (sparc) */
94 int separate_frames=0;
95 int file_format=0;
96 int save_sif=0; // SIF is made (1) or not made (0)
97 char ecatfile[FILENAME_MAX], dbname[FILENAME_MAX], *cptr;
98 char temp[FILENAME_MAX], outputdir[FILENAME_MAX], dbdir[FILENAME_MAX];
99 IMG img;
100 float fmin, fmax;
101 SIF sif;
102
103
104 /*
105 * Get arguments
106 */
107 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
108 outputdir[0]=ecatfile[0]=dbname[0]=dbdir[0]=(char)0;
109 flipping=anaFlipping();
110 imgInit(&img); sifInit(&sif);
111 /* Options */
112 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') { /* options */
113 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
114 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
115 if(strncasecmp(cptr, "FLIP=", 5)==0) {
116 cptr+=5; if(*cptr=='n' || *cptr=='N') {flipping=0; continue;}
117 else if(*cptr=='y' || *cptr=='Y') {flipping=1; continue;}
118 } else if(strncasecmp(cptr, "FRAMES", 2)==0) {
119 separate_frames=1; continue;
120 } else if(strcasecmp(cptr, "LITTLE")==0) {
121 ana_order=0; continue;
122 } else if(strcasecmp(cptr, "PC")==0) {
123 ana_order=0; continue;
124 } else if(strcasecmp(cptr, "INTEL")==0) {
125 ana_order=0; continue;
126 } else if(strcasecmp(cptr, "BIG")==0) {
127 ana_order=1; continue;
128 } else if(strcasecmp(cptr, "SUN")==0) {
129 ana_order=1; continue;
130 } else if(strcasecmp(cptr, "SPARC")==0) {
131 ana_order=1; continue;
132 } else if(strncasecmp(cptr, "O=", 2)==0) {
133 cptr+=2;
134 if(strlen(cptr)>0) strcpy(outputdir, cptr); else strcpy(outputdir, ".");
135 continue;
136 } else if(strcasecmp(cptr, "SIF")==0) {
137 save_sif=1; continue;
138 }
139 fprintf(stderr, "Error: invalid option '%s'\n", argv[ai]);
140 return(1);
141 } else break;
142
143 /* Print help or version? */
144 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
145 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
146 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
147
148 /* Process other arguments, starting from the first non-option */
149 for(; ai<argc; ai++) {
150 /* Other arguments are ECAT files which must exist */
151 if(access(argv[ai], 0) == -1) {
152 fprintf(stderr, "Error: file %s does not exist\n", argv[ai]);
153 return(1);
154 }
155 if(ffi<1) ffi=ai;
156 fileNr++;
157 }
158
159 /* Is something missing? */
160 if(fileNr<1) {
161 fprintf(stderr, "Error: no ECAT files were specified.\n");
162 return(1);
163 }
164
165
166 /* In verbose mode print arguments and options */
167 if(verbose>1) {
168 printf("flipping := %d\n", flipping);
169 printf("ana_order := %d\n", ana_order);
170 printf("separate_frames := %d\n", separate_frames);
171 printf("save_sif := %d\n", save_sif);
172 printf("outputdir := %s\n", outputdir);
173 printf("fileNr := %d\n", fileNr);
174 }
175 if(verbose>2) IMG_TEST=ANALYZE_TEST=verbose-2; else IMG_TEST=ANALYZE_TEST=0;
176 if(verbose>0) {
177 if(flipping==0) printf("image(s) will not be flipped in z-direction.\n");
178 else printf("image(s) will be flipped in z-direction.\n");
179 }
180
181
182 /*
183 * Process each ECAT file separately
184 */
185 if(verbose>1) printf("processing...\n");
186 fileNr=0;
187 for(ai=ffi; ai<argc; ai++) {
188
189 strcpy(ecatfile, argv[ai]);
190 if(verbose>0) {fprintf(stdout, "%s : \n", ecatfile); fflush(stdout);}
191 imgEmpty(&img);
192 sifEmpty(&sif);
193
194 /*
195 * Make Analyze database name
196 */
197 /* Make output directory name, if it was not given */
198 if(strlen(outputdir)<1) {
199 /* Get input directory */
200 strcpy(dbdir, ecatfile);
201 cptr=strrchr(dbdir, '/'); if(cptr==NULL) cptr=strrchr(dbdir, '\\');
202 if(cptr!=NULL) {cptr++; cptr[0]=(char)0;} else dbdir[0]=(char)0;
203 /* Add default part */
204 if(ana_order==1) strcat(dbdir, "ana_unix_files");
205 else strcat(dbdir, "ana_pc_files");
206 } else {
207 strcpy(dbdir, outputdir);
208 /* Remove trailing slashes */
209 ret=strlen(dbdir)-1;
210 if(dbdir[ret]=='/' || dbdir[ret]=='\\') dbdir[ret]=(char)0;
211 }
212 /* Create the subdirectory */
213 if(access(dbdir, 0) == -1) {
214 if(verbose>0) {
215 fprintf(stdout, " Creating subdirectory %s\n", dbdir);
216 fflush(stdout);
217 }
218#ifdef WIN32
219 ret=mkdir(dbdir);
220#else
221 ret=mkdir(dbdir, 00775);
222#endif
223 if(ret!=0) {
224 fprintf(stderr, " Error: cannot create subdirectory.\n");
225 fflush(stderr); errorNr++; continue;
226 }
227 }
228 /* Combine path and filename */
229 cptr=strrchr(ecatfile, '/'); if(cptr==NULL) cptr=strrchr(ecatfile, '\\');
230 if(cptr==NULL) cptr=ecatfile; else cptr++;
231#ifdef WIN32
232 snprintf(dbname, FILENAME_MAX, "%s\\%s", dbdir, cptr);
233#else
234 snprintf(dbname, FILENAME_MAX, "%s/%s", dbdir, cptr);
235#endif
236 cptr=strrchr(dbname, '.'); if(cptr!=NULL) cptr[0]=(char)0;
237 if(verbose>1) printf(" Analyze db_name: '%s'\n", dbname);
238 /* Check if file exists: Analyze database can be overwritten, but existing
239 ECAT 6.3 image (.img without .hdr) will lead to an error */
240 if(separate_frames!=1 && anaExists(dbname)==0) {
241 strcpy(temp, dbname); strcat(temp, ".img");
242 if(access(temp, 0) != -1) {
243 fprintf(stderr, " Error: %s would be overwritten.\n", temp);
244 fprintf(stdout, " No conversion is done for %s\n", ecatfile);
245 fflush(stdout); fflush(stderr);
246 errorNr++; continue;
247 }
248 }
249
250 /*
251 * Remove possibly existing database
252 */
253 ret=anaRemove(dbname); if(ret) return STATUS_CANNOTERASE;
254
255 /*
256 * Get the global min and max pixel values;
257 * those are needed for Analyze header, and for scaling pixels
258 */
259 if(verbose>1) fprintf(stdout, " searching min and max in %s\n", ecatfile);
260 ret=imgReadMinMax(ecatfile, &fmin, &fmax);
261 if(ret) {
262 fprintf(stderr, "Error: %s\n", imgStatus(ret));
263 if(verbose>3) imgInfo(&img);
264 errorNr++; fflush(stderr); continue;
265 }
266 if(verbose>2)
267 printf(" global_min := %g\n global_max := %g\n", fmin, fmax);
268
269 /*
270 * Get the frame number and allocate memory for SIF, if requested
271 */
272 if(save_sif) {
273 /* Read information from input image for SIF */
274 if(verbose>1) printf(" reading header information\n");
275 ret=imgReadHeader(ecatfile, &img, img._fileFormat);
276 if(ret) {
277 fprintf(stderr, "Error: %s\n", imgStatus(ret));
278 errorNr++; fflush(stderr); continue;
279 }
280 /* Allocate SIF to store frame times */
281 ret=sifSetmem(&sif, img.dimt); if(ret!=0) {
282 fprintf(stderr, "Error: out of memory.\n");
283 errorNr++; fflush(stderr); continue;
284 }
285 sif.colNr=4; sif.version=1;
286 imgEmpty(&img);
287 }
288
289 /*
290 * Conversion of ECAT file, one frame at a time
291 */
292 if(verbose>0) fprintf(stdout, " processing %s\n", ecatfile);
293 fi=0; imgEmpty(&img);
294 while((ret=imgReadFrame(ecatfile, fi+1, &img, 0)) == 0) {
295 if(verbose>1) printf(" frame %d\n", fi+1);
296 /* reverse the flipping/no-flipping in imgWriteAnalyzeFrame, if required */
297 if(flipping!=anaFlipping()) imgFlipPlanes(&img);
298 /* Set the write file format including byte order */
299 if(fi==0) file_format=img._fileFormat; // must be saved to enable reading
300 // the next frame
301 if(ana_order) img._fileFormat=IMG_ANA; else img._fileFormat=IMG_ANA_L;
302 /* Write the frame in Analyze format */
303 if(separate_frames!=1) { // into one Analyze file
304 ret=imgWriteAnalyzeFrame(dbname, fi+1, &img, 0, fmin, fmax);
305 if(ret) anaRemove(dbname); //printf("ret := %d\n", ret);
306 } else { // each frame in a separate Analyze file
307 snprintf(temp, FILENAME_MAX, "%s_fr%03d", dbname, fi+1); // make database name for frame
308 ret=imgMinMax(&img, &fmin, &fmax);
309 if(ret==0) ret=imgWriteAnalyzeFrame(temp, 1, &img, 0, fmin, fmax);
310 if(ret) anaRemove(temp);
311 }
312 if(ret!=STATUS_OK) break;
313 if(verbose>3) printf(" frame written.\n");
314 /* Set SIF contents for this frame, if requested */
315 if(save_sif) {
316 sif.x1[fi]=img.start[0]; sif.x2[fi]=img.end[0];
317 if(fi==0) {
318 /* Set isotope */
319 strcpy(sif.isotope_name, imgIsotope(&img) );
320 /* Set studynumber */
321 strcpy(sif.studynr, img.studyNr);
322 /* Set scan start time */
323 sif.scantime=img.scanStart;
324 }
325 }
326 /* Prepare to the next frame */
327 img._fileFormat=file_format;
328 fi++;
329 } // next frame
330 if(verbose>0) {
331 if(ret==STATUS_NOMATRIX)
332 fprintf(stdout, " %d frame(s) processed.\n", fi);
333 }
334 if(ret!=STATUS_OK && ret!=STATUS_NOMATRIX) {
335 fprintf(stderr, "Error: %s\n", imgStatus(ret)); //if(TEST) imgInfo(&img);
336 errorNr++; fflush(stderr); continue;
337 }
338 imgEmpty(&img);
339
340 /* Save SIF, if requested */
341 if(save_sif) {
342 char temp[FILENAME_MAX+4];
343 sprintf(temp, "%s.sif", dbname);
344 ret=sifWrite(&sif, temp);
345 if(ret!=0) {
346 fprintf(stderr, "Error: cannot write %s\n", temp);
347 errorNr++; fflush(stderr); continue;
348 }
349 sifEmpty(&sif);
350 }
351
352 } /* next file */
353
354 if(errorNr>0) return(errorNr+10);
355 return(0);
356}
357/*****************************************************************************/
358
359/*****************************************************************************/
int anaFlipping()
Definition analyze.c:635
int ANALYZE_TEST
Definition analyze.c:8
int anaExists(const char *dbname)
Definition analyze.c:20
int anaRemove(const char *dbname)
Definition analyze.c:666
int IMG_TEST
Definition img.c:6
void imgInfo(IMG *image)
Definition img.c:359
char * imgStatus(int status_index)
Definition img.c:330
void imgEmpty(IMG *image)
Definition img.c:121
void imgInit(IMG *image)
Definition img.c:60
int imgWriteAnalyzeFrame(const char *dbname, int frame_to_write, IMG *img, int frame_index, float fmin, float fmax)
Definition img_ana.c:751
char * imgIsotope(IMG *img)
Definition imgdecayc.c:76
int imgReadFrame(const char *fname, int frame_to_read, IMG *img, int frame_index)
Definition imgfile.c:269
int imgReadHeader(const char *fname, IMG *img, int format)
Definition imgfile.c:199
void imgFlipPlanes(IMG *img)
Definition imgflips.c:55
int imgReadMinMax(const char *fname, float *fmin, float *fmax)
Definition imgminmax.c:211
int imgMinMax(IMG *img, float *minvalue, float *maxvalue)
Definition imgminmax.c:154
Header file for libtpcimgio.
int sifWrite(SIF *data, char *filename)
Definition sifio.c:145
#define IMG_ANA_L
void sifInit(SIF *data)
Definition sif.c:17
#define IMG_ANA
int sifSetmem(SIF *data, int frameNr)
Definition sif.c:56
void sifEmpty(SIF *data)
Definition sif.c:33
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
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
time_t scanStart
int _fileFormat
unsigned short int dimt
float * start
float * end
char studyNr[MAX_STUDYNR_LEN+1]
double * x1
double * x2
int version
char studynr[MAX_STUDYNR_LEN+1]
time_t scantime
char isotope_name[8]
int colNr