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