TPCCLIB
Loading...
Searching...
No Matches
efixplnr.c
Go to the documentation of this file.
1
9/*****************************************************************************/
10#include "tpcclibConfig.h"
11/*****************************************************************************/
12#include <stdio.h>
13#include <stdlib.h>
14#include <math.h>
15#include <string.h>
16#include <time.h>
17/*****************************************************************************/
18#include "libtpcmisc.h"
19#include "libtpcimgio.h"
20/*****************************************************************************/
21
22/*****************************************************************************/
23static char *info[] = {
24 "Convert ECAT 6.3 or 7.x matrix numbers (planes, frames, gates, and/or beds)",
25 "into continuous sequence, for instance, plane numbers 8,10,12 to 1,2,3.",
26 " ",
27 "Usage: @P [Options] ecatfile(s)",
28 " ",
29 "Options:",
30 " -planes=<Y|n>",
31 " Plane numbers are changed to be continuous and start from 1 (Y, default)",
32 " or not changed (n).",
33 " -frames=<y|N>",
34 " Frame numbers are changed to be continuous and start from 1 (y)",
35 " or not changed (N, default).",
36 " -gates=<y|N>",
37 " Gate numbers are changed to be continuous and start from 1 (y)",
38 " or not changed (N, default).",
39 " -beds=<y|N>",
40 " Bed numbers are changed to be continuous and start from 0 (y)",
41 " or not changed (N, default).",
42 " -stdoptions", // List standard options like --help, -v, etc
43 " ",
44 "See also: esplit, lmlist, e7vplavg, e63mreg, img2flat, ecat2ana",
45 " ",
46 "Keywords: ECAT, matrixlist, image, sinogram, plane, frame, tool",
47 0};
48/*****************************************************************************/
49
50/*****************************************************************************/
51/* Turn on the globbing of the command line, since it is disabled by default in
52 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
53 In Unix&Linux wildcard command line processing is enabled by default. */
54/*
55#undef _CRT_glob
56#define _CRT_glob -1
57*/
58int _dowildcard = -1;
59/*****************************************************************************/
60
61/*****************************************************************************/
63
73 MATRIXLIST *ml,
75 FILE *fp,
77 char *resfile
78) {
79 FILE *fp2=NULL;
80 int m, blkNr, nxtblk, bi;
81 char buf[MatBLKSIZE];
82
83
84 if(mh==NULL || ml==NULL || fp==NULL || resfile==NULL) return STATUS_FAULT;
85 /* Open output file */
86 fp2=ecat63Create(resfile, mh); if(fp2==NULL) return STATUS_NOWRITEPERM;
87 /* Copy the matrices */
88 for(m=0; m<ml->matrixNr; m++) if(ml->matdir[m].matstat==1) {
89 blkNr=1+ml->matdir[m].endblk-ml->matdir[m].strtblk;
90 /* Get block number for matrix header and data */
91 nxtblk=ecat63Matenter(fp2, ml->matdir[m].matnum, blkNr-1);
92 if(nxtblk<1) {fclose(fp2); remove(resfile); return STATUS_INVALIDMATLIST;}
93 /* Copy each block */
94 for(bi=ml->matdir[m].strtblk; bi<=ml->matdir[m].endblk; bi++) {
95 /* Read block */
96 fseek(fp, (bi-1)*MatBLKSIZE, SEEK_SET);
97 if(ftell(fp)!=(bi-1)*MatBLKSIZE) {
98 fclose(fp2); remove(resfile); return STATUS_NOMATRIX;}
99 if(fread(buf, MatBLKSIZE, 1, fp)<1) {
100 fclose(fp2); remove(resfile); return STATUS_NOMATRIX;}
101 /* Write block */
102 fseek(fp2, (nxtblk-1)*MatBLKSIZE, SEEK_SET);
103 if(ftell(fp2)!=(nxtblk-1)*MatBLKSIZE) {
104 fclose(fp2); remove(resfile); return STATUS_INVALIDMATLIST;}
105 if(fwrite(buf, 1, MatBLKSIZE, fp2)<1) {
106 fclose(fp2); remove(resfile); return STATUS_DISKFULL;}
107 nxtblk++;
108 }
109 }
110 fclose(fp2);
111 return STATUS_OK;
112}
113/*****************************************************************************/
114
115/*****************************************************************************/
127 FILE *fp,
129 char *resfile
130) {
131 FILE *fp2=NULL;
132 int m, blkNr, nxtblk, bi;
133 char buf[MatBLKSIZE];
134
135
136 if(mh==NULL || ml==NULL || fp==NULL || resfile==NULL) return STATUS_FAULT;
137 /* Open output file */
138 fp2=ecat7Create(resfile, mh); if(fp2==NULL) return STATUS_NOWRITEPERM;
139 /* Copy the matrices */
140 for(m=0; m<ml->matrixNr; m++) if(ml->matdir[m].status==1) {
141 blkNr=1+ml->matdir[m].endblk-ml->matdir[m].strtblk;
142 /* Get block number for matrix header and data */
143 nxtblk=ecat7EnterMatrix(fp2, ml->matdir[m].id, blkNr-1);
144 if(nxtblk<1) {fclose(fp2); remove(resfile); return STATUS_INVALIDMATLIST;}
145 /* Copy each block */
146 for(bi=ml->matdir[m].strtblk; bi<=ml->matdir[m].endblk; bi++) {
147 /* Read block */
148 fseek(fp, (bi-1)*MatBLKSIZE, SEEK_SET);
149 if(ftell(fp)!=(bi-1)*MatBLKSIZE) {
150 fclose(fp2); remove(resfile); return STATUS_NOMATRIX;}
151 if(fread(buf, MatBLKSIZE, 1, fp)<1) {
152 fclose(fp2); remove(resfile); return STATUS_NOMATRIX;}
153 /* Write block */
154 fseek(fp2, (nxtblk-1)*MatBLKSIZE, SEEK_SET);
155 if(ftell(fp2)!=(nxtblk-1)*MatBLKSIZE) {
156 fclose(fp2); remove(resfile); return STATUS_INVALIDMATLIST;}
157 if(fwrite(buf, 1, MatBLKSIZE, fp2)<1) {
158 fclose(fp2); remove(resfile); return STATUS_DISKFULL;}
159 nxtblk++;
160 }
161 }
162 fclose(fp2);
163 return STATUS_OK;
164}
165/*****************************************************************************/
166
167/*****************************************************************************/
174 char *ecatfile,
176 int do_planes,
178 int do_frames,
180 int do_gates,
182 int do_beds,
184 int verbose
185) {
186 int ret;
187 int ecat_format=0; // 6 or 7
188 char outfile[FILENAME_MAX];
189 FILE *fp=NULL;
190 ECAT7_mainheader ecat7_main_header;
191 ECAT63_mainheader ecat63_main_header;
193 MATRIXLIST ml6;
194
195
196 /*
197 * Open the file
198 */
199 if(verbose>1) printf(" opening %s in binary format\n", ecatfile);
200 if((fp=fopen(ecatfile, "rb")) == NULL) {
201 fprintf(stderr, "Error: cannot read file %s\n", ecatfile);
202 return(2);
203 }
204
205 /*
206 * Determine the file format (ECAT 6 or 7)
207 * Read mainheader
208 */
209 if(verbose>2) printf(" reading main header\n");
210 ecat_format=0;
211 /* Try to read ECAT 7.x main header */
212 ret=ecat7ReadMainheader(fp, &ecat7_main_header);
213 if(ret) {
214 fprintf(stderr, "Error: unsupported file format %s\n", ecatfile);
215 fclose(fp); return(3);
216 }
217 /* If header could be read, check for magic number */
218 if(strncmp(ecat7_main_header.magic_number, ECAT7V_MAGICNR, 7)==0) {
219 ecat_format=7;
220 } else { // maybe this is ECAT 6.3
221 ret=ecat63ReadMainheader(fp, &ecat63_main_header);
222 if(ret==0) ecat_format=6;
223 }
224 if(verbose>2) printf(" ecat_format := %d\n", ecat_format);
225
226 /*
227 * Read matrixlist
228 */
229 if(verbose>1) printf(" reading matrix list\n");
230 ecat7InitMatlist(&ml7);
231 ecat63InitMatlist(&ml6);
232 if(ecat_format==7) {
233 ret=ecat7ReadMatlist(fp, &ml7, verbose-1);
234 if(ret==0 && (ml7.matrixNr<1 || ecat7CheckMatlist(&ml7))) ret=99;
235 } else if(ecat_format==6) {
236 ret=ecat63ReadMatlist(fp, &ml6, verbose-1);
237 if(ret==0 && (ml6.matrixNr<1 || ecat63CheckMatlist(&ml6))) ret=99;
238 } else {
239 fprintf(stderr, "Error: unsupported file format %s\n", ecatfile);
240 fclose(fp); return(3);
241 }
242 if(ret) {
243 fprintf(stderr, "Error %d: invalid matrix list.\n", ret);
244 fclose(fp); return(4);
245 }
246
247 /*
248 * Fix matrixlist
249 */
250 if(verbose>1) printf(" fixing matrix list\n");
251 if(ecat_format==6) {
252 if(verbose>2) ecat63PrintMatlist(&ml6); // print original matrixlist
253 ecat63GatherMatlist(&ml6, do_planes, do_frames, do_gates, do_beds);
254 if(verbose>2) ecat63PrintMatlist(&ml6); // print fixed matrixlist
255 } else {
256 if(verbose>2) ecat7PrintMatlist(&ml7); // print original matrixlist
257 ecat7GatherMatlist(&ml7, do_planes, do_frames, do_gates, do_beds);
258 if(verbose>2) ecat7PrintMatlist(&ml7); // print fixed matrixlist
259 }
260
261 /*
262 * Replace ECAT data with new matrixlist:
263 * Write data with new matrix list in temp file
264 * Delete original file
265 * Rename temp file to original filename
266 */
267 if(verbose>1) printf(" writing fixed data in temporary file\n");
268 /* Make tempfile name */
269 strcpy(outfile, ecatfile); strcat(outfile, "_efixplnr");
270 if(verbose>3) printf(" tempfile := %s\n", outfile);
271 if(ecat_format==6) {
272 /* Update num_* in mainheader */
273 ecat63GetNums(&ml6,
274 &ecat63_main_header.num_planes, // strict 2D format
275 &ecat63_main_header.num_frames,
276 &ecat63_main_header.num_gates,
277 &ecat63_main_header.num_bed_pos);
278 ret=ecat63CopyFile(&ecat63_main_header, &ml6, fp, outfile);
279 } else {
280 /* Update num_* in mainheader */
281 ecat7GetNums(&ml7, &ecat7_main_header, fp,
282 &ecat7_main_header.num_planes,
283 &ecat7_main_header.num_frames,
284 &ecat7_main_header.num_gates,
285 &ecat7_main_header.num_bed_pos);
286 ret=ecat7CopyFile(&ecat7_main_header, &ml7, fp, outfile);
287 }
288 fclose(fp);
289 if(ret) {fprintf(stderr, "Error: %s\n", imgStatus(ret)); return(11);}
290 /* Remove input file */
291 if(verbose>1) printf(" removing %s\n", ecatfile);
292 ret=remove(ecatfile); if(ret) {
293 fprintf(stderr, "Error: cannot overwrite file %s\n", ecatfile);
294 return(13);
295 }
296 /* Rename temp file to input name */
297 if(verbose>1) printf(" renaming %s to %s\n", outfile, ecatfile);
298 ret=rename(outfile, ecatfile); if(ret) {
299 fprintf(stderr, "Error: could not rename %s to %s\n", outfile, ecatfile);
300 return(15);
301 }
302
303 return(0);
304}
305/*****************************************************************************/
306
307/*****************************************************************************/
309
312int main(int argc, char **argv)
313{
314 int ai, help=0, version=0, verbose=1;
315 int ret, ffi=0, fileNr=0, okNr=0;
316 short int do_planes=1, do_frames=0, do_gates=0, do_beds=0;
317 char *cptr;
318 char ecatfile[FILENAME_MAX];
319
320
321 /*
322 * Get arguments
323 */
324 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
325 ecatfile[0]=(char)0;
326 /* Options */
327 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') { /* options */
328 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
329 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
330 if(strncasecmp(cptr, "PLANES=", 7)==0) {
331 cptr+=7;
332 if(strncasecmp(cptr, "YES", 1)==0 || strcasecmp(cptr, "ON")==0) {
333 do_planes=1; continue;}
334 if(strncasecmp(cptr, "NO", 1)==0 || strcasecmp(cptr, "OFF")==0) {
335 do_planes=0; continue;}
336 } else if(strncasecmp(cptr, "FRAMES=", 7)==0) {
337 cptr+=7;
338 if(strncasecmp(cptr, "YES", 1)==0 || strcasecmp(cptr, "ON")==0) {
339 do_frames=1; continue;}
340 if(strncasecmp(cptr, "NO", 1)==0 || strcasecmp(cptr, "OFF")==0) {
341 do_frames=0; continue;}
342 } else if(strncasecmp(cptr, "GATES=", 6)==0) {
343 cptr+=6;
344 if(strncasecmp(cptr, "YES", 1)==0 || strcasecmp(cptr, "ON")==0) {
345 do_gates=1; continue;}
346 if(strncasecmp(cptr, "NO", 1)==0 || strcasecmp(cptr, "OFF")==0) {
347 do_gates=0; continue;}
348 } else if(strncasecmp(cptr, "BEDS=", 5)==0) {
349 cptr+=5;
350 if(strncasecmp(cptr, "YES", 1)==0 || strcasecmp(cptr, "ON")==0) {
351 do_beds=1; continue;}
352 if(strncasecmp(cptr, "NO", 1)==0 || strcasecmp(cptr, "OFF")==0) {
353 do_beds=0; continue;}
354 }
355 fprintf(stderr, "Error: invalid option '%s'\n", argv[ai]);
356 return(1);
357 } else break;
358
359 /* Print help or version? */
360 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
361 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
362 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
363
364 /* Process other arguments, starting from the first non-option */
365 for(; ai<argc; ai++) {
366 if(ffi<1) ffi=ai;
367 fileNr++;
368 }
369
370 /* Is something missing? */
371 if(fileNr<1) {
372 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
373 return(1);
374 }
375
376 /* In verbose mode print arguments and options */
377 if(verbose>1) {
378 printf("do_planes := %d\n", do_planes);
379 printf("do_frames := %d\n", do_frames);
380 printf("do_gates := %d\n", do_gates);
381 printf("do_beds := %d\n", do_beds);
382 printf("fileNr := %d\n", fileNr);
383 }
384
385 /* Anything to do? */
386 if(do_planes==0 && do_frames==0 && do_gates==0 && do_beds==0) return(0);
387
388 /* Fix all ECAT files */
389 for(ai=ffi; ai<argc; ai++) {
390 strcpy(ecatfile, argv[ai]);
391 if(verbose>0 && fileNr>1) printf("fixing %s\n", ecatfile);
392 ret=ecatFixMatrixlist(ecatfile, do_planes, do_frames, do_gates, do_beds,
393 verbose-2);
394 if(ret==0) {
395 if(verbose>1) fprintf(stdout, " ok.\n");
396 okNr++;
397 } else {
398 if(verbose>0) fprintf(stdout, " failed (%d).\n", ret);
399 }
400 }
401 if(okNr<fileNr) {
402 fprintf(stderr, "Error: %d out of %d files failed.\n", fileNr-okNr, fileNr);
403 return(1);
404 } else {
405 if(verbose>0) fprintf(stdout, "%d file(s) fixed.\n", okNr);
406 }
407 return(0);
408}
409/*****************************************************************************/
410
411/*****************************************************************************/
int ecat63Matenter(FILE *fp, int matnum, int blkNr)
Definition ecat63ml.c:159
int ecat63ReadMatlist(FILE *fp, MATRIXLIST *ml, int verbose)
Definition ecat63ml.c:46
void ecat63InitMatlist(MATRIXLIST *mlist)
Definition ecat63ml.c:20
int ecat63GatherMatlist(MATRIXLIST *ml, short int do_planes, short int do_frames, short int do_gates, short int do_beds)
Definition ecat63ml.c:510
int ecat63GetNums(MATRIXLIST *ml, short int *num_planes, short int *num_frames, short int *num_gates, short int *num_bed_pos)
Definition ecat63ml.c:450
void ecat63PrintMatlist(MATRIXLIST *ml)
Definition ecat63ml.c:130
int ecat63CheckMatlist(MATRIXLIST *ml)
Definition ecat63ml.c:324
int ecat63ReadMainheader(FILE *fp, ECAT63_mainheader *h)
Definition ecat63r.c:25
FILE * ecat63Create(const char *fname, ECAT63_mainheader *h)
Definition ecat63w.c:365
void ecat7InitMatlist(ECAT7_MATRIXLIST *mlist)
Definition ecat7ml.c:15
int ecat7GetNums(ECAT7_MATRIXLIST *ml, ECAT7_mainheader *mh, FILE *fp, short int *num_planes, short int *num_frames, short int *num_gates, short int *num_bed_pos)
Definition ecat7ml.c:452
int ecat7ReadMatlist(FILE *fp, ECAT7_MATRIXLIST *ml, int verbose)
Definition ecat7ml.c:41
int ecat7EnterMatrix(FILE *fp, int matrix_id, int block_nr)
Definition ecat7ml.c:147
int ecat7GatherMatlist(ECAT7_MATRIXLIST *ml, short int do_planes, short int do_frames, short int do_gates, short int do_beds)
Definition ecat7ml.c:535
void ecat7PrintMatlist(ECAT7_MATRIXLIST *ml)
Definition ecat7ml.c:112
int ecat7CheckMatlist(ECAT7_MATRIXLIST *ml)
Definition ecat7ml.c:329
int ecat7ReadMainheader(FILE *fp, ECAT7_mainheader *h)
Definition ecat7r.c:15
FILE * ecat7Create(const char *fname, ECAT7_mainheader *h)
Definition ecat7w.c:567
int ecat7CopyFile(ECAT7_mainheader *mh, ECAT7_MATRIXLIST *ml, FILE *fp, char *resfile)
Definition efixplnr.c:121
int ecatFixMatrixlist(char *ecatfile, int do_planes, int do_frames, int do_gates, int do_beds, int verbose)
Definition efixplnr.c:172
int ecat63CopyFile(ECAT63_mainheader *mh, MATRIXLIST *ml, FILE *fp, char *resfile)
Definition efixplnr.c:69
char * imgStatus(int status_index)
Definition img.c:330
Header file for libtpcimgio.
#define MatBLKSIZE
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
short int num_bed_pos
ECAT7_MatDir * matdir
short int num_frames
char magic_number[14]
short int num_gates
short int num_planes
short int num_bed_pos
MatDir * matdir
int matstat
int endblk
int matnum
int strtblk