TPCCLIB
Loading...
Searching...
No Matches
nii2ecat.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 scanner_type, float zoom, int verbose);
31/*****************************************************************************/
32
33/*****************************************************************************/
34static char *info[] = {
35 "Conversion of NIfTI-1 PET image database(s) to ECAT 7 image volume",
36 "image format.",
37 "Conversion can also be done using ImageConverter (.NET application).",
38 " ",
39 "Usage: @P [Options] database",
40 " ",
41 "Options:",
42 " -O=<output path>",
43 " Data directory for ECAT images; by default current working directory.",
44 " -stdoptions", // List standard options like --help, -v, etc
45 " ",
46 "NIfTI database can be specified as a path, containing one or more databases,",
47 "or filename of one NIfTI database without extension.",
48 "NIfTI file(s) must be named as *.nii (single format) or *.hdr and *.img",
49 "(dual format).",
50 "Program reads time frame information from SIF, if SIF is located in",
51 "the database directory and if file is named with *.sif extension.",
52 " ",
53 "Example:",
54 "Conversion of all NIfTI images in directory S:\\temp\\neuro to ECAT 7",
55 "images in directory C:\\data in PC/Windows:",
56 " C:",
57 " cd \\data",
58 " @P s:\\temp\\neuro",
59 " ",
60 "See also: ecat2nii, eframe, sif2ecat, e7emhdr, e7evhdr, flat2img, ana2ecat",
61 " ",
62 "Keywords: image, format conversion, ECAT, NIfTI",
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, n, errorNr=0, niiNr=0;
85 int scanner_type=0;
86 float zoom=-1.0;
87 char ecatdir[FILENAME_MAX], dbdir[FILENAME_MAX], ecatfile[FILENAME_MAX];
88 char temp[FILENAME_MAX], dbname[FILENAME_MAX], *cptr;
89 DIR *dp;
90 struct dirent *de;
91
92
93 /*
94 * Get arguments
95 */
96 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
97 ecatdir[0]=dbdir[0]=(char)0;
98 /* Options */
99 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') { /* options */
100 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
101 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
102 if(strncasecmp(cptr, "ZOOM=", 5)==0) {
103 cptr+=5; zoom=atof_dpi(cptr); if(zoom>0.0) continue;
104 } else if(strncasecmp(cptr, "SCANNER=", 8)==0) {
105 cptr+=8;
106 if(*cptr=='9') {scanner_type=SCANNER_ECAT931; continue;}
107 if(*cptr=='A' || *cptr=='a') {scanner_type=SCANNER_ADVANCE; continue;}
108 if(strcasecmp(cptr, "HRRT")==0) {
109 scanner_type=SCANNER_HRRT;
110 fprintf(stderr, "Warning: HRRT not fully supported.\n");
111 continue;
112 }
113 if(strncasecmp(cptr, "HR", 2)==0) {scanner_type=SCANNER_HRPLUS; continue;}
114 } else if(strncasecmp(cptr, "O=", 2)==0) {
115 cptr+=2;
116 if(strlen(cptr)>0) strcpy(ecatdir, cptr); else strcpy(ecatdir, ".");
117 continue;
118 }
119 fprintf(stderr, "Error: invalid option '%s'\n", argv[ai]);
120 return(1);
121
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 for(; ai<argc; ai++) {
131 if(!dbdir[0]) {
132 strcpy(dbdir, argv[ai]); continue;
133 }
134 fprintf(stderr, "Error: invalid argument '%s'\n", argv[ai]);
135 return(1);
136 }
137
138 /* Is something missing? */
139 if(!dbdir[0]) {
140 fprintf(stderr, "Error: NIfTI image was not given.");
141 return(1);
142 }
143 /* Ouput path is current working path by default */
144 if(!ecatdir[0]) strcpy(ecatdir, ".");
145
146 /* In verbose mode print arguments and options */
147 if(verbose>1) {
148 printf("program := %s\n", argv[0]);
149 printf("zoom := %g\n", zoom);
150 printf("scanner_type := %d\n", scanner_type);
151 printf("ecatdir := %s\n", ecatdir);
152 }
153 if(verbose>2) IMG_TEST=verbose-3; else IMG_TEST=0;
154
155
156 /*
157 * Create output directory, if necessary
158 */
159 if(ecatdir[0]) {
160 if(access(ecatdir, 0) == -1) {
161 if(verbose>0) fprintf(stdout, "Creating subdirectory %s\n", ecatdir);
162#ifdef HAVE_MKDIR2
163 ret=mkdir(ecatdir, 00775);
164#elif defined HAVE_MKDIR1
165 ret=mkdir(ecatdir);
166#elif defined HAVE__MKDIR
167 ret=_mkdir(ecatdir);
168#else
169 ret=1;
170#endif
171 if(ret!=0) {
172 fprintf(stderr, "Error: cannot created subdirectory.\n");
173 return(2);
174 }
175 }
176 } else strcpy(ecatdir, ".");
177
178
179 /*
180 * Read and convert NIfTI images
181 */
182 dp=opendir(dbdir);
183
184 if(dp==NULL) {
185 /* This is not a directory, or there is no read permission */
186 /* Check if this is an NIfTI database name with or without extension */
187 strcpy(dbname, dbdir); niftiRemoveFNameExtension(dbname);
188 ret=niftiExists(dbname, NULL, NULL, NULL, NULL, verbose-2, temp);
189 if(ret==0) {
190 fprintf(stderr, "Error: cannot open NIfTI image or directory %s (%s)\n",
191 dbdir, temp);
192 return(3);
193 } else if(ret==1)
194 fprintf(stderr, "Warning: no SIF for %s; frame times not available.\n",
195 dbname);
196 /* It seems to be an NIfTI database, therefore convert it */
197
198 /*
199 * Make ECAT filename
200 */
201 cptr=strrchr(dbname, '/'); if(cptr==NULL) cptr=strrchr(dbname, '\\');
202 if(cptr!=NULL) cptr++; else cptr=dbname;
203#ifdef WIN32
204 snprintf(ecatfile, FILENAME_MAX, "%s\\%s", ecatdir, cptr);
205#else
206 snprintf(ecatfile, FILENAME_MAX, "%s/%s", ecatdir, cptr);
207#endif
208 strcat(ecatfile, ".v");
209 if(verbose>2) printf(" ECAT filename: '%s'\n", ecatfile);
210 /* Remove existing ECAT file */
211 if(access(ecatfile, 0)!=-1 && remove(ecatfile)!=0) {
212 fprintf(stderr, "Error: cannot overwrite %s\n", ecatfile);
213 errorNr++; return(5);
214 }
215
216
217 /*
218 * Read NIfTI file and write ECAT image frame-by-frame
219 */
220 if(verbose>0) fprintf(stdout, "%s :\n", dbname);
221 niiNr++;
222 if(verbose>0) printf(" processing NIfTI image\n");
223 ret=imgNiftiToEcat(dbname, ecatfile, scanner_type, zoom, verbose-1);
224 if(ret!=STATUS_OK) {
225 fprintf(stderr, "Error: %s\n", imgStatus(ret));
226 return(11);
227 }
228 if(verbose>0)
229 fprintf(stdout, " Image saved in ECAT format in %s\n", ecatfile);
230 return(0); // finished.
231 }
232
233
234 /* Directory was previously opened succesfully: */
235 /* Conversion of all NIfTI images in the specified path */
236 while((de=readdir(dp))!=NULL) {
237 if(verbose>6) printf("'%s'\n", de->d_name);
238 /* Remove trailing slashes */
239 ret=strlen(dbdir)-1;
240 if(dbdir[ret]=='/' || dbdir[ret]=='\\') dbdir[ret]=(char)0;
241
242 /*
243 * Make NIfTI database name
244 */
245
246 /* Check that filename extension is .hdr or .nii */
247 n=strlen(de->d_name);
248 if(n<5) continue;
249 cptr=(de->d_name)+n-4;
250 if(strcasecmp(cptr, ".hdr")!=0 && strcasecmp(cptr, ".nii")!=0) continue;
251 /* Make database name */
252 strcpy(temp, de->d_name); temp[n-4]=(char)0;
253#ifdef WIN32
254 snprintf(dbname, FILENAME_MAX, "%s\\%s", dbdir, temp);
255#else
256 snprintf(dbname, FILENAME_MAX, "%s/%s", dbdir, temp);
257#endif
258 /* Check that NIfTI database exists */
259 ret=niftiExists(dbname, NULL, NULL, NULL, NULL, verbose-2, NULL);
260 if(ret==0) continue;
261 if(verbose>0) fprintf(stdout, "%s :\n", dbname);
262 niiNr++;
263 if(ret==2) fprintf(stderr," Warning: no SIF.\n");
264 fflush(stdout); fflush(stderr);
265
266 /*
267 * Make ECAT filename
268 */
269#ifdef WIN32
270 snprintf(ecatfile, FILENAME_MAX-2, "%s\\%s", ecatdir, temp);
271#else
272 snprintf(ecatfile, FILENAME_MAX-2, "%s/%s", ecatdir, temp);
273#endif
274 strcat(ecatfile, ".v");
275 if(verbose>1) printf(" ECAT filename: '%s'\n", ecatfile);
276
277 /* Remove existing ECAT file */
278 if(access(ecatfile, 0)!=-1 && remove(ecatfile)!=0) {
279 fprintf(stderr, "Error: cannot overwrite %s\n", ecatfile);
280 errorNr++; continue;
281 }
282
283 /*
284 * Read NIfTI file and write ECAT image frame-by-frame
285 */
286 if(verbose>0) printf(" processing NIfTI image\n");
287 ret=imgNiftiToEcat(dbname, ecatfile, scanner_type, zoom, verbose-1);
288 if(ret!=STATUS_OK) {
289 fprintf(stderr, "Error: %s\n", imgStatus(ret));
290 errorNr++; continue;
291 }
292 if(verbose>0) fprintf(stdout, " Image saved in ECAT format in %s\n",
293 ecatfile);
294
295 } /* next NIfTI image */
296 closedir(dp);
297 if(niiNr==0) {
298 fprintf(stderr, "Error: no NIfTI images were found in %s\n", dbdir);
299 return(2);
300 }
301
302 return(errorNr);
303}
304/*****************************************************************************/
305
306/*****************************************************************************/
308
314 char *dbname,
316 char *ecatfile,
318 int scanner_type,
320 float zoom,
322 int verbose
323) {
324 IMG img;
325 int zi, fi, ret, file_format=0;
326
327 if(verbose>0) printf("\nimgNiftiToEcat(%s, %s)\n", dbname, ecatfile);
328 /* Check the arguments */
329 if(dbname==NULL || ecatfile==NULL) return STATUS_FAULT;
330
331 /* Read the first frame */
332 imgInit(&img); fi=0;
333 if(verbose>1) printf(" reading the first frame\n");
334 ret=imgReadNiftiFirstFrame(dbname, &img, verbose-1);
335 if(ret!=STATUS_OK) {imgEmpty(&img); return ret;}
336 /* ... and then the rest of the frames */
337 do {
338 fi++;
339 if(verbose>1) printf(" frame %d\n", fi);
340 /* Set header information */
341 if(fi==0) // must be saved for reading next frame
342 file_format=img._fileFormat;
343 if(scanner_type>0) imgSetScanner(&img, scanner_type);
344 if(zoom>0.0) img.zoom=zoom;
345 for(zi=0; zi<img.dimz; zi++) img.planeNumber[zi]=zi+1;
346 if(verbose>15) imgInfo(&img);
347 /* Write the frame in ECAT 7 format */
349 ret=imgWriteFrame(ecatfile, fi, &img, 0); //printf("ret := %d\n", ret);
350 if(ret!=STATUS_OK) break;
351 if(verbose>1) printf(" frame written.\n");
352 /* Try to read the next frame */
353 img._fileFormat=file_format;
354 ret=imgReadNiftiFrame(dbname, fi+1, &img, 0, verbose-1);
355 } while(ret==0);
356 imgEmpty(&img);
357 if(verbose>0 && ret==STATUS_NOMATRIX) {
358 fprintf(stdout, " %d frame(s) processed.\n", fi);
359 }
360 if(ret!=STATUS_OK && ret!=STATUS_NOMATRIX) {
361 remove(ecatfile); return ret;
362 }
363 /*if(verbose>2)
364 fprintf(stdout, " Image saved in ECAT format in %s\n", ecatfile);*/
365 return STATUS_OK;
366}
367/*****************************************************************************/
368
369/*****************************************************************************/
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 imgReadNiftiFirstFrame(const char *filename, IMG *img, int verbose)
Definition img_nii.c:78
int imgReadNiftiFrame(const char *filename, int frame_to_read, IMG *img, int frame_index, int verbose)
Definition img_nii.c:311
int imgWriteFrame(const char *fname, int frame_to_write, IMG *img, int frame_index)
Definition imgfile.c:392
int imgSetScanner(IMG *img, int scanner_type)
Definition imgscanner.c:14
Header file for libtpcimgio.
#define IMG_E7
#define SCANNER_ADVANCE
#define SCANNER_HRRT
void niftiRemoveFNameExtension(char *fname)
Definition nifti.c:23
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 imgNiftiToEcat(char *dbname, char *ecatfile, int scanner_type, float zoom, int verbose)
Definition nii2ecat.c:312
int _fileFormat
int * planeNumber
unsigned short int dimz
float zoom