TPCCLIB
Loading...
Searching...
No Matches
ana2ecat.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 <dirent.h>
16#include <sys/stat.h>
17#include <unistd.h>
18#ifdef HAVE_DIRECT_H
19#include <direct.h>
20#endif
21/*****************************************************************************/
22#include "libtpcmisc.h"
23#include "libtpcimgio.h"
24#include "libtpcimgp.h"
25/*****************************************************************************/
26
27/*****************************************************************************/
28/* Local functions */
30 char *dbname, char *ecatfile, int flipping, int scanner_type, float zoom,
31 int verbose
32);
33/*****************************************************************************/
34
35/*****************************************************************************/
36static char *info[] = {
37 "Conversion of Analyze 7.5 database(s) to ECAT 7 image volume or ECAT 6.3",
38 "image format.",
39 " ",
40 "Usage: @P [Options] database",
41 " ",
42 "Options:",
43 " -7 or -6",
44 " Images are written in ECAT 7 (default) or 6.3 format.",
45 " -O=<output path>",
46 " Data directory for ECAT images; by default current working directory.",
47 " -flip=<y|n>",
48 " Override the default and environment variable ANALYZE_FLIP setting",
49 " by always flipping/not flipping image in z-direction (planes).",
50 " If environment variable is not set, then default is y.",
51 " Images are always flipped in x,y-directions.",
52 " -stdoptions", // List standard options like --help, -v, etc
53 " ",
54 "Analyze database can be specified as a path, or filename without extension.",
55 "Program reads time frame information from SIF, if SIF is located in",
56 "the Analyze database directory and if file is named with *.sif extension.",
57 " ",
58 "Example:",
59 "Conversion of all Analyze files in directory S:\\temp\\neuro to ECAT 7",
60 "images in directory C:\\data in PC/Windows:",
61 " C:",
62 " cd \\data",
63 " @P s:\\temp\\neuro",
64 " ",
65 "Specific extensions to Analyze 7.5 format:",
66 " -Scale factor to retain quantitation in image_dimension.funused1",
67 " -Isotope halflife (sec) in image_dimension.funused3;",
68 " this does not imply whether data is corrected for decay or not.",
69 " -String in data_history.descrip tells whether data is corrected for decay;",
70 " 'Decay corrected.' or 'No decay correction.'",
71 " ",
72 "See also: ecat2ana, eframe, sif2ecat, e7emhdr, e7evhdr, flat2img, nii2ecat",
73 " ",
74 "Keywords: image, format conversion, ECAT, Analyze",
75 0};
76/*****************************************************************************/
77
78/*****************************************************************************/
79/* Turn on the globbing of the command line, since it is disabled by default in
80 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
81 In Unix&Linux wildcard command line processing is enabled by default. */
82/*
83#undef _CRT_glob
84#define _CRT_glob -1
85*/
86int _dowildcard = -1;
87/*****************************************************************************/
88
89/*****************************************************************************/
93int main(int argc, char **argv)
94{
95 int ai, help=0, version=0, verbose=1;
96 int ret, n, errorNr=0, flipping, anaNr=0;
97 int scanner_type=0, outFormat=7;
98 float zoom=-1.0;
99 char ecatdir[FILENAME_MAX], dbdir[FILENAME_MAX], ecatfile[FILENAME_MAX];
100 char temp[FILENAME_MAX], dbname[FILENAME_MAX], *cptr;
101 DIR *dp;
102 struct dirent *de;
103
104
105 /*
106 * Get arguments
107 */
108 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
109 ecatdir[0]=dbdir[0]=ecatfile[0]=(char)0;
110 flipping=anaFlipping();
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, "ZOOM=", 5)==0) {
119 cptr+=5; zoom=atof_dpi(cptr); if(zoom>0.0) continue;
120 } else if(strncmp(cptr, "7", 1)==0) {
121 outFormat=7; continue;
122 } else if(strncmp(cptr, "6", 1)==0) {
123 outFormat=6; continue;
124 } else if(strncasecmp(cptr, "SCANNER=", 8)==0) {
125 cptr+=8;
126 if(*cptr=='9') {scanner_type=SCANNER_ECAT931; continue;}
127 if(*cptr=='A' || *cptr=='a') {scanner_type=SCANNER_ADVANCE; continue;}
128 if(strcasecmp(cptr, "HRRT")==0) {
129 scanner_type=SCANNER_HRRT;
130 fprintf(stderr, "Warning: HRRT not fully supported.\n");
131 continue;
132 }
133 if(strncasecmp(cptr, "HR", 2)==0) {scanner_type=SCANNER_HRPLUS; continue;}
134 } else if(strncasecmp(cptr, "O=", 2)==0) {
135 cptr+=2;
136 if(strlen(cptr)>0) strcpy(ecatdir, cptr); else strcpy(ecatdir, ".");
137 continue;
138 }
139 fprintf(stderr, "Error: invalid option '%s'\n", argv[ai]);
140 return(1);
141
142 } else break;
143
144 /* Print help or version? */
145 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
146 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
147 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
148
149 /* Process other arguments, starting from the first non-option */
150 for(; ai<argc; ai++) {
151 if(!dbdir[0]) {
152 strcpy(dbdir, argv[ai]); continue;
153 }
154 fprintf(stderr, "Error: invalid argument '%s'\n", argv[ai]);
155 return(1);
156 }
157
158 /* Is something missing? */
159 if(!dbdir[0]) {
160 fprintf(stderr, "Error: Analyze database was not given.");
161 return(1);
162 }
163 /* Output path is current working path by default */
164 if(!ecatdir[0]) strcpy(ecatdir, ".");
165
166 /* In verbose mode print arguments and options */
167 if(verbose>1) {
168 printf("flipping := %d\n", flipping);
169 printf("zoom := %g\n", zoom);
170 printf("scanner_type := %d\n", scanner_type);
171 printf("outFormat := %d\n", outFormat);
172 printf("ecatdir := %s\n", ecatdir);
173 }
174 if(verbose>2) IMG_TEST=ANALYZE_TEST=verbose-2; else IMG_TEST=ANALYZE_TEST=0;
175 if(verbose>0) {
176 if(flipping==0) printf("image(s) will not be flipped in z-direction.\n");
177 else printf("image(s) will be flipped in z-direction.\n");
178 }
179
180
181 /*
182 * Create output directory, if necessary
183 */
184 if(ecatdir[0]) {
185 if(access(ecatdir, 0) == -1) {
186 if(verbose>0) fprintf(stdout, "Creating subdirectory %s\n", ecatdir);
187#ifdef HAVE_MKDIR2
188 ret=mkdir(ecatdir, 00775);
189#elif defined HAVE_MKDIR1
190 ret=mkdir(ecatdir);
191#elif defined HAVE__MKDIR
192 ret=_mkdir(ecatdir);
193#else
194 ret=1;
195#endif
196 if(ret!=0) {
197 fprintf(stderr, "Error: cannot created subdirectory.\n");
198 return(2);
199 }
200 }
201 } else strcpy(ecatdir, ".");
202
203
204 /*
205 * Read and convert Analyze images
206 */
207 dp=opendir(dbdir);
208
209 if(dp==NULL) {
210 /* This is not a directory, or there is no read permission */
211 /* Check if this is an Analyze database name with or without extension */
212 strcpy(dbname, dbdir); anaRemoveFNameExtension(dbname);
213 if(anaExists(dbname)==0) {
214 fprintf(stderr, "Error: cannot open Analyze image or directory %s\n",
215 dbdir);
216 return(3);
217 }
218 /* Check that this is not actually NIfTI */
219 ret=niftiExists(dbname, NULL, NULL, NULL, NULL, 0, NULL);
220 if(ret!=0) {
221 fprintf(stderr, "Error: %s contains NIfTI, not Analyze image\n", dbdir);
222 return(3);
223 }
224 /* It seems to be an Analyze file, so proceed with conversion */
225
226 /*
227 * Make ECAT filename
228 */
229 cptr=strrchr(dbname, '/'); if(cptr==NULL) cptr=strrchr(dbname, '\\');
230 if(cptr!=NULL) cptr++; else cptr=dbname;
231#ifdef WIN32
232 snprintf(ecatfile, FILENAME_MAX, "%s\\%s", ecatdir, cptr);
233#else
234 snprintf(ecatfile, FILENAME_MAX, "%s/%s", ecatdir, cptr);
235#endif
236 if(outFormat==6) strcat(ecatfile, ".img"); else strcat(ecatfile, ".v");
237 if(verbose>2) printf(" ECAT filename: '%s'\n", ecatfile);
238 /* Check if file exists: ECAT 6.3 file (without .hdr) can be overwritten,
239 but existing Analyze file (.img with .hdr) should lead to an error */
240 strcpy(temp, ecatfile); anaRemoveFNameExtension(temp);
241 if(anaExists(temp)) {
242 fprintf(stderr, " Error: %s would be overwritten.\n", ecatfile);
243 fprintf(stdout, " No conversion is done for %s\n", dbname);
244 fflush(stdout); fflush(stderr);
245 errorNr++; return(4);
246 }
247 /* Remove existing ECAT file */
248 if(access(ecatfile, 0)!=-1 && remove(ecatfile)!=0) {
249 fprintf(stderr, "Error: cannot overwrite %s\n", ecatfile);
250 errorNr++; return(5);
251 }
252
253
254 /*
255 * Read Analyze file and write ECAT image frame-by-frame
256 */
257 if(verbose>0) fprintf(stdout, "%s :\n", dbname);
258 anaNr++;
259 if(verbose>0) printf(" processing Analyze image\n");
260 ret=imgAnalyzeToEcat(dbname, ecatfile, flipping, scanner_type, zoom,
261 verbose-1);
262 if(ret!=STATUS_OK) {
263 fprintf(stderr, "Error: %s\n", imgStatus(ret)); //if(TEST) imgInfo(&img);
264 return(11);
265 }
266 if(verbose>0)
267 fprintf(stdout, " Image saved in ECAT format in %s\n", ecatfile);
268 return(0); // finished.
269 }
270
271
272 /* Directory was previously opened succesfully: */
273 /* Conversion of all Analyzes images in the specified path */
274 while((de=readdir(dp))!=NULL) {
275 if(verbose>6) printf("'%s'\n", de->d_name);
276 /* Remove trailing slashes */
277 ret=strlen(dbdir)-1;
278 if(dbdir[ret]=='/' || dbdir[ret]=='\\') dbdir[ret]=(char)0;
279
280 /*
281 * Make Analyze database name
282 */
283 /* Check that filename extension is .hdr */
284 n=strlen(de->d_name);
285 if(n<5 || strcmp((de->d_name)+n-4, ".hdr")!=0) continue;
286 /* Make Analyze database name */
287 strcpy(temp, de->d_name); temp[n-4]=(char)0;
288#ifdef WIN32
289 snprintf(dbname, FILENAME_MAX, "%s\\%s", dbdir, temp);
290#else
291 snprintf(dbname, FILENAME_MAX, "%s/%s", dbdir, temp);
292#endif
293 /* Check that Analyze database exists (also .img) */
294 if(anaExists(dbname)==0) continue;
295 if(verbose>0) fprintf(stdout, "%s :\n", dbname);
296 anaNr++;
297 /* Check that this is not actually NIfTI */
298 ret=niftiExists(dbname, NULL, NULL, NULL, NULL, 0, NULL);
299 if(ret!=0) {
300 fprintf(stderr, " Error: %s is NIfTI image\n", dbname);
301 continue;
302 }
303
304 /*
305 * Make ECAT filename
306 */
307#ifdef WIN32
308 snprintf(ecatfile, FILENAME_MAX, "%s\\%s", ecatdir, temp);
309#else
310 snprintf(ecatfile, FILENAME_MAX, "%s/%s", ecatdir, temp);
311#endif
312 if(outFormat==6) strcat(ecatfile, ".img"); else strcat(ecatfile, ".v");
313 if(verbose>1) printf(" ECAT filename: '%s'\n", ecatfile);
314
315
316 /* Check if file exists: ECAT 6.3 file (without .hdr) can be overwritten,
317 but existing Analyze file (.img with .hdr) should lead to an error */
318 strcpy(temp, ecatfile); anaRemoveFNameExtension(temp);
319 if(anaExists(temp)) {
320 fprintf(stderr, " Error: %s would be overwritten.\n", ecatfile);
321 fprintf(stdout, " No conversion is done for %s\n", dbname);
322 fflush(stdout); fflush(stderr);
323 errorNr++; continue;
324 }
325
326 /* Remove existing ECAT file */
327 if(access(ecatfile, 0)!=-1 && remove(ecatfile)!=0) {
328 fprintf(stderr, "Error: cannot overwrite %s\n", ecatfile);
329 errorNr++; continue;
330 }
331
332 /*
333 * Read Analyze file and write ECAT image frame-by-frame
334 */
335 if(verbose>0) printf(" processing Analyze image\n");
336 ret=imgAnalyzeToEcat(dbname, ecatfile, flipping, scanner_type, zoom,
337 verbose-1);
338 if(ret!=STATUS_OK) {
339 fprintf(stderr, "Error: %s\n", imgStatus(ret)); //if(TEST) imgInfo(&img);
340 errorNr++; continue;
341 }
342 if(verbose>0)
343 fprintf(stdout, " Image saved in ECAT format in %s\n", ecatfile);
344
345 } /* next Analyze image */
346 closedir(dp);
347 if(anaNr==0) {
348 fprintf(stderr, "Error: no Analyze files were found in %s\n", dbdir);
349 return(2);
350 }
351
352 return(errorNr);
353}
354/*****************************************************************************/
355
356/*****************************************************************************/
358
364 char *dbname,
366 char *ecatfile,
368 int flipping,
370 int scanner_type,
372 float zoom,
374 int verbose
375) {
376 IMG img;
377 int zi, fi, ret, file_format=0;
378
379 if(verbose>0) printf("\nimgAnalyzeToEcat(%s, %s)\n", dbname, ecatfile);
380 /* Check the arguments */
381 if(dbname==NULL || ecatfile==NULL) return STATUS_FAULT;
382
383 /* Read the first frame */
384 imgInit(&img); fi=0;
385 ret=imgReadAnalyzeFirstFrame(dbname, &img);
386 if(ret!=STATUS_OK) {imgEmpty(&img); return ret;}
387 do {
388 fi++;
389 if(verbose>1) printf(" frame %d\n", fi);
390 /* Set header information */
391 if(fi==0) // must be saved for reading next frame
392 file_format=img._fileFormat;
393 if(scanner_type>0) imgSetScanner(&img, scanner_type);
394 if(zoom>0.0) img.zoom=zoom;
395 for(zi=0; zi<img.dimz; zi++) img.planeNumber[zi]=zi+1;
396 if(verbose>10) imgInfo(&img);
397 if(flipping!=anaFlipping()) imgFlipPlanes(&img);
398 /* Write the frame in ECAT format */
399 img._fileFormat=0;
400 ret=imgWriteFrame(ecatfile, fi, &img, 0); //printf("ret := %d\n", ret);
401 if(ret!=STATUS_OK) break;
402 if(verbose>2) printf(" frame written.\n");
403 /* Try to read the next frame */
404 img._fileFormat=file_format;
405 ret=imgReadAnalyzeFrame(dbname, fi+1, &img, 0);
406 } while(ret==0);
407 imgEmpty(&img);
408 if(verbose>0 && ret==STATUS_NOMATRIX) {
409 fprintf(stdout, " %d frame(s) processed.\n", fi);
410 }
411 if(ret!=STATUS_OK && ret!=STATUS_NOMATRIX) {
412 remove(ecatfile); return ret;
413 }
414 /*if(verbose>2)
415 fprintf(stdout, " Image saved in ECAT format in %s\n", ecatfile);*/
416 return STATUS_OK;
417}
418/*****************************************************************************/
419
420/*****************************************************************************/
int imgAnalyzeToEcat(char *dbname, char *ecatfile, int flipping, int scanner_type, float zoom, int verbose)
Definition ana2ecat.c:362
int anaFlipping()
Definition analyze.c:635
void anaRemoveFNameExtension(char *fname)
Definition analyze.c:687
int ANALYZE_TEST
Definition analyze.c:8
int anaExists(const char *dbname)
Definition analyze.c:17
double atof_dpi(char *str)
Definition decpoint.c:59
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 imgReadAnalyzeFirstFrame(const char *fname, IMG *img)
Definition img_ana.c:592
int imgReadAnalyzeFrame(const char *fname, int frame_to_read, IMG *img, int frame_index)
Definition img_ana.c:639
int imgWriteFrame(const char *fname, int frame_to_write, IMG *img, int frame_index)
Definition imgfile.c:392
void imgFlipPlanes(IMG *img)
Definition imgflips.c:55
int imgSetScanner(IMG *img, int scanner_type)
Definition imgscanner.c:14
Header file for libtpcimgio.
#define SCANNER_ADVANCE
#define SCANNER_HRRT
int niftiExists(const char *dbname, char *hdrfile, char *imgile, char *siffile, NIFTI_DSR *header, int verbose, char *status)
Definition nifti.c:160
#define SCANNER_HRPLUS
#define SCANNER_ECAT931
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
int _fileFormat
int * planeNumber
unsigned short int dimz
float zoom