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