My Project
img_e7.c
Go to the documentation of this file.
1/******************************************************************************
2
3 Copyright (c) 2007,2010 Turku PET Centre
4
5 Library: img_e7.c
6 Description: ECAT 7 I/O routines for IMG data.
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 See the GNU Lesser General Public License for more details:
17 http://www.gnu.org/copyleft/lesser.html
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with this library/program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
23 Turku PET Centre, Turku, Finland, http://www.turkupetcentre.fi/
24
25 Modification history:
26 2007-02-27 Vesa Oikonen
27 Functions moved from imgfile.c.
28 Bug correction in imgWrite2DEcat7():
29 prompts were set after the header was written.
30 2007-03-25 VO
31 Added functions imgReadEcat7Header(), imgEcat7Supported(),
32 imgReadEcat7Frame(), imgReadEcat7FirstFrame(), imgGetEcat7Fileformat(),
33 imgWriteEcat7Frame(), and imgSetEcat7SHeader().
34 2007-04-03 VO
35 Added support for ECAT 7 polar maps.
36 2007-17-07 Harri Merisaari
37 Modified timezone correction in for ANSI compatibility and for
38 other timezones in imgGetEcat7MHeader
39 2007-09-07 VO
40 The rest of strcpy's replaced by strncpy's in imgGetEcat7MHeader(),
41 most importantly study_description, where overflow caused accidental
42 change of IMG type.
43 2007-09-10 VO
44 Return value of localtime() is checked.
45 2007-09-12 VO
46 Bug correction in imgReadEcat7Frame(): did not set 2D image plane numbers.
47 2010-02-12 VO
48 Timezone correction added also into imgSetEcat7MHeader().
49
50
51******************************************************************************/
52#include <stdio.h>
53#include <stdlib.h>
54#include <unistd.h>
55#include <math.h>
56#include <string.h>
57#include <time.h>
58/*****************************************************************************/
59#include "petc99.h"
60#include "swap.h"
61#include "halflife.h"
62/*****************************************************************************/
63#include "include/img.h"
64#include "include/ecat7.h"
65#include "include/imgmax.h"
66#include "include/imgdecay.h"
67#include "include/imgfile.h"
68/*****************************************************************************/
69
70/*****************************************************************************/
83int imgReadEcat7(const char *fname, IMG *img) {
84 FILE *fp;
85 int ret, m, i, fi, pi, xi, yi, frame, plane, prev_frame, prev_plane;
86 int dimx, dimy, dimz, planeNr, frameNr, blkNr=0, pxlNr;
87 ECAT7_mainheader main_header;
88 ECAT7_imageheader image_header;
89 ECAT7_2Dscanheader scan2d_header;
90 ECAT7_scanheader scan_header;
91 ECAT7_polmapheader polmap_header;
92 ECAT7_MATRIXLIST mlist;
93 ECAT7_Matval matval;
94 float *fdata=NULL, *fptr;
95
96
97 if(IMG_TEST) printf("imgReadEcat7(%s, *img)\n", fname);
98 /* Check the arguments */
99 if(fname==NULL) return(1);
100 if(img==NULL || img->status!=IMG_STATUS_INITIALIZED) {
101 imgSetStatus(img, STATUS_FAULT); return(2);}
102
103 /* Open file for read */
104 if((fp=fopen(fname, "rb"))==NULL) {imgSetStatus(img, STATUS_NOFILE); return(3);}
105
106 /* Read main header */
107 ret=ecat7ReadMainheader(fp, &main_header);
108 if(ret) {fclose(fp); imgSetStatus(img, STATUS_UNKNOWNFORMAT); return(4);}
109 /* Check for magic number */
110 if(strncmp(main_header.magic_number, ECAT7V_MAGICNR, 7)!=0) {
111 fclose(fp); imgSetStatus(img, STATUS_UNKNOWNFORMAT); return(4);
112 }
113
114 /* Check if file_type is supported */
115 if(imgEcat7Supported(&main_header)==0) {
116 fclose(fp); imgSetStatus(img, STATUS_UNSUPPORTED); return(5);
117 }
118
119 /* Read matrix list */
120 ecat7InitMatlist(&mlist);
121 ret=ecat7ReadMatlist(fp, &mlist);
122 if(ret || mlist.matrixNr<1 || ecat7CheckMatlist(&mlist)) {
123 fclose(fp); imgSetStatus(img, STATUS_INVALIDMATLIST); return(6);}
125 if(IMG_TEST>2) ecat7PrintMatlist(&mlist);
126
127 /* Calculate the number of planes, frames and gates */
128 /* Check that all planes have equal nr of frames (gates) */
129 /* and check that frames (gates) are consequentally numbered */
130 prev_plane=plane=-1; prev_frame=frame=-1; frameNr=planeNr=0; ret=0;
131 for(m=0; m<mlist.matrixNr; m++) {
132 ecat7_id_to_val(mlist.matdir[m].id, &matval); plane=matval.plane;
133 if(main_header.num_frames>=main_header.num_gates) frame=matval.frame;
134 else frame=matval.gate;
135 if(plane!=prev_plane) {frameNr=1; planeNr++;}
136 else {frameNr++; if(prev_frame>0 && frame!=prev_frame+1) {ret=1; break;}}
137 prev_plane=plane; prev_frame=frame;
138 /* Calculate and check the size of one data matrix */
139 if(m==0) {
140 blkNr=mlist.matdir[m].endblk-mlist.matdir[m].strtblk;
141 } else if(blkNr!=mlist.matdir[m].endblk-mlist.matdir[m].strtblk) {
142 ret=2; break;
143 }
144 } /* next matrix */
145 if(IMG_TEST>2) printf("frameNr=%d planeNr=%d\n", frameNr, planeNr);
146 if(ret==1 || (frameNr*planeNr != mlist.matrixNr)) {
147 fclose(fp); imgSetStatus(img, STATUS_MISSINGMATRIX); ecat7EmptyMatlist(&mlist); return(7);}
148 if(ret==2) {
149 fclose(fp); imgSetStatus(img, STATUS_VARMATSIZE); ecat7EmptyMatlist(&mlist); return(8);}
150
151 /* Read the first subheader to get planeNr from volumes and to get x&y dim */
152 m=0; dimz=1; imgSetStatus(img, STATUS_NOSUBHEADER);
153 switch(main_header.file_type) {
154 case ECAT7_IMAGE8:
155 case ECAT7_IMAGE16:
156 case ECAT7_VOLUME8:
157 case ECAT7_VOLUME16:
158 img->type=IMG_TYPE_IMAGE;
159 ret=ecat7ReadImageheader(fp, mlist.matdir[m].strtblk, &image_header);
160 dimx=image_header.x_dimension; dimy=image_header.y_dimension;
161 if(image_header.num_dimensions>2 && image_header.z_dimension>1)
162 planeNr=dimz=image_header.z_dimension;
163 break;
164 case ECAT7_2DSCAN:
165 img->type=IMG_TYPE_RAW;
166 ret=ecat7Read2DScanheader(fp, mlist.matdir[m].strtblk, &scan2d_header);
167 dimx=scan2d_header.num_r_elements; dimy=scan2d_header.num_angles;
168 if(scan2d_header.num_dimensions>2 && scan2d_header.num_z_elements>1)
169 planeNr=dimz=scan2d_header.num_z_elements;
170 break;
171 case ECAT7_3DSCAN:
172 case ECAT7_3DSCAN8:
173 case ECAT7_3DSCANFIT:
174 img->type=IMG_TYPE_RAW;
175 ret=ecat7ReadScanheader(fp, mlist.matdir[m].strtblk, &scan_header);
176 dimx=scan_header.num_r_elements; dimy=scan_header.num_angles;
177 for(i=dimz=0; i<64; i++) dimz+=scan_header.num_z_elements[i];
178 planeNr=dimz;
179 /*if(scan_header.axial_compression!=0) {img->statmsg=imgmsg[STATUS_UNSUPPORTEDAXIALCOMP]; ret=-1;}*/
180 break;
181 case ECAT7_POLARMAP:
183 ret=ecat7ReadPolmapheader(fp, mlist.matdir[m].strtblk, &polmap_header);
184 planeNr=dimz=dimy=1; dimx=0;
185 for(i=0; i<polmap_header.num_rings; i++)
186 dimx+=polmap_header.sectors_per_ring[i];
187 break;
188 default: dimx=dimy=dimz=planeNr=0; ret=-1;
189 }
190 pxlNr=dimx*dimy;
191 if(ret || pxlNr<1 || planeNr<1) {
192 fclose(fp); ecat7EmptyMatlist(&mlist); return(9);}
194
195 /* Allocate memory for IMG data */
196 ret=imgAllocate(img, planeNr, dimy, dimx, frameNr);
197 if(ret) {
198 fclose(fp); imgSetStatus(img, STATUS_NOMEMORY);
199 ecat7EmptyMatlist(&mlist); return(11);
200 }
201 /* Copy information from mainheader */
202 imgGetEcat7MHeader(img, &main_header);
203 /* Set fileFormat */
204 switch(main_header.file_type) {
205 case ECAT7_IMAGE8:
206 case ECAT7_IMAGE16:
207 img->_fileFormat=IMG_E7_2D; break;
208 case ECAT7_VOLUME8:
209 case ECAT7_VOLUME16:
210 img->_fileFormat=IMG_E7; break;
211 case ECAT7_2DSCAN:
212 img->_fileFormat=IMG_E7_2D; break;
213 case ECAT7_3DSCAN:
214 case ECAT7_3DSCAN8:
215 case ECAT7_3DSCANFIT:
216 img->_fileFormat=IMG_E7; break;
217 case ECAT7_POLARMAP:
218 img->_fileFormat=IMG_POLARMAP; break;
219 default:
220 img->_fileFormat=IMG_UNKNOWN; break;
221 }
222
223 if(dimz>1) {
224 /* Read ECAT volume matrices */
225 fi=0;
226 for(m=0; m<mlist.matrixNr; m++) {
227 /* Get matrix values */
228 ecat7_id_to_val(mlist.matdir[m].id, &matval);
229 /* Read subheader and data */
230 if(img->type==IMG_TYPE_IMAGE)
231 ret=ecat7ReadImageMatrix(fp, mlist.matdir[m].strtblk,
232 mlist.matdir[m].endblk, &image_header, &fdata);
233 else
234 ret=ecat7ReadScanMatrix(fp, mlist.matdir[m].strtblk,
235 mlist.matdir[m].endblk, &scan_header, &fdata);
236 if(ret || fdata==NULL) {
237 if(IMG_TEST) printf("ecat7ReadXMatrix()=%d\n%s\n", ret, ecat7errmsg);
238 fclose(fp); imgSetStatus(img, STATUS_NOMATRIX); ecat7EmptyMatlist(&mlist); return(13);}
239 /* Copy subheader information */
240 if(img->type==IMG_TYPE_POLARMAP) {
241 img->_dataType=polmap_header.data_type;
242 img->start[fi]=polmap_header.frame_start_time/1000.;
243 img->end[fi]=img->start[fi]+polmap_header.frame_duration/1000.;
244 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
245 img->sizex=0.001*polmap_header.pixel_size;
246 } else if(img->type==IMG_TYPE_IMAGE) {
247 img->_dataType=image_header.data_type;
248 img->start[fi]=image_header.frame_start_time/1000.;
249 img->end[fi]=img->start[fi]+image_header.frame_duration/1000.;
250 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
251 if(image_header.decay_corr_fctr>1.0) {
252 img->decayCorrFactor[fi]=image_header.decay_corr_fctr;
253 img->decayCorrected=1;
254 }
255 img->zoom=image_header.recon_zoom;
256 img->sizex=10.*image_header.x_pixel_size;
257 img->sizey=10.*image_header.y_pixel_size;
258 img->sizez=10.*image_header.z_pixel_size;
259 img->resolutionx=10.*image_header.x_resolution;
260 img->resolutiony=10.*image_header.y_resolution;
261 img->resolutionz=10.*image_header.z_resolution;
262 } else {
263 img->_dataType=scan_header.data_type;
264 img->start[fi]=scan_header.frame_start_time/1000.;
265 img->end[fi]=img->start[fi]+scan2d_header.frame_duration/1000.;
266 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
267 if(scan_header.x_resolution>0.0)
268 img->sampleDistance=10.0*scan_header.x_resolution;
269 else
270 img->sampleDistance=10.0*main_header.bin_size;
271 /* also, correct for dead-time */
272 if(scan_header.deadtime_correction_factor>0.0)
273 for(i=0, fptr=fdata; i<dimz*pxlNr; i++, fptr++)
274 *fptr*=scan_header.deadtime_correction_factor;
275 img->prompts[fi]=(float)scan_header.prompts;
276 img->randoms[fi]=scan_header.delayed;
277 }
278 /* Copy matrix data through volume planes */
279 for(pi=0; pi<dimz; pi++) {
280 for(yi=0, fptr=fdata+pi*pxlNr; yi<dimy; yi++) for(xi=0; xi<dimx; xi++)
281 img->m[pi][yi][xi][fi]= *fptr++;
282 }
283 free(fdata); fi++;
284 } /* next matrix */
285 /* Set plane numbers */
286 for(pi=0; pi<dimz; pi++) img->planeNumber[pi]=pi+1;
287 } else {
288 /* Read separate matrices */
289 prev_plane=plane=-1; prev_frame=frame=-1; pi=fi=-1;
290 for(m=0; m<mlist.matrixNr; m++) {
291 ecat7_id_to_val(mlist.matdir[m].id, &matval); plane=matval.plane;
292 if(main_header.num_frames>=main_header.num_gates) frame=matval.frame;
293 else frame=matval.gate;
294 if(plane!=prev_plane) {fi=0; pi++;} else fi++;
295 /* Read subheader and data */
296 if(img->type==IMG_TYPE_POLARMAP)
297 ret=ecat7ReadPolarmapMatrix(fp, mlist.matdir[m].strtblk,
298 mlist.matdir[m].endblk, &polmap_header, &fdata);
299 else if(img->type==IMG_TYPE_IMAGE)
300 ret=ecat7ReadImageMatrix(fp, mlist.matdir[m].strtblk,
301 mlist.matdir[m].endblk, &image_header, &fdata);
302 else
303 ret=ecat7Read2DScanMatrix(fp, mlist.matdir[m].strtblk,
304 mlist.matdir[m].endblk, &scan2d_header, &fdata);
305 if(ret || fdata==NULL) {
306 fclose(fp); imgSetStatus(img, STATUS_NOMATRIX); ecat7EmptyMatlist(&mlist); return(13);}
307 /* Copy subheader information */
308 if(fi==0) img->planeNumber[pi]=plane;
309 if(img->type==IMG_TYPE_POLARMAP) {
310 img->_dataType=polmap_header.data_type;
311 img->start[fi]=polmap_header.frame_start_time/1000.;
312 img->end[fi]=img->start[fi]+polmap_header.frame_duration/1000.;
313 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
314 img->sizex=0.001*polmap_header.pixel_size;
315 } else if(img->type==IMG_TYPE_IMAGE) {
316 img->_dataType=image_header.data_type;
317 img->start[fi]=image_header.frame_start_time/1000.;
318 img->end[fi]=img->start[fi]+image_header.frame_duration/1000.;
319 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
320 if(image_header.decay_corr_fctr>1.0) {
321 img->decayCorrFactor[fi]=image_header.decay_corr_fctr;
322 img->decayCorrected=1;
323 }
324 img->zoom=image_header.recon_zoom;
325 img->sizex=10.*image_header.x_pixel_size;
326 img->sizey=10.*image_header.y_pixel_size;
327 img->sizez=10.*image_header.z_pixel_size;
328 img->resolutionx=10.*image_header.x_resolution;
329 img->resolutiony=10.*image_header.y_resolution;
330 img->resolutionz=10.*image_header.z_resolution;
331 } else {
332 img->_dataType=scan2d_header.data_type;
333 img->start[fi]=scan2d_header.frame_start_time/1000.;
334 img->end[fi]=img->start[fi]+scan2d_header.frame_duration/1000.;
335 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
336 if(scan_header.x_resolution>0.0)
337 img->sampleDistance=10.0*scan_header.x_resolution;
338 else
339 img->sampleDistance=10.0*main_header.bin_size;
340 /* also, correct for dead-time */
341 if(scan2d_header.deadtime_correction_factor>0.0)
342 for(i=0, fptr=fdata; i<pxlNr; i++, fptr++)
343 *fptr*=scan2d_header.deadtime_correction_factor;
344 img->prompts[fi]=(float)scan_header.prompts;
345 img->randoms[fi]=scan_header.delayed;
346 }
347 /* Copy matrix data */
348 for(yi=0, fptr=fdata; yi<dimy; yi++) for(xi=0; xi<dimx; xi++)
349 img->m[pi][yi][xi][fi]= *fptr++;
350 free(fdata);
351 /* prepare for the next matrix */
352 prev_plane=plane; prev_frame=frame;
353 } /* next matrix */
354 }
355 fclose(fp); ecat7EmptyMatlist(&mlist);
356
357 /* Calibrate */
358 if(main_header.ecat_calibration_factor>0.0)
359 for(pi=0; pi<img->dimz; pi++)
360 for(yi=0; yi<img->dimy; yi++) for(xi=0; xi<img->dimx; xi++)
361 for(fi=0; fi<img->dimt; fi++)
362 img->m[pi][yi][xi][fi]*=main_header.ecat_calibration_factor;
363
365 return(0);
366}
367/*****************************************************************************/
368
369/*****************************************************************************/
380int imgWriteEcat7(const char *fname, IMG *img) {
381 ECAT7_mainheader main_header;
382 ECAT7_imageheader image_header;
383 ECAT7_scanheader scan_header;
384 FILE *fp;
385 int fi, pi, xi, yi, pxlNr, matrixId, ret;
386 float *fdata, *fptr;
387
388
389 if(IMG_TEST) printf("imgWriteEcat7(%s, *img)\n", fname);
390 if(IMG_TEST>1 && ECAT7_TEST==0) ECAT7_TEST=1;
391 /* Check the arguments */
392 if(fname==NULL) return(1);
393 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) {
394 imgSetStatus(img, STATUS_FAULT); return(2);}
395 if(img->type!=IMG_TYPE_RAW && img->type!=IMG_TYPE_IMAGE) {
396 imgSetStatus(img, STATUS_FAULT); return(2);}
397
398 /* Initiate headers */
399 memset(&main_header, 0, sizeof(ECAT7_mainheader));
400 memset(&image_header,0, sizeof(ECAT7_imageheader));
401 memset(&scan_header, 0, sizeof(ECAT7_scanheader));
402
403 /* Set main header */
404 imgSetEcat7MHeader(img, &main_header);
405 main_header.bin_size=img->sampleDistance/10.0;
406
407 /* Allocate memory for matrix float data */
408 pxlNr=img->dimx*img->dimy*img->dimz;
409 fdata=(float*)malloc(pxlNr*sizeof(float));
410 if(fdata==NULL) {imgSetStatus(img, STATUS_NOMEMORY); return(3);}
411
412 /* Open file, write main header and initiate matrix list */
413 fp=ecat7Create(fname, &main_header);
414 if(fp==NULL) {free(fdata); imgSetStatus(img, STATUS_NOWRITEPERM); return(6);}
415
416 /* Set (most of) subheader contents */
417 if(img->type==IMG_TYPE_RAW) {
418 scan_header.x_resolution=img->sampleDistance/10.0;
419 scan_header.num_dimensions=4;
420 if(img->dimz==239) {
421 scan_header.num_z_elements[0]=63;
422 scan_header.num_z_elements[1]=106;
423 scan_header.num_z_elements[2]=70;
424 } else {
425 scan_header.num_z_elements[0]=img->dimz;
426 }
427 scan_header.storage_order=1;
428 scan_header.data_type=ECAT7_SUNI2;
429 scan_header.num_r_elements=img->dimx;
430 scan_header.num_angles=img->dimy;
431 } else if(img->type==IMG_TYPE_IMAGE) {
432 image_header.num_dimensions=3;
433 image_header.z_dimension=img->dimz;
434 image_header.data_type=ECAT7_SUNI2;
435 image_header.x_dimension=img->dimx;
436 image_header.y_dimension=img->dimy;
437 image_header.recon_zoom=img->zoom;
438 image_header.x_pixel_size=0.1*img->sizex;
439 image_header.y_pixel_size=0.1*img->sizey;
440 image_header.z_pixel_size=0.1*img->sizez;
441 image_header.x_resolution=0.1*img->resolutionx;
442 image_header.y_resolution=0.1*img->resolutiony;
443 image_header.z_resolution=0.1*img->resolutionz;
444 }
445
446 /* Write each matrix */
447 for(fi=0; fi<img->dimt; fi++) {
448
449 /* Create new matrix id (i.e. matnum) */
450 matrixId=ecat7_val_to_id(fi+1, 1, 1, 0, 0);
451
452 /* Copy matrix pixel values to fdata */
453 fptr=fdata;
454 for(pi=0; pi<img->dimz; pi++)
455 for(yi=0; yi<img->dimy; yi++) for(xi=0; xi<img->dimx; xi++)
456 *fptr++=img->m[pi][yi][xi][fi];
457
458 /* Write subheader and data */
459 fptr=fdata;
460 if(img->type==IMG_TYPE_RAW) {
461 scan_header.frame_start_time=(int)temp_roundf(1000.*img->start[fi]);
462 scan_header.frame_duration=(int)temp_roundf(1000.*(img->end[fi]-img->start[fi]));
463 scan_header.prompts=temp_roundf(img->prompts[fi]);
464 scan_header.delayed=temp_roundf(img->randoms[fi]);
465 /*ecat7PrintScanheader(&scan_header, stdout);*/
466 ret=ecat7WriteScanMatrix(fp, matrixId, &scan_header, fptr);
467 } else if(img->type==IMG_TYPE_IMAGE) {
468 image_header.frame_start_time=(int)temp_roundf(1000.*img->start[fi]);
469 image_header.frame_duration=(int)temp_roundf(1000.*(img->end[fi]-img->start[fi]));
470 image_header.decay_corr_fctr=img->decayCorrFactor[fi];
471 /*ecat7PrintImageheader(&image_header, stdout);*/
472 ret=ecat7WriteImageMatrix(fp, matrixId, &image_header, fptr);
473 } else {free(fdata); fclose(fp); imgSetStatus(img, STATUS_UNSUPPORTED); return(8);}
474 if(ret) {
475 if(IMG_TEST) {printf("matrixId=%d ret=%d\n", matrixId, ret);}
476 free(fdata); fclose(fp); imgSetStatus(img, STATUS_DISKFULL); return(7);
477 }
478
479 } /* next matrix */
480 free(fdata); fclose(fp);
481
483 return(0);
484}
485/*****************************************************************************/
486
487/*****************************************************************************/
498int imgWrite2DEcat7(const char *fname, IMG *img) {
499 ECAT7_mainheader main_header;
500 ECAT7_imageheader image_header;
501 ECAT7_2Dscanheader scan2d_header;
502 FILE *fp;
503 int fi, pi, xi, yi, pxlNr, matrixId, ret;
504 float *fdata, *fptr;
505
506
507 if(IMG_TEST) printf("imgWrite2DEcat7(%s, *img)\n", fname);
508 if(IMG_TEST>1 && ECAT7_TEST==0) ECAT7_TEST=1;
509 /* Check the arguments */
510 if(fname==NULL) {return(1);}
511 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) {
512 imgSetStatus(img, STATUS_FAULT); return(2);}
513
514 /* Initiate headers */
515 memset(&main_header, 0, sizeof(ECAT7_mainheader));
516 memset(&image_header,0, sizeof(ECAT7_imageheader));
517 memset(&scan2d_header, 0, sizeof(ECAT7_2Dscanheader));
518
519 /* Set main header */
520 imgSetEcat7MHeader(img, &main_header);
521 main_header.bin_size=img->sampleDistance/10.0;
522 if(img->type==IMG_TYPE_RAW) main_header.file_type=ECAT7_2DSCAN;
523 else main_header.file_type=ECAT7_IMAGE16;
524 main_header.num_planes=img->dimz;
525
526 /* Allocate memory for matrix float data */
527 pxlNr=img->dimx*img->dimy;
528 fdata=(float*)malloc(pxlNr*sizeof(float));
529 if(fdata==NULL) {imgSetStatus(img, STATUS_NOMEMORY); return(3);}
530
531 /* Open file, write main header and initiate matrix list */
532 fp=ecat7Create(fname, &main_header);
533 if(fp==NULL) {free(fdata); imgSetStatus(img, STATUS_NOWRITEPERM); return(6);}
534
535 /* Set (most of) subheader contents */
536 if(img->type==IMG_TYPE_RAW) {
537 scan2d_header.num_dimensions=2;
538 scan2d_header.num_z_elements=1;
539 scan2d_header.data_type=ECAT7_SUNI2;
540 scan2d_header.num_r_elements=img->dimx;
541 scan2d_header.num_angles=img->dimy;
542 } else if(img->type==IMG_TYPE_IMAGE) {
543 image_header.num_dimensions=2;
544 image_header.z_dimension=1;
545 image_header.data_type=ECAT7_SUNI2;
546 image_header.x_dimension=img->dimx;
547 image_header.y_dimension=img->dimy;
548 image_header.recon_zoom=img->zoom;
549 image_header.x_pixel_size=0.1*img->sizex;
550 image_header.y_pixel_size=0.1*img->sizey;
551 image_header.z_pixel_size=0.1*img->sizez;
552 image_header.x_resolution=0.1*img->resolutionx;
553 image_header.y_resolution=0.1*img->resolutiony;
554 image_header.z_resolution=0.1*img->resolutionz;
555 }
556
557 /* Write each matrix */
558 for(fi=0; fi<img->dimt; fi++) for(pi=0; pi<img->dimz; pi++) {
559
560 /* Create new matrix id (i.e. matnum) */
561 matrixId=ecat7_val_to_id(fi+1, img->planeNumber[pi], 1, 0, 0);
562
563 /* Copy matrix pixel values to fdata */
564 fptr=fdata;
565 for(yi=0; yi<img->dimy; yi++) for(xi=0; xi<img->dimx; xi++)
566 *fptr++=img->m[pi][yi][xi][fi];
567
568 /* Write subheader and data */
569 fptr=fdata;
570 if(img->type==IMG_TYPE_RAW) {
571 scan2d_header.frame_start_time=(int)temp_roundf(1000.*img->start[fi]);
572 scan2d_header.frame_duration=(int)temp_roundf(1000.*(img->end[fi]-img->start[fi]));
573 scan2d_header.prompts=temp_roundf(img->prompts[fi]);
574 scan2d_header.delayed=temp_roundf(img->randoms[fi]);
575 ret=ecat7Write2DScanMatrix(fp, matrixId, &scan2d_header, fptr);
576 } else if(img->type==IMG_TYPE_IMAGE) {
577 image_header.frame_start_time=(int)temp_roundf(1000.*img->start[fi]);
578 image_header.frame_duration=(int)temp_roundf(1000.*(img->end[fi]-img->start[fi]));
579 image_header.decay_corr_fctr=img->decayCorrFactor[fi];
580 ret=ecat7WriteImageMatrix(fp, matrixId, &image_header, fptr);
581 } else {free(fdata); fclose(fp); imgSetStatus(img, STATUS_UNSUPPORTED); return(8);}
582 if(ret) {
583 if(IMG_TEST) {printf("matrixId=%d ret=%d\n", matrixId, ret);}
584 free(fdata); fclose(fp); imgSetStatus(img, STATUS_DISKFULL); return(7);
585 }
586
587 } /* next matrix */
588 free(fdata); fclose(fp);
589
591 return(0);
592}
593/*****************************************************************************/
594
595/*****************************************************************************/
606int imgWritePolarmap(const char *fname, IMG *img) {
607 ECAT7_mainheader main_header;
608 ECAT7_polmapheader polmap_header;
609 FILE *fp;
610 int fi, pi, xi, yi, pxlNr, matrixId, ret;
611 float *fdata, *fptr;
612
613
614 if(IMG_TEST) printf("imgWritePolarmap(%s, *img)\n", fname);
615 if(IMG_TEST>1 && ECAT7_TEST==0) ECAT7_TEST=1;
616 /* Check the arguments */
617 if(fname==NULL) return(1);
618 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) {
619 imgSetStatus(img, STATUS_FAULT); return(2);}
620 if(img->type!=IMG_TYPE_POLARMAP) {
621 imgSetStatus(img, STATUS_FAULT); return(2);}
622
623 /* Initiate headers */
624 memset(&main_header, 0, sizeof(ECAT7_mainheader));
625 memset(&polmap_header,0, sizeof(ECAT7_polmapheader));
626
627 /* Set main header */
628 imgSetEcat7MHeader(img, &main_header);
629 main_header.bin_size=img->sampleDistance/10.0;
630
631 /* Allocate memory for matrix float data */
632 pxlNr=img->dimx*img->dimy*img->dimz;
633 fdata=(float*)malloc(pxlNr*sizeof(float));
634 if(fdata==NULL) {imgSetStatus(img, STATUS_NOMEMORY); return(3);}
635
636 /* Open file, write main header and initiate matrix list */
637 fp=ecat7Create(fname, &main_header);
638 if(fp==NULL) {free(fdata); imgSetStatus(img, STATUS_NOWRITEPERM); return(6);}
639
640 /* Set (most of) subheader contents */
641 imgSetEcat7SHeader(img, &polmap_header);
642
643 /* Write each matrix */
644 for(fi=0; fi<img->dimt; fi++) {
645
646 /* Create new matrix id (i.e. matnum) */
647 matrixId=ecat7_val_to_id(fi+1, 1, 1, 0, 0);
648
649 /* Copy matrix pixel values to fdata */
650 fptr=fdata;
651 for(pi=0; pi<img->dimz; pi++)
652 for(yi=0; yi<img->dimy; yi++) for(xi=0; xi<img->dimx; xi++)
653 *fptr++=img->m[pi][yi][xi][fi];
654
655 /* Write subheader and data */
656 fptr=fdata;
657 polmap_header.frame_start_time=(int)temp_roundf(1000.*img->start[fi]);
658 polmap_header.frame_duration=(int)temp_roundf(1000.*(img->end[fi]-img->start[fi]));
659 /*ecat7PrintImageheader(&image_header, stdout);*/
660 ret=ecat7WritePolarmapMatrix(fp, matrixId, &polmap_header, fptr);
661 if(ret) {
662 if(IMG_TEST) {printf("matrixId=%d ret=%d\n", matrixId, ret);}
663 free(fdata); fclose(fp); imgSetStatus(img, STATUS_DISKFULL); return(7);
664 }
665
666 } /* next matrix */
667 free(fdata); fclose(fp);
668
670 return(0);
671}
672/*****************************************************************************/
673
674/*****************************************************************************/
682#ifndef __STRICT_ANSI__
683 struct tm *scanStartTime;
684 time_t lt;
685#endif
686
687 img->scanner=h->system_type;
688 imgUnitFromEcat7(img, h);
689 strncpy(img->radiopharmaceutical, h->radiopharmaceutical, 32);
692#ifndef __STRICT_ANSI__
693 /* refresh timezone information (might be out of date) */
694 tzset();
695 /* correct scan start time in hours */
696 lt = (time_t)img->scanStart;
697 scanStartTime = localtime(&lt);
698 if(scanStartTime!=NULL) {
699 scanStartTime->tm_hour -= (timezone/3600);
700 img->scanStart = mktime(scanStartTime);
701 }
702#endif
703 img->axialFOV=10.0*h->distance_scanned;
704 img->transaxialFOV=10.0*h->transaxial_fov;
705 strncpy(img->studyNr, h->study_type, MAX_STUDYNR_LEN);
706 strncpy(img->patientName, h->patient_name, 32);
707 strncpy(img->patientID, h->patient_id, 16);
708 img->sizez=10.0*h->plane_separation;
709 switch(h->file_type) {
710 case ECAT7_IMAGE8:
711 case ECAT7_IMAGE16:
712 case ECAT7_VOLUME8:
713 case ECAT7_VOLUME16: img->type=IMG_TYPE_IMAGE; break;
714 case ECAT7_POLARMAP: img->type=IMG_TYPE_POLARMAP; break;
715 default: img->type=IMG_TYPE_RAW;
716 }
718 strncpy(img->studyDescription, h->study_description, 32);
719 strncpy(img->userProcessCode, h->user_process_code, 10);
720 img->userProcessCode[10]=(char)0;
721 /* If valid study number is found in user_process_code, then take it */
722 if(!img->studyNr[0] && studynr_validity_check(img->userProcessCode))
723 strcpy(img->studyNr, img->userProcessCode);
724}
725/*****************************************************************************/
726
727/*****************************************************************************/
735#ifndef __STRICT_ANSI__
736 struct tm *scanStartTime;
737 time_t lt;
738#endif
739
740 h->sw_version=72;
741 if(img->type==IMG_TYPE_POLARMAP) {
742 strcpy(h->magic_number, ECAT7V_MAGICNR);
744 } else if(img->type==IMG_TYPE_RAW) {
745 strcpy(h->magic_number, ECAT7S_MAGICNR);
747 else h->file_type=ECAT7_3DSCAN;
748 } else {
749 strcpy(h->magic_number, ECAT7V_MAGICNR);
752 }
753 h->system_type=img->scanner;
755#ifndef __STRICT_ANSI__
756 /* refresh timezone information (might be out of date) */
757 tzset();
758 /* correct scan start time in hours */
759 lt = (time_t)h->scan_start_time;
760 scanStartTime = localtime(&lt);
761 if(scanStartTime!=NULL) {
762 scanStartTime->tm_hour += (timezone/3600);
763 h->scan_start_time = mktime(scanStartTime);
764 }
765#endif
767 imgUnitToEcat7(img, h);
769 h->transaxial_fov=img->transaxialFOV/10.0;
770 h->num_planes=img->dimz; /* h->num_planes=1; */
771 h->num_frames=img->dimt;
772 h->num_gates=1;
773 h->num_bed_pos=0;
774 h->distance_scanned=img->axialFOV/10.0;
775 h->plane_separation=img->sizez/10.0;
776 strncpy(h->radiopharmaceutical, img->radiopharmaceutical, 32);
777 strcpy(h->isotope_name, imgIsotope(img));
778 strcpy(h->study_type, img->studyNr);
779 strcpy(h->patient_name, img->patientName);
780 strcpy(h->patient_id, img->patientID);
782 strcpy(h->study_description, img->studyDescription);
783 strncpy(h->user_process_code, img->userProcessCode, 10);
784}
785/*****************************************************************************/
786
787/*****************************************************************************/
795 int fileFormat=IMG_UNKNOWN;
796 switch(h->file_type) {
797 case ECAT7_IMAGE8:
798 case ECAT7_IMAGE16:
799 fileFormat=IMG_E7_2D; break;
800 case ECAT7_VOLUME8:
801 case ECAT7_VOLUME16:
802 fileFormat=IMG_E7; break;
803 case ECAT7_2DSCAN:
804 fileFormat=IMG_E7_2D; break;
805 case ECAT7_3DSCAN:
806 case ECAT7_3DSCAN8:
807 case ECAT7_3DSCANFIT:
808 fileFormat=IMG_E7; break;
809 case ECAT7_POLARMAP:
810 fileFormat=IMG_POLARMAP; break;
811 default:
812 fileFormat=IMG_UNKNOWN; break;
813 }
814 return fileFormat;
815}
816/*****************************************************************************/
827int imgReadEcat7Header(const char *fname, IMG *img) {
828 FILE *fp;
829 int ret, m, i;
830 int planeNr, frameNr, blkNr=0;
831 ECAT7_mainheader main_header;
832 ECAT7_imageheader image_header;
833 ECAT7_2Dscanheader scan2d_header;
834 ECAT7_scanheader scan_header;
835 ECAT7_polmapheader polmap_header;
836 ECAT7_MATRIXLIST mlist;
837
838
839 if(IMG_TEST) printf("\nimgReadEcat7Header(%s, *img)\n", fname);
840
841 /* Check the arguments */
842 if(img==NULL) return STATUS_FAULT;
845 if(fname==NULL) return STATUS_FAULT;
846
847 /* Open the file */
848 if((fp=fopen(fname, "rb")) == NULL) return STATUS_NOFILE;
849
850 /* Read main header */
851 ret=ecat7ReadMainheader(fp, &main_header);
852 if(ret) {fclose(fp); return STATUS_NOMAINHEADER;}
853 /* Check for magic number */
854 if(strncmp(main_header.magic_number, ECAT7V_MAGICNR, 7)!=0) {
855 fclose(fp); return STATUS_UNKNOWNFORMAT;}
856 /* Check if file_type is supported */
857 if(imgEcat7Supported(&main_header)==0) {fclose(fp); return STATUS_UNSUPPORTED;}
858 /* Copy main header information into IMG; sets also img.type */
859 imgGetEcat7MHeader(img, &main_header);
860 if(IMG_TEST>7) printf("img.type := %d\n", img->type);
861 img->_fileFormat=imgGetEcat7Fileformat(&main_header);
862 if(IMG_TEST>7) printf("img._fileFormat := %d\n", img->_fileFormat);
863 if(img->_fileFormat==IMG_UNKNOWN) {fclose(fp); return STATUS_UNSUPPORTED;}
864
865 /* Read matrix list */
866 ecat7InitMatlist(&mlist);
867 ret=ecat7ReadMatlist(fp, &mlist);
868 if(ret || mlist.matrixNr<1 || ecat7CheckMatlist(&mlist)) {
869 fclose(fp); return STATUS_INVALIDMATLIST;}
870 /* Make sure that plane and frame numbers are continuous */
871 ecat7GatherMatlist(&mlist, 1, 1, 1, 1);
872 /* Get plane and frame numbers and check that volume is full */
873 ret=ecat7GetPlaneAndFrameNr(&mlist, &main_header, &planeNr, &frameNr);
874 if(ret) {ecat7EmptyMatlist(&mlist); fclose(fp); return ret;}
875 img->dimz=planeNr;
876 img->dimt=frameNr;
877 /* Get and check the size of data matrices */
878 ret=ecat7GetMatrixBlockSize(&mlist, &blkNr);
879 if(ret) {ecat7EmptyMatlist(&mlist); fclose(fp); return ret;}
880
881 /* Read one subheader */
882 if(IMG_TEST>5) printf("main_header.file_type := %d\n", main_header.file_type);
883 m=0;
884 switch(main_header.file_type) {
885 case ECAT7_IMAGE8:
886 case ECAT7_IMAGE16:
887 case ECAT7_VOLUME8:
888 case ECAT7_VOLUME16:
889 ret=ecat7ReadImageheader(fp, mlist.matdir[m].strtblk, &image_header);
890 break;
891 case ECAT7_2DSCAN:
892 ret=ecat7Read2DScanheader(fp, mlist.matdir[m].strtblk, &scan2d_header);
893 break;
894 case ECAT7_3DSCAN:
895 case ECAT7_3DSCAN8:
896 case ECAT7_3DSCANFIT:
897 ret=ecat7ReadScanheader(fp, mlist.matdir[m].strtblk, &scan_header);
898 break;
899 case ECAT7_POLARMAP:
900 ret=ecat7ReadPolmapheader(fp, mlist.matdir[m].strtblk, &polmap_header);
901 break;
902 default: ret=-1;
903 }
904 /* Free locally allocated memory and close the file */
905 ecat7EmptyMatlist(&mlist); fclose(fp);
906 /* Check whether subheader was read */
907 if(ret) return STATUS_NOSUBHEADER;
908
909 /* Get the following information in the subheader:
910 dimensions x, y and z; datatype;
911 image decay correction on/off, zoom, pixel size and resolution;
912 sinogram sample distance.
913 */
914 switch(main_header.file_type) {
915 case ECAT7_IMAGE8:
916 case ECAT7_IMAGE16:
917 case ECAT7_VOLUME8:
918 case ECAT7_VOLUME16:
919 img->dimx=image_header.x_dimension; img->dimy=image_header.y_dimension;
920 if(image_header.num_dimensions>2 && image_header.z_dimension>1)
921 /*planeNr=*/ img->dimz=image_header.z_dimension;
922 img->_dataType=image_header.data_type;
923 if(image_header.decay_corr_fctr>1.0) img->decayCorrected=1;
924 img->zoom=image_header.recon_zoom;
925 img->sizex=10.*image_header.x_pixel_size;
926 img->sizey=10.*image_header.y_pixel_size;
927 img->sizez=10.*image_header.z_pixel_size;
928 img->resolutionx=10.*image_header.x_resolution;
929 img->resolutiony=10.*image_header.y_resolution;
930 img->resolutionz=10.*image_header.z_resolution;
931 break;
932 case ECAT7_2DSCAN:
933 img->dimx=scan2d_header.num_r_elements; img->dimy=scan2d_header.num_angles;
934 if(scan2d_header.num_dimensions>2 && scan2d_header.num_z_elements>1)
935 planeNr=img->dimz=scan2d_header.num_z_elements;
936 img->_dataType=scan2d_header.data_type;
937 if(scan2d_header.x_resolution>0.0)
938 img->sampleDistance=10.0*scan2d_header.x_resolution;
939 else
940 img->sampleDistance=10.0*main_header.bin_size;
941 break;
942 case ECAT7_3DSCAN:
943 case ECAT7_3DSCAN8:
944 case ECAT7_3DSCANFIT:
945 img->dimx=scan_header.num_r_elements; img->dimy=scan_header.num_angles;
946 for(i=img->dimz=0; i<64; i++) img->dimz+=scan_header.num_z_elements[i];
947 /* planeNr=img->dimz; */
948 img->_dataType=scan_header.data_type;
949 if(scan_header.x_resolution>0.0)
950 img->sampleDistance=10.0*scan_header.x_resolution;
951 else
952 img->sampleDistance=10.0*main_header.bin_size;
953 break;
954 case ECAT7_POLARMAP:
955 img->dimy=img->dimz=1;
956 img->polarmap_num_rings=polmap_header.num_rings;
959 for(i=0; i<img->polarmap_num_rings; i++) {
960 img->polarmap_sectors_per_ring[i]=polmap_header.sectors_per_ring[i];
961 img->polarmap_ring_position[i]=polmap_header.ring_position[i];
962 img->polarmap_ring_angle[i]=polmap_header.ring_angle[i];
963 }
964 img->polarmap_start_angle=polmap_header.start_angle;
965 for(i=0, img->dimx=0; i<img->polarmap_num_rings; i++)
966 img->dimx+=img->polarmap_sectors_per_ring[i];
967 /* pixel_size actually contains volume, in cubic cm */
968 img->sizex=img->sizey=img->sizez=0.001*polmap_header.pixel_size;
969 break;
970 }
971
973 return STATUS_OK;
974}
975/*****************************************************************************/
976
977/*****************************************************************************/
985 if(h==NULL) return(0);
986 if(h->file_type==ECAT7_VOLUME8) return(1);
987 if(h->file_type==ECAT7_VOLUME16) return(1);
988 if(h->file_type==ECAT7_IMAGE8) return(1);
989 if(h->file_type==ECAT7_IMAGE16) return(1);
990 if(h->file_type==ECAT7_2DSCAN) return(1);
991 if(h->file_type==ECAT7_3DSCAN) return(1);
992 if(h->file_type==ECAT7_3DSCAN8) return(1);
993 if(h->file_type==ECAT7_3DSCANFIT) return(1);
994 if(h->file_type==ECAT7_POLARMAP) return(1);
995 return(0);
996}
997/*****************************************************************************/
998
999/*****************************************************************************/
1008int imgReadEcat7FirstFrame(const char *fname, IMG *img) {
1009 int ret=0;
1010
1011 if(IMG_TEST) printf("\nimgReadEcat7FirstFrame(%s, *img)\n", fname);
1012 /* Check the input */
1013 if(img==NULL) return STATUS_FAULT;
1016 if(fname==NULL) return STATUS_FAULT;
1017
1018 /* Read header information from file */
1019 ret=imgReadEcat7Header(fname, img); if(ret) return(ret);
1020 if(IMG_TEST>3) imgInfo(img);
1021
1022 /* Allocate memory for one frame */
1023 img->dimt=1;
1024 ret=imgAllocate(img, img->dimz, img->dimy, img->dimx, img->dimt);
1025 if(ret) return STATUS_NOMEMORY;
1026
1027 /* Read the first frame */
1028 ret=imgReadEcat7Frame(fname, 1, img, 0); if(ret) return(ret);
1029
1030 /* All went well */
1031 imgSetStatus(img, STATUS_OK);
1032 return STATUS_OK;
1033}
1034/*****************************************************************************/
1035
1036/*****************************************************************************/
1051int imgReadEcat7Frame(const char *fname, int frame_to_read, IMG *img, int frame_index) {
1052 FILE *fp;
1053 int ret, m, i, pi, xi, yi, frame, plane, seqplane, pxlNr;
1054 /* int blkNr=0; */
1055 ECAT7_mainheader main_header;
1056 ECAT7_imageheader image_header;
1057 ECAT7_2Dscanheader scan2d_header;
1058 ECAT7_scanheader scan_header;
1059 ECAT7_polmapheader polmap_header;
1060 ECAT7_MATRIXLIST mlist;
1061 ECAT7_Matval matval;
1062 float *fdata=NULL, *fptr;
1063
1064
1065 if(IMG_TEST) printf("\nimgReadEcat7Frame(%s, %d, *img, %d)\n",
1066 fname, frame_to_read, frame_index);
1067
1068 /* Check the input */
1069 if(img==NULL) return STATUS_FAULT;
1070 if(img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
1071 if(fname==NULL) return STATUS_FAULT;
1072 if(frame_index<0 || frame_index>img->dimt-1) return STATUS_FAULT;
1073 if(frame_to_read<1) return STATUS_FAULT;
1074
1075 /* Open file for read */
1076 if((fp=fopen(fname, "rb")) == NULL) return STATUS_NOFILE;
1077
1078 /* Read main header */
1079 ret=ecat7ReadMainheader(fp, &main_header);
1080 if(ret) {fclose(fp); return STATUS_NOMAINHEADER;}
1081 /* Check for magic number */
1082 if(strncmp(main_header.magic_number, ECAT7V_MAGICNR, 7)!=0) {
1083 fclose(fp); return STATUS_UNKNOWNFORMAT;}
1084 /* Check if file_type is supported */
1085 if(imgEcat7Supported(&main_header)==0) {
1086 fclose(fp); return STATUS_UNSUPPORTED;}
1087 /* Read matrix list and nr and sort it */
1088 ecat7InitMatlist(&mlist);
1089 ret=ecat7ReadMatlist(fp, &mlist);
1090 if(ret) {fclose(fp); return STATUS_NOMATLIST;}
1091 if(mlist.matrixNr<=0 || ecat7CheckMatlist(&mlist)) {
1092 fclose(fp); ecat7EmptyMatlist(&mlist); return STATUS_INVALIDMATLIST;}
1093 /* Make sure that plane and frame numbers are continuous */
1094 ecat7GatherMatlist(&mlist, 1, 1, 1, 1);
1095 ecat7SortMatlistByFrame(&mlist); /* printf("matlist sorted\n"); */
1096 /* Calculate and check the size of one data matrix */
1097 /*ret=ecat7GetMatrixBlockSize(&mlist, &blkNr); if(ret) {fclose(fp); return ret;}*/
1098
1099 /* Read all matrices that belong to the required frame */
1100 /*blkNr=-1;*/
1101 ret=0; seqplane=-1; pxlNr=img->dimx*img->dimy;
1102 for(m=0; m<mlist.matrixNr; m++) {
1103 /* get frame and plane */
1104 ecat7_id_to_val(mlist.matdir[m].id, &matval); plane=matval.plane;
1105 if(main_header.num_frames>=main_header.num_gates) frame=matval.frame;
1106 else frame=matval.gate; /* printf("frame=%d plane=%d\n", frame, plane); */
1107 if(frame!=frame_to_read) continue; /* do not process other frames */
1108 /*if(img->dimz>1) seqplane++; else seqplane=plane-1; */
1109 if(img->_fileFormat==IMG_E7_2D) seqplane=plane-1; else seqplane++;
1110
1111 /* Read subheader and data */
1112 if(IMG_TEST>4) printf("reading matrix %d,%d\n", frame, plane);
1113 if(img->type==IMG_TYPE_IMAGE) { /* 2D or 3D image */
1114 ret=ecat7ReadImageMatrix(fp, mlist.matdir[m].strtblk,
1115 mlist.matdir[m].endblk, &image_header, &fdata);
1116 } else if(img->type==IMG_TYPE_POLARMAP) { /* polarmap */
1117 ret=ecat7ReadPolarmapMatrix(fp, mlist.matdir[m].strtblk,
1118 mlist.matdir[m].endblk, &polmap_header, &fdata);
1119 } else if(img->dimz>1) { /* 3D sinogram */
1120 ret=ecat7ReadScanMatrix(fp, mlist.matdir[m].strtblk,
1121 mlist.matdir[m].endblk, &scan_header, &fdata);
1122 } else { /* 2D sinogram */
1123 ret=ecat7Read2DScanMatrix(fp, mlist.matdir[m].strtblk,
1124 mlist.matdir[m].endblk, &scan2d_header, &fdata);
1125 }
1126 if(ret || fdata==NULL) {
1127 fclose(fp); ecat7EmptyMatlist(&mlist); return STATUS_NOMATRIX;}
1128
1129 /* Copy information concerning this frame and make correction to data */
1130 if(img->type==IMG_TYPE_IMAGE) {
1131 img->start[frame_index]=image_header.frame_start_time/1000.;
1132 img->end[frame_index]=img->start[frame_index]+image_header.frame_duration/1000.;
1133 img->mid[frame_index]=0.5*(img->start[frame_index]+img->end[frame_index]);
1134 if(image_header.decay_corr_fctr>1.0) {
1135 img->decayCorrFactor[frame_index]=image_header.decay_corr_fctr;}
1136 } else if(img->type==IMG_TYPE_POLARMAP) { /* polarmap */
1137 img->start[frame_index]=polmap_header.frame_start_time/1000.;
1138 img->end[frame_index]=img->start[frame_index]+polmap_header.frame_duration/1000.;
1139 img->mid[frame_index]=0.5*(img->start[frame_index]+img->end[frame_index]);
1140 } else if(img->dimz>1) {
1141 img->start[frame_index]=scan_header.frame_start_time/1000.;
1142 img->end[frame_index]=img->start[frame_index]+scan2d_header.frame_duration/1000.;
1143 img->mid[frame_index]=0.5*(img->start[frame_index]+img->end[frame_index]);
1144 /* also, correct for dead-time */
1145 if(scan_header.deadtime_correction_factor>0.0)
1146 for(i=0, fptr=fdata; i<img->dimz*pxlNr; i++, fptr++)
1147 *fptr*=scan_header.deadtime_correction_factor;
1148 img->prompts[frame_index]=(float)scan_header.prompts;
1149 img->randoms[frame_index]=scan_header.delayed;
1150 } else {
1151 img->start[frame_index]=scan2d_header.frame_start_time/1000.;
1152 img->end[frame_index]=img->start[frame_index]+scan2d_header.frame_duration/1000.;
1153 img->mid[frame_index]=0.5*(img->start[frame_index]+img->end[frame_index]);
1154 /* also, correct for dead-time */
1155 if(scan2d_header.deadtime_correction_factor>0.0)
1156 for(i=0, fptr=fdata; i<pxlNr; i++, fptr++)
1157 *fptr*=scan2d_header.deadtime_correction_factor;
1158 img->prompts[frame_index]=(float)scan2d_header.prompts;
1159 img->randoms[frame_index]=scan2d_header.delayed;
1160 }
1161 /* Copy matrix data through volume planes */
1162 if(img->_fileFormat!=IMG_E7_2D) {
1163 /* if(img->dimz>1) { */
1164 for(pi=0; pi<img->dimz; pi++) {
1165 if(IMG_TEST>5) printf(" putting data into m[%d][][][%d]\n", pi, frame_index);
1166 for(yi=0, fptr=fdata+pi*pxlNr; yi<img->dimy; yi++)
1167 for(xi=0; xi<img->dimx; xi++)
1168 img->m[pi][yi][xi][frame_index]= *fptr++;
1169 }
1170 } else {
1171 if(IMG_TEST>5) printf(" putting data into m[%d][][][%d]\n", seqplane, frame_index);
1172 for(yi=0, fptr=fdata; yi<img->dimy; yi++)
1173 for(xi=0; xi<img->dimx; xi++)
1174 img->m[seqplane][yi][xi][frame_index]= *fptr++;
1175 img->planeNumber[seqplane]=plane;
1176 }
1177 free(fdata);
1178 /* Calibrate */
1179 if(main_header.ecat_calibration_factor>0.0)
1180 for(pi=0; pi<img->dimz; pi++)
1181 for(yi=0; yi<img->dimy; yi++) for(xi=0; xi<img->dimx; xi++)
1182 img->m[pi][yi][xi][frame_index]*=main_header.ecat_calibration_factor;
1183 } /* next matrix */
1184 if(IMG_TEST>3) printf("end of matrices.\n");
1185 ecat7EmptyMatlist(&mlist);
1186 fclose(fp);
1187
1188 /* seqplane is <0 only if this frame did not exist at all; return -1 */
1189 if(IMG_TEST>4) printf("last_seqplane := %d.\n", seqplane);
1190 if(seqplane<0) return STATUS_NOMATRIX;
1191
1192 /* check that correct number of planes was read */
1193 if(seqplane>0 && (seqplane+1 != img->dimz)) return STATUS_MISSINGMATRIX;
1194
1195 /* All went well */
1196 imgSetStatus(img, STATUS_OK);
1197 return STATUS_OK;
1198}
1199/*****************************************************************************/
1200
1201/*****************************************************************************/
1222int imgWriteEcat7Frame(const char *fname, int frame_to_write, IMG *img, int frame_index) {
1223 IMG test_img;
1224 int ret=0, pxlNr, zi, xi, yi, matrixId;
1225 ECAT7_mainheader main_header;
1226 ECAT7_imageheader image_header;
1227 ECAT7_scanheader scan_header;
1228 ECAT7_2Dscanheader scan2d_header;
1229 ECAT7_polmapheader polmap_header;
1230 void *sub_header=NULL;
1231 FILE *fp;
1232 float *fdata=NULL, *fptr;
1233
1234
1235 if(IMG_TEST) printf("\nimgWriteEcat7Frame(%s, %d, *img, %d)\n",
1236 fname, frame_to_write, frame_index);
1237
1238 /*
1239 * Check the input
1240 */
1241 if(fname==NULL) return STATUS_FAULT;
1242 if(img==NULL) return STATUS_FAULT;
1243 if(img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
1244 if(frame_to_write<0) return STATUS_FAULT;
1245 if(frame_index<0 || frame_index>=img->dimt) return STATUS_FAULT;
1246 if(img->_fileFormat!=IMG_E7 &&
1247 img->_fileFormat!=IMG_POLARMAP &&
1248 img->_fileFormat!=IMG_E7_2D) return STATUS_FAULT;
1249
1250 /* Initiate headers */
1251 memset(&main_header, 0, sizeof(ECAT7_mainheader));
1252 memset(&image_header,0, sizeof(ECAT7_imageheader));
1253 memset(&scan_header, 0, sizeof(ECAT7_scanheader));
1254 memset(&scan2d_header, 0, sizeof(ECAT7_2Dscanheader));
1255 memset(&polmap_header,0, sizeof(ECAT7_polmapheader));
1256 imgInit(&test_img);
1257
1258
1259 /*
1260 * If file does not exist, then create it with new mainheader,
1261 * and if it does exist, then read and check header information.
1262 * Create or edit mainheader to contain correct frame nr.
1263 * In any case, leave file pointer open for write.
1264 */
1265 if(access(fname, 0) == -1) { /* file does not exist */
1266
1267 /* Set main header */
1268 imgSetEcat7MHeader(img, &main_header);
1269 main_header.bin_size=img->sampleDistance/10.0;
1270 if(frame_to_write==0) frame_to_write=1;
1271 main_header.num_frames=frame_to_write;
1272
1273 /* Open file, write main header and initiate matrix list */
1274 fp=ecat7Create(fname, &main_header); if(fp==NULL) return STATUS_NOWRITEPERM;
1275
1276 } else { /* file exists */
1277
1278 /* Read header information for checking */
1279 ret=imgReadEcat7Header(fname, &test_img); if(ret!=0) return ret;
1280 /* Check that file format is the same */
1281 if(img->_fileFormat!=test_img._fileFormat || img->type!=test_img.type)
1282 return STATUS_WRONGFILETYPE;
1283 /* Check that matrix sizes are the same */
1284 if(img->dimz!=test_img.dimz || img->dimx!=test_img.dimx ||
1285 img->dimy!=test_img.dimy)
1286 return STATUS_VARMATSIZE;
1287 imgEmpty(&test_img);
1288
1289 /* Open the file for read and write */
1290 if((fp=fopen(fname, "r+b"))==NULL) return STATUS_NOWRITEPERM;
1291
1292 /* Read the mainheader, set new frame number, and write it back */
1293 if((ret=ecat7ReadMainheader(fp, &main_header))!=0) return STATUS_NOMAINHEADER;
1294 if(frame_to_write==0) frame_to_write=main_header.num_frames+1;
1295 if(main_header.num_frames<frame_to_write)
1296 main_header.num_frames=frame_to_write;
1297 if((ret=ecat7WriteMainheader(fp, &main_header))!=0) return STATUS_NOWRITEPERM;
1298
1299 }
1300 if(IMG_TEST>2) {
1301 printf("frame_to_write := %d\n", frame_to_write);
1302 }
1303
1304 /* Allocate memory for matrix float data */
1305 pxlNr=img->dimx*img->dimy*img->dimz; /* for 2D too! */
1306 fdata=(float*)malloc(pxlNr*sizeof(float));
1307 if(fdata==NULL) {fclose(fp); return STATUS_NOMEMORY;}
1308
1309 /* Set matrix subheader */
1310 if(img->_fileFormat==IMG_E7) {
1311 if(img->type==IMG_TYPE_RAW) sub_header=(void*)&scan_header;
1312 else sub_header=&image_header;
1313 } else if(img->_fileFormat==IMG_E7_2D) {
1314 if(img->type==IMG_TYPE_RAW) sub_header=(void*)&scan_header;
1315 else sub_header=(void*)&image_header;
1316 } else if(img->_fileFormat==IMG_POLARMAP) {
1317 sub_header=(void*)&polmap_header;
1318 } else {fclose(fp); return STATUS_FAULT;}
1319 imgSetEcat7SHeader(img, sub_header);
1320
1321 /* Copy matrix pixel values to fdata */
1322 fptr=fdata;
1323 for(zi=0; zi<img->dimz; zi++)
1324 for(yi=0; yi<img->dimy; yi++) for(xi=0; xi<img->dimx; xi++)
1325 *fptr++=img->m[zi][yi][xi][frame_index];
1326
1327 /* Write subheader and data, and set the rest of subheader contents */
1328 fptr=fdata; ret=-1;
1329 if(img->_fileFormat==IMG_E7) {
1330 /* Create new matrix id (i.e. matnum) */
1331 matrixId=ecat7_val_to_id(frame_to_write, 1, 1, 0, 0);
1332 if(img->type==IMG_TYPE_RAW) {
1333 scan_header.frame_start_time=(int)temp_roundf(1000.*img->start[frame_index]);
1334 scan_header.frame_duration=
1335 (int)temp_roundf(1000.*(img->end[frame_index]-img->start[frame_index]));
1336 scan_header.prompts=temp_roundf(img->prompts[frame_index]);
1337 scan_header.delayed=temp_roundf(img->randoms[frame_index]);
1338 ret=ecat7WriteScanMatrix(fp, matrixId, &scan_header, fptr);
1339 } else {
1340 image_header.frame_start_time=(int)temp_roundf(1000.*img->start[frame_index]);
1341 image_header.frame_duration=
1342 (int)temp_roundf(1000.*(img->end[frame_index]-img->start[frame_index]));
1343 image_header.decay_corr_fctr=img->decayCorrFactor[frame_index];
1344 /*ecat7PrintImageheader(&image_header, stdout);*/
1345 ret=ecat7WriteImageMatrix(fp, matrixId, &image_header, fptr);
1346 }
1347 } else if(img->_fileFormat==IMG_E7_2D) {
1348 for(zi=0; zi<img->dimz; zi++, fptr+=img->dimx*img->dimy) {
1349 /* Create new matrix id (i.e. matnum) */
1350 matrixId=ecat7_val_to_id(frame_to_write, img->planeNumber[zi], 1, 0, 0);
1351 if(img->type==IMG_TYPE_RAW) {
1352 scan2d_header.frame_start_time=
1353 (int)temp_roundf(1000.*img->start[frame_index]);
1354 scan2d_header.frame_duration=
1355 (int)temp_roundf(1000.*(img->end[frame_index]-img->start[frame_index]));
1356 scan2d_header.prompts=temp_roundf(img->prompts[frame_index]);
1357 scan2d_header.delayed=temp_roundf(img->randoms[frame_index]);
1358 ret=ecat7Write2DScanMatrix(fp, matrixId, &scan2d_header, fptr);
1359 } else {
1360 image_header.frame_start_time=
1361 (int)temp_roundf(1000.*img->start[frame_index]);
1362 image_header.frame_duration=
1363 (int)temp_roundf(1000.*(img->end[frame_index]-img->start[frame_index]));
1364 image_header.decay_corr_fctr=img->decayCorrFactor[frame_index];
1365 ret=ecat7WriteImageMatrix(fp, matrixId, &image_header, fptr);
1366 }
1367 if(ret!=0) break;
1368 } /* next plane */
1369 } else if(img->_fileFormat==IMG_POLARMAP) {
1370 /* Create new matrix id (i.e. matnum) */
1371 matrixId=ecat7_val_to_id(frame_to_write, 1, 1, 0, 0);
1372 polmap_header.frame_start_time=(int)temp_roundf(1000.*img->start[frame_index]);
1373 polmap_header.frame_duration=
1374 (int)temp_roundf(1000.*(img->end[frame_index]-img->start[frame_index]));
1375 ret=ecat7WritePolarmapMatrix(fp, matrixId, &polmap_header, fptr);
1376 }
1377 free(fdata); fclose(fp);
1378 if(ret) return STATUS_DISKFULL;
1379
1380 return STATUS_OK;
1381}
1382/*****************************************************************************/
1383
1384/*****************************************************************************/
1391void imgSetEcat7SHeader(IMG *img, void *h) {
1392 ECAT7_imageheader *image_header;
1393 ECAT7_scanheader *scan_header;
1394 ECAT7_2Dscanheader *scan2d_header;
1395 ECAT7_polmapheader *polmap_header;
1396 int i;
1397
1398 if(img->type==IMG_TYPE_POLARMAP) {
1399 polmap_header=(ECAT7_polmapheader*)h;
1400 polmap_header->data_type=ECAT7_SUNI2;
1401 polmap_header->num_rings=img->polarmap_num_rings;
1402 if(polmap_header->num_rings>32) polmap_header->num_rings=32;
1403 for(i=0; i<polmap_header->num_rings; i++) {
1404 polmap_header->sectors_per_ring[i]=img->polarmap_sectors_per_ring[i];
1405 polmap_header->ring_position[i]=img->polarmap_ring_position[i];
1406 polmap_header->ring_angle[i]=img->polarmap_ring_angle[i];
1407 }
1408 polmap_header->start_angle=258;
1409 polmap_header->pixel_size=1000.0*img->sizex;
1410 polmap_header->quant_units=0; /* default, see main header */
1411 } else if(img->type==IMG_TYPE_RAW) {
1412 if(img->_fileFormat==IMG_E7_2D) {
1413 scan2d_header=(ECAT7_2Dscanheader*)h;
1414 scan2d_header->num_dimensions=2;
1415 scan2d_header->num_z_elements=1;
1416 scan2d_header->data_type=ECAT7_SUNI2;
1417 scan2d_header->num_r_elements=img->dimx;
1418 scan2d_header->num_angles=img->dimy;
1419 } else {
1420 scan_header=(ECAT7_scanheader*)h;
1421 scan_header->x_resolution=img->sampleDistance/10.0;
1422 scan_header->num_dimensions=4;
1423 if(img->dimz==239) {
1424 scan_header->num_z_elements[0]=63;
1425 scan_header->num_z_elements[1]=106;
1426 scan_header->num_z_elements[2]=70;
1427 } else {
1428 scan_header->num_z_elements[0]=img->dimz;
1429 }
1430 scan_header->storage_order=1;
1431 scan_header->data_type=ECAT7_SUNI2;
1432 scan_header->num_r_elements=img->dimx;
1433 scan_header->num_angles=img->dimy;
1434 }
1435 } else {
1436 image_header=(ECAT7_imageheader*)h;
1437 image_header->data_type=ECAT7_SUNI2;
1438 image_header->x_dimension=img->dimx;
1439 image_header->y_dimension=img->dimy;
1440 image_header->recon_zoom=img->zoom;
1441 image_header->x_pixel_size=0.1*img->sizex;
1442 image_header->y_pixel_size=0.1*img->sizey;
1443 image_header->z_pixel_size=0.1*img->sizez;
1444 image_header->x_resolution=0.1*img->resolutionx;
1445 image_header->y_resolution=0.1*img->resolutiony;
1446 image_header->z_resolution=0.1*img->resolutionz;
1447 if(img->_fileFormat==IMG_E7_2D) {
1448 image_header->num_dimensions=2;
1449 image_header->z_dimension=1;
1450 } else {
1451 image_header->num_dimensions=3;
1452 image_header->z_dimension=img->dimz;
1453 }
1454 for(i=0; i<49; i++) image_header->fill_user[i]=0;
1455 }
1456}
1457/*****************************************************************************/
1458
1459/*****************************************************************************/
#define ECAT7_VOLUME8
Definition: ecat7.h:73
#define ECAT7_3DSCAN
Definition: ecat7.h:78
#define ECAT7_3DSCAN8
Definition: ecat7.h:79
#define ECAT7_IMAGE16
Definition: ecat7.h:69
char ecat7errmsg[128]
Definition: ecat7.h:99
#define ECAT7_3DSCANFIT
Definition: ecat7.h:81
#define ECAT7_VOLUME16
Definition: ecat7.h:74
#define ECAT7V_MAGICNR
Definition: ecat7.h:53
#define ECAT7_IMAGE8
Definition: ecat7.h:77
#define ECAT7S_MAGICNR
Definition: ecat7.h:54
#define ECAT7_POLARMAP
Definition: ecat7.h:72
int ECAT7_TEST
Definition: ecat7.h:101
#define ECAT7_SUNI2
Definition: ecat7.h:63
#define ECAT7_2DSCAN
Definition: ecat7.h:68
int ecat7ReadMatlist(FILE *fp, ECAT7_MATRIXLIST *ml)
Definition: ecat7ml.c:86
void ecat7InitMatlist(ECAT7_MATRIXLIST *mlist)
Definition: ecat7ml.c:59
void ecat7SortMatlistByFrame(ECAT7_MATRIXLIST *ml)
Definition: ecat7ml.c:340
int ecat7GetPlaneAndFrameNr(ECAT7_MATRIXLIST *mlist, ECAT7_mainheader *h, int *plane_nr, int *frame_nr)
Definition: ecat7ml.c:409
int ecat7GetMatrixBlockSize(ECAT7_MATRIXLIST *mlist, int *blk_nr)
Definition: ecat7ml.c:455
void ecat7SortMatlistByPlane(ECAT7_MATRIXLIST *ml)
Definition: ecat7ml.c:314
void ecat7_id_to_val(int matrix_id, ECAT7_Matval *matval)
Definition: ecat7ml.c:299
void ecat7EmptyMatlist(ECAT7_MATRIXLIST *mlist)
Definition: ecat7ml.c:70
int ecat7_val_to_id(int frame, int plane, int gate, int data, int bed)
Definition: ecat7ml.c:282
int ecat7GatherMatlist(ECAT7_MATRIXLIST *ml, short int do_planes, short int do_frames, short int do_gates, short int do_beds)
Definition: ecat7ml.c:572
void ecat7PrintMatlist(ECAT7_MATRIXLIST *ml)
Definition: ecat7ml.c:149
int ecat7CheckMatlist(ECAT7_MATRIXLIST *ml)
Definition: ecat7ml.c:366
int ecat7Read2DScanMatrix(FILE *fp, int first_block, int last_block, ECAT7_2Dscanheader *h, float **fdata)
Definition: ecat7r.c:749
int ecat7ReadScanheader(FILE *fp, int blk, ECAT7_scanheader *h)
Definition: ecat7r.c:424
int ecat7ReadPolmapheader(FILE *fp, int blk, ECAT7_polmapheader *h)
Definition: ecat7r.c:325
int ecat7ReadMainheader(FILE *fp, ECAT7_mainheader *h)
Definition: ecat7r.c:78
int ecat7ReadPolarmapMatrix(FILE *fp, int first_block, int last_block, ECAT7_polmapheader *h, float **fdata)
Definition: ecat7r.c:939
int ecat7Read2DScanheader(FILE *fp, int blk, ECAT7_2Dscanheader *h)
Definition: ecat7r.c:485
int ecat7ReadImageMatrix(FILE *fp, int first_block, int last_block, ECAT7_imageheader *h, float **fdata)
Definition: ecat7r.c:656
int ecat7ReadImageheader(FILE *fp, int blk, ECAT7_imageheader *h)
Definition: ecat7r.c:177
int ecat7ReadScanMatrix(FILE *fp, int first_block, int last_block, ECAT7_scanheader *h, float **fdata)
Definition: ecat7r.c:844
int ecat7WriteImageMatrix(FILE *fp, int matrix_id, ECAT7_imageheader *h, float *fdata)
Definition: ecat7w.c:682
int ecat7WriteScanMatrix(FILE *fp, int matrix_id, ECAT7_scanheader *h, float *fdata)
Definition: ecat7w.c:852
int ecat7WritePolarmapMatrix(FILE *fp, int matrix_id, ECAT7_polmapheader *h, float *fdata)
Definition: ecat7w.c:939
int ecat7Write2DScanMatrix(FILE *fp, int matrix_id, ECAT7_2Dscanheader *h, float *fdata)
Definition: ecat7w.c:767
FILE * ecat7Create(const char *fname, ECAT7_mainheader *h)
Definition: ecat7w.c:616
int ecat7WriteMainheader(FILE *fp, ECAT7_mainheader *h)
Definition: ecat7w.c:73
void imgInfo(IMG *image)
Definition: img.c:414
int imgAllocate(IMG *image, int planes, int rows, int columns, int frames)
Definition: img.c:285
void imgSetStatus(IMG *img, int status_index)
Definition: img.c:399
void imgEmpty(IMG *image)
Definition: img.c:216
void imgInit(IMG *image)
Definition: img.c:163
#define IMG_TYPE_RAW
Definition: img.h:81
@ STATUS_INVALIDPOLARMAP
Definition: img.h:126
@ STATUS_NOMATLIST
Definition: img.h:120
@ STATUS_OK
Definition: img.h:118
@ STATUS_DISKFULL
Definition: img.h:119
@ STATUS_WRONGFILETYPE
Definition: img.h:124
@ STATUS_NOWRITEPERM
Definition: img.h:119
@ STATUS_UNKNOWNFORMAT
Definition: img.h:118
@ STATUS_NOFILE
Definition: img.h:118
@ STATUS_NOMATRIX
Definition: img.h:121
@ STATUS_MISSINGMATRIX
Definition: img.h:119
@ STATUS_INVALIDMATLIST
Definition: img.h:120
@ STATUS_NOSUBHEADER
Definition: img.h:121
@ STATUS_VARMATSIZE
Definition: img.h:120
@ STATUS_UNSUPPORTED
Definition: img.h:119
@ STATUS_FAULT
Definition: img.h:118
@ STATUS_NOMAINHEADER
Definition: img.h:120
@ STATUS_NOMEMORY
Definition: img.h:118
int IMG_TEST
Definition: img.h:128
#define IMG_E7
Definition: img.h:86
#define IMG_STATUS_OCCUPIED
Definition: img.h:73
#define IMG_UNKNOWN
Definition: img.h:84
#define IMG_E7_2D
Definition: img.h:87
#define IMG_TYPE_POLARMAP
Definition: img.h:82
#define IMG_STATUS_INITIALIZED
Definition: img.h:72
#define IMG_POLARMAP
Definition: img.h:88
#define MAX_POLARMAP_NUM_RINGS
Definition: img.h:116
#define IMG_TYPE_IMAGE
Definition: img.h:80
int imgWrite2DEcat7(const char *fname, IMG *img)
Definition: img_e7.c:498
void imgGetEcat7MHeader(IMG *img, ECAT7_mainheader *h)
Definition: img_e7.c:681
int imgWriteEcat7(const char *fname, IMG *img)
Definition: img_e7.c:380
int imgReadEcat7Frame(const char *fname, int frame_to_read, IMG *img, int frame_index)
Definition: img_e7.c:1051
int imgEcat7Supported(ECAT7_mainheader *h)
Definition: img_e7.c:984
int imgReadEcat7FirstFrame(const char *fname, IMG *img)
Definition: img_e7.c:1008
int imgReadEcat7(const char *fname, IMG *img)
Definition: img_e7.c:83
int imgReadEcat7Header(const char *fname, IMG *img)
Definition: img_e7.c:827
int imgGetEcat7Fileformat(ECAT7_mainheader *h)
Definition: img_e7.c:794
int imgWriteEcat7Frame(const char *fname, int frame_to_write, IMG *img, int frame_index)
Definition: img_e7.c:1222
int imgWritePolarmap(const char *fname, IMG *img)
Definition: img_e7.c:606
void imgSetEcat7MHeader(IMG *img, ECAT7_mainheader *h)
Definition: img_e7.c:734
void imgSetEcat7SHeader(IMG *img, void *h)
Definition: img_e7.c:1391
char * imgIsotope(IMG *img)
Definition: imgdecay.c:110
void imgUnitToEcat7(IMG *img, ECAT7_mainheader *h)
Definition: imgunit.c:266
void imgUnitFromEcat7(IMG *img, ECAT7_mainheader *h)
Definition: imgunit.c:210
ECAT7_MatDir * matdir
Definition: ecat7.h:614
int id
Definition: ecat7.h:606
int strtblk
Definition: ecat7.h:607
int endblk
Definition: ecat7.h:608
int plane
Definition: ecat7.h:617
int gate
Definition: ecat7.h:617
int frame
Definition: ecat7.h:617
Definition: img.h:156
float sizex
Definition: img.h:208
int polarmap_num_rings
Definition: img.h:239
unsigned short int dimx
Definition: img.h:261
char type
Definition: img.h:198
float resolutionx
Definition: img.h:220
char patientName[32]
Definition: img.h:176
float resolutiony
Definition: img.h:222
char studyDescription[32]
Definition: img.h:192
float sampleDistance
Definition: img.h:206
short int polarmap_start_angle
Definition: img.h:252
float **** m
Definition: img.h:274
float transaxialFOV
Definition: img.h:204
char status
Definition: img.h:164
time_t scanStart
Definition: img.h:186
int _fileFormat
Definition: img.h:229
char decayCorrected
Definition: img.h:184
float * prompts
Definition: img.h:306
char userProcessCode[11]
Definition: img.h:190
unsigned short int dimt
Definition: img.h:259
int _dataType
Definition: img.h:226
int * planeNumber
Definition: img.h:284
char patientID[16]
Definition: img.h:178
int scanner
Definition: img.h:231
float sizey
Definition: img.h:210
float * start
Definition: img.h:290
unsigned short int dimz
Definition: img.h:265
int polarmap_sectors_per_ring[MAX_POLARMAP_NUM_RINGS]
Definition: img.h:244
unsigned short int dimy
Definition: img.h:263
int orientation
Definition: img.h:188
float * end
Definition: img.h:292
float zoom
Definition: img.h:200
char radiopharmaceutical[32]
Definition: img.h:180
float * decayCorrFactor
Definition: img.h:314
float isotopeHalflife
Definition: img.h:182
short int polarmap_ring_angle[MAX_POLARMAP_NUM_RINGS]
Definition: img.h:250
char studyNr[MAX_STUDYNR_LEN+1]
Definition: img.h:174
float * randoms
Definition: img.h:308
float axialFOV
Definition: img.h:202
float * mid
Definition: img.h:294
float polarmap_ring_position[MAX_POLARMAP_NUM_RINGS]
Definition: img.h:247
float sizez
Definition: img.h:212
float resolutionz
Definition: img.h:224
short int num_dimensions
Definition: ecat7.h:424
short int num_z_elements
Definition: ecat7.h:428
float x_resolution
Definition: ecat7.h:430
float deadtime_correction_factor
Definition: ecat7.h:452
int frame_start_time
Definition: ecat7.h:450
short int data_type
Definition: ecat7.h:423
short int num_angles
Definition: ecat7.h:426
short int num_r_elements
Definition: ecat7.h:425
int frame_duration
Definition: ecat7.h:451
short int y_dimension
Definition: ecat7.h:236
short int x_dimension
Definition: ecat7.h:234
float x_pixel_size
Definition: ecat7.h:254
float z_pixel_size
Definition: ecat7.h:258
int frame_start_time
Definition: ecat7.h:262
float recon_zoom
Definition: ecat7.h:246
float decay_corr_fctr
Definition: ecat7.h:278
short int z_dimension
Definition: ecat7.h:238
float y_resolution
Definition: ecat7.h:268
float x_resolution
Definition: ecat7.h:266
short int data_type
Definition: ecat7.h:230
float z_resolution
Definition: ecat7.h:270
short int fill_user[49]
Definition: ecat7.h:350
short int num_dimensions
Definition: ecat7.h:232
int frame_duration
Definition: ecat7.h:260
float y_pixel_size
Definition: ecat7.h:256
char patient_name[32]
Definition: ecat7.h:158
char study_description[32]
Definition: ecat7.h:178
short int patient_orientation
Definition: ecat7.h:183
short int file_type
Definition: ecat7.h:113
char isotope_name[8]
Definition: ecat7.h:119
int scan_start_time
Definition: ecat7.h:117
float distance_scanned
Definition: ecat7.h:137
char patient_id[16]
Definition: ecat7.h:156
float transaxial_fov
Definition: ecat7.h:139
short int sw_version
Definition: ecat7.h:109
short int num_gates
Definition: ecat7.h:191
char magic_number[14]
Definition: ecat7.h:105
float plane_separation
Definition: ecat7.h:199
short int num_frames
Definition: ecat7.h:189
float isotope_halflife
Definition: ecat7.h:121
char user_process_code[10]
Definition: ecat7.h:207
short int num_planes
Definition: ecat7.h:187
char radiopharmaceutical[32]
Definition: ecat7.h:123
float bin_size
Definition: ecat7.h:211
short int num_bed_pos
Definition: ecat7.h:193
float ecat_calibration_factor
Definition: ecat7.h:146
short int system_type
Definition: ecat7.h:111
char study_type[12]
Definition: ecat7.h:154
float ring_position[32]
Definition: ecat7.h:581
float pixel_size
Definition: ecat7.h:590
short int num_rings
Definition: ecat7.h:579
short int sectors_per_ring[32]
Definition: ecat7.h:580
short int data_type
Definition: ecat7.h:577
short int quant_units
Definition: ecat7.h:594
int frame_start_time
Definition: ecat7.h:592
short int start_angle
Definition: ecat7.h:583
int frame_duration
Definition: ecat7.h:591
short int ring_angle[32]
Definition: ecat7.h:582
float x_resolution
Definition: ecat7.h:373
short int num_dimensions
Definition: ecat7.h:357
short int num_angles
Definition: ecat7.h:361
short int num_z_elements[64]
Definition: ecat7.h:365
int frame_start_time
Definition: ecat7.h:409
float deadtime_correction_factor
Definition: ecat7.h:413
short int data_type
Definition: ecat7.h:355
int frame_duration
Definition: ecat7.h:411
short int num_r_elements
Definition: ecat7.h:359
short int storage_order
Definition: ecat7.h:369