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 /*****************************************************************************/
83 int 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);}
124  ecat7SortMatlistByPlane(&mlist);
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:
182  img->type=IMG_TYPE_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);}
193  imgSetStatus(img, STATUS_OK);
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 
364  imgSetStatus(img, STATUS_OK);
365  return(0);
366 }
367 /*****************************************************************************/
368 
369 /*****************************************************************************/
380 int 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 
482  imgSetStatus(img, STATUS_OK);
483  return(0);
484 }
485 /*****************************************************************************/
486 
487 /*****************************************************************************/
498 int 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 
590  imgSetStatus(img, STATUS_OK);
591  return(0);
592 }
593 /*****************************************************************************/
594 
595 /*****************************************************************************/
606 int 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 
669  imgSetStatus(img, STATUS_OK);
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);
691  img->scanStart=h->scan_start_time;
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);
751  else h->file_type=ECAT7_VOLUME16;
752  }
753  h->system_type=img->scanner;
754  h->scan_start_time=img->scanStart;
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 /*****************************************************************************/
827 int 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;
843  if(img->status!=IMG_STATUS_INITIALIZED) 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;
958  return STATUS_INVALIDPOLARMAP;
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 
972  imgSetStatus(img, STATUS_OK);
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 /*****************************************************************************/
1008 int 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;
1014  if(img->status!=IMG_STATUS_INITIALIZED) return STATUS_FAULT;
1015  imgSetStatus(img, 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 /*****************************************************************************/
1051 int 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 /*****************************************************************************/
1222 int 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 /*****************************************************************************/
1391 void 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
FILE * ecat7Create(const char *fname, ECAT7_mainheader *h)
Definition: ecat7w.c:616
int ecat7Write2DScanMatrix(FILE *fp, int matrix_id, ECAT7_2Dscanheader *h, float *fdata)
Definition: ecat7w.c:767
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