TPCCLIB
Loading...
Searching...
No Matches
img_e7.c
Go to the documentation of this file.
1
5/*****************************************************************************/
6#include "libtpcimgio.h"
7/*****************************************************************************/
8
9/*****************************************************************************/
21 const char *fname,
24 IMG *img
25) {
26 ECAT7_mainheader main_header;
27 ECAT7_imageheader image_header;
28 ECAT7_2Dscanheader scan2d_header;
29 ECAT7_scanheader scan_header;
30 ECAT7_polmapheader polmap_header;
31 ECAT7_MATRIXLIST mlist;
32 ECAT7_Matval matval;
33 float *fdata=NULL, *fptr;
34 int blkNr=0;
35
36
37 if(IMG_TEST) printf("imgReadEcat7(%s, *img)\n", fname);
38 /* Check the arguments */
39 if(fname==NULL) return(1);
40 if(img==NULL || img->status!=IMG_STATUS_INITIALIZED) {
41 imgSetStatus(img, STATUS_FAULT); return(2);}
42
43 /* Open file for read */
44 FILE *fp;
45 if((fp=fopen(fname, "rb"))==NULL) {imgSetStatus(img,STATUS_NOFILE); return(3);}
46
47 /* Read main header */
48 int ret=ecat7ReadMainheader(fp, &main_header);
49 if(ret) {fclose(fp); imgSetStatus(img, STATUS_UNKNOWNFORMAT); return(4);}
50 /* Check for magic number */
51 if(strncmp(main_header.magic_number, ECAT7V_MAGICNR, 7)!=0) {
52 fclose(fp); imgSetStatus(img, STATUS_UNKNOWNFORMAT); return(4);
53 }
54
55 /* Check if file_type is supported */
56 if(imgEcat7Supported(&main_header)==0) {
57 fclose(fp); imgSetStatus(img, STATUS_UNSUPPORTED); return(5);
58 }
59
60 /* Read matrix list */
61 ecat7InitMatlist(&mlist);
62 ret=ecat7ReadMatlist(fp, &mlist, IMG_TEST-1);
63 if(ret || mlist.matrixNr<1 || ecat7CheckMatlist(&mlist)) {
64 if(IMG_TEST) printf(" ret=%d mlist.matrixNr=%d\n", ret, mlist.matrixNr);
65 fclose(fp); imgSetStatus(img, STATUS_INVALIDMATLIST); return(6);}
67 if(IMG_TEST>2) ecat7PrintMatlist(&mlist);
68
69 /* Calculate the number of planes, frames and gates */
70 /* Check that all planes have equal nr of frames (gates) */
71 /* and check that frames (gates) are consequentally numbered */
72 int frame, plane, prev_frame, prev_plane, planeNr, frameNr;
73 prev_plane=plane=-1; prev_frame=frame=-1; frameNr=planeNr=0; ret=0;
74 for(int m=0; m<mlist.matrixNr; m++) {
75 ecat7_id_to_val(mlist.matdir[m].id, &matval); plane=matval.plane;
76 if(main_header.num_frames>=main_header.num_gates) frame=matval.frame;
77 else frame=matval.gate;
78 if(plane!=prev_plane) {frameNr=1; planeNr++;}
79 else {frameNr++; if(prev_frame>0 && frame!=prev_frame+1) {ret=1; break;}}
80 prev_plane=plane; prev_frame=frame;
81 /* Calculate and check the size of one data matrix */
82 if(m==0) {
83 blkNr=mlist.matdir[m].endblk-mlist.matdir[m].strtblk;
84 } else if(blkNr!=mlist.matdir[m].endblk-mlist.matdir[m].strtblk) {
85 ret=2; break;
86 }
87 } /* next matrix */
88 if(IMG_TEST>2) printf("frameNr=%d planeNr=%d\n", frameNr, planeNr);
89 if(ret==1 || (frameNr*planeNr != mlist.matrixNr)) {
90 fclose(fp); imgSetStatus(img, STATUS_MISSINGMATRIX);
91 ecat7EmptyMatlist(&mlist); return(7);
92 }
93 if(ret==2) {
94 fclose(fp); imgSetStatus(img, STATUS_VARMATSIZE);
95 ecat7EmptyMatlist(&mlist); return(8);
96 }
97
98 /* Read the first subheader to get planeNr from volumes and to get x&y dim */
99 int m=0, dimx, dimy, dimz=1;
100 imgSetStatus(img, STATUS_NOSUBHEADER);
101 switch(main_header.file_type) {
102 case ECAT7_IMAGE8:
103 case ECAT7_IMAGE16:
104 case ECAT7_VOLUME8:
105 case ECAT7_VOLUME16:
106 img->type=IMG_TYPE_IMAGE;
107 ret=ecat7ReadImageheader(fp, mlist.matdir[m].strtblk, &image_header);
108 dimx=image_header.x_dimension; dimy=image_header.y_dimension;
109 if(image_header.num_dimensions>2 && image_header.z_dimension>1)
110 planeNr=dimz=image_header.z_dimension;
111 break;
112 case ECAT7_2DSCAN:
113 img->type=IMG_TYPE_RAW;
114 ret=ecat7Read2DScanheader(fp, mlist.matdir[m].strtblk, &scan2d_header);
115 dimx=scan2d_header.num_r_elements; dimy=scan2d_header.num_angles;
116 if(scan2d_header.num_dimensions>2 && scan2d_header.num_z_elements>1)
117 planeNr=dimz=scan2d_header.num_z_elements;
118 break;
119 case ECAT7_3DSCAN:
120 case ECAT7_3DSCAN8:
121 case ECAT7_3DSCANFIT:
122 img->type=IMG_TYPE_RAW;
123 ret=ecat7ReadScanheader(fp, mlist.matdir[m].strtblk, &scan_header);
124 dimx=scan_header.num_r_elements; dimy=scan_header.num_angles;
125 dimz=0;
126 for(int i=0; i<64; i++) dimz+=scan_header.num_z_elements[i];
127 planeNr=dimz;
128 /*if(scan_header.axial_compression!=0) {
129 img->statmsg=imgmsg[STATUS_UNSUPPORTEDAXIALCOMP]; ret=-1;}*/
130 break;
131 case ECAT7_POLARMAP:
133 ret=ecat7ReadPolmapheader(fp, mlist.matdir[m].strtblk, &polmap_header);
134 planeNr=dimz=dimy=1; dimx=0;
135 for(int i=0; i<polmap_header.num_rings; i++)
136 dimx+=polmap_header.sectors_per_ring[i];
137 break;
138 default: dimx=dimy=dimz=planeNr=0; ret=-1;
139 }
140 long long pxlNr=dimx*dimy;
141 if(ret || pxlNr<1 || planeNr<1) {
142 fclose(fp); ecat7EmptyMatlist(&mlist); return(9);}
143 imgSetStatus(img, STATUS_OK);
144
145 /* Allocate memory for IMG data */
146 ret=imgAllocate(img, planeNr, dimy, dimx, frameNr);
147 if(ret) {
148 fclose(fp); imgSetStatus(img, STATUS_NOMEMORY);
149 ecat7EmptyMatlist(&mlist); return(11);
150 }
151 /* Copy information from mainheader */
152 imgGetEcat7MHeader(img, &main_header);
153 /* Set fileFormat */
154 switch(main_header.file_type) {
155 case ECAT7_IMAGE8:
156 case ECAT7_IMAGE16:
157 img->_fileFormat=IMG_E7_2D; break;
158 case ECAT7_VOLUME8:
159 case ECAT7_VOLUME16:
160 img->_fileFormat=IMG_E7; break;
161 case ECAT7_2DSCAN:
162 img->_fileFormat=IMG_E7_2D; break;
163 case ECAT7_3DSCAN:
164 case ECAT7_3DSCAN8:
165 case ECAT7_3DSCANFIT:
166 img->_fileFormat=IMG_E7; break;
167 case ECAT7_POLARMAP:
168 img->_fileFormat=IMG_POLARMAP; break;
169 default:
170 img->_fileFormat=IMG_UNKNOWN; break;
171 }
172
173 if(dimz>1) {
174 /* Read ECAT volume matrices */
175 int fi=0;
176 for(int m=0; m<mlist.matrixNr; m++) {
177 /* Get matrix values */
178 ecat7_id_to_val(mlist.matdir[m].id, &matval);
179 /* Read subheader and data */
180 if(img->type==IMG_TYPE_IMAGE)
181 ret=ecat7ReadImageMatrix(fp, mlist.matdir[m].strtblk,
182 mlist.matdir[m].endblk, &image_header, &fdata);
183 else
184 ret=ecat7ReadScanMatrix(fp, mlist.matdir[m].strtblk,
185 mlist.matdir[m].endblk, &scan_header, &fdata);
186 if(ret || fdata==NULL) {
187 if(IMG_TEST) printf("ecat7ReadXMatrix()=%d\n%s\n", ret, ecat7errmsg);
188 fclose(fp); imgSetStatus(img, STATUS_NOMATRIX);
189 ecat7EmptyMatlist(&mlist); return(13);
190 }
191 /* Copy subheader information */
192 if(img->type==IMG_TYPE_POLARMAP) {
193 img->_dataType=polmap_header.data_type;
194 img->start[fi]=polmap_header.frame_start_time/1000.;
195 img->end[fi]=img->start[fi]+polmap_header.frame_duration/1000.;
196 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
197 img->sizex=0.001*polmap_header.pixel_size;
198 } else if(img->type==IMG_TYPE_IMAGE) {
199 img->_dataType=image_header.data_type;
200 img->start[fi]=image_header.frame_start_time/1000.;
201 img->end[fi]=img->start[fi]+image_header.frame_duration/1000.;
202 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
203 if(image_header.decay_corr_fctr>1.0) {
204 img->decayCorrFactor[fi]=image_header.decay_corr_fctr;
206 } else {
207 img->decayCorrFactor[fi]=0.0;
209 }
210 img->zoom=image_header.recon_zoom;
211 img->sizex=10.*image_header.x_pixel_size;
212 img->sizey=10.*image_header.y_pixel_size;
213 img->sizez=10.*image_header.z_pixel_size;
214 img->resolutionx=10.*image_header.x_resolution;
215 img->resolutiony=10.*image_header.y_resolution;
216 img->resolutionz=10.*image_header.z_resolution;
217 img->xform[0]=NIFTI_XFORM_UNKNOWN; // qform
218 img->xform[1]=NIFTI_XFORM_SCANNER_ANAT; // sform
219 img->quatern[6]=img->sizex; img->quatern[9]=img->sizex;
220 img->quatern[11]=img->sizey; img->quatern[13]=img->sizey;
221 img->quatern[16]=img->sizez; img->quatern[17]=img->sizez;
222 img->mt[0]=image_header.mt_1_1;
223 img->mt[1]=image_header.mt_1_2;
224 img->mt[2]=image_header.mt_1_3;
225 img->mt[3]=image_header.mt_1_4;
226 img->mt[4]=image_header.mt_2_1;
227 img->mt[5]=image_header.mt_2_2;
228 img->mt[6]=image_header.mt_2_3;
229 img->mt[7]=image_header.mt_2_4;
230 img->mt[8]=image_header.mt_3_1;
231 img->mt[9]=image_header.mt_3_2;
232 img->mt[10]=image_header.mt_3_3;
233 img->mt[11]=image_header.mt_3_4;
234 } else {
235 img->_dataType=scan_header.data_type;
236 img->start[fi]=scan_header.frame_start_time/1000.;
237 img->end[fi]=img->start[fi]+scan_header.frame_duration/1000.;
238 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
239 if(scan_header.x_resolution>0.0)
240 img->sampleDistance=10.0*scan_header.x_resolution;
241 else
242 img->sampleDistance=10.0*main_header.bin_size;
243 /* also, correct for dead-time */
244 if(scan_header.deadtime_correction_factor>0.0) {
245 fptr=fdata;
246 for(long long i=0; i<dimz*pxlNr; i++, fptr++)
247 *fptr*=scan_header.deadtime_correction_factor;
248 }
249 img->prompts[fi]=(float)scan_header.prompts;
250 img->randoms[fi]=scan_header.delayed;
251 }
252 /* Copy matrix data through volume planes */
253 for(int pi=0; pi<dimz; pi++) {
254 fptr=fdata+pi*pxlNr;
255 for(int yi=0; yi<dimy; yi++)
256 for(int xi=0; xi<dimx; xi++)
257 img->m[pi][yi][xi][fi]= *fptr++;
258 }
259 free(fdata); fi++;
260 } /* next matrix */
261 /* Set plane numbers */
262 for(int pi=0; pi<dimz; pi++) img->planeNumber[pi]=pi+1;
263 } else {
264 /* Read separate matrices */
265 prev_plane=plane=-1; prev_frame=frame=-1;
266 int pi=-1, fi=-1;
267 for(int m=0; m<mlist.matrixNr; m++) {
268 ecat7_id_to_val(mlist.matdir[m].id, &matval); plane=matval.plane;
269 if(main_header.num_frames>=main_header.num_gates) frame=matval.frame;
270 else frame=matval.gate;
271 if(plane!=prev_plane) {fi=0; pi++;} else fi++;
272 /* Read subheader and data */
273 if(img->type==IMG_TYPE_POLARMAP)
274 ret=ecat7ReadPolarmapMatrix(fp, mlist.matdir[m].strtblk,
275 mlist.matdir[m].endblk, &polmap_header, &fdata);
276 else if(img->type==IMG_TYPE_IMAGE)
277 ret=ecat7ReadImageMatrix(fp, mlist.matdir[m].strtblk,
278 mlist.matdir[m].endblk, &image_header, &fdata);
279 else
280 ret=ecat7Read2DScanMatrix(fp, mlist.matdir[m].strtblk,
281 mlist.matdir[m].endblk, &scan2d_header, &fdata);
282 if(ret || fdata==NULL) {
283 fclose(fp); imgSetStatus(img, STATUS_NOMATRIX);
284 ecat7EmptyMatlist(&mlist); return(13);
285 }
286 /* Copy subheader information */
287 if(fi==0) img->planeNumber[pi]=plane;
288 if(img->type==IMG_TYPE_POLARMAP) {
289 img->_dataType=polmap_header.data_type;
290 img->start[fi]=polmap_header.frame_start_time/1000.;
291 img->end[fi]=img->start[fi]+polmap_header.frame_duration/1000.;
292 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
293 img->sizex=0.001*polmap_header.pixel_size;
294 } else if(img->type==IMG_TYPE_IMAGE) {
295 img->_dataType=image_header.data_type;
296 img->start[fi]=image_header.frame_start_time/1000.;
297 img->end[fi]=img->start[fi]+image_header.frame_duration/1000.;
298 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
299 if(image_header.decay_corr_fctr>1.0) {
300 img->decayCorrFactor[fi]=image_header.decay_corr_fctr;
302 } else {
303 img->decayCorrFactor[fi]=0.0;
305 }
306 img->zoom=image_header.recon_zoom;
307 img->sizex=10.*image_header.x_pixel_size;
308 img->sizey=10.*image_header.y_pixel_size;
309 img->sizez=10.*image_header.z_pixel_size;
310 img->resolutionx=10.*image_header.x_resolution;
311 img->resolutiony=10.*image_header.y_resolution;
312 img->resolutionz=10.*image_header.z_resolution;
313 img->xform[0]=NIFTI_XFORM_UNKNOWN; // qform
314 img->xform[1]=NIFTI_XFORM_SCANNER_ANAT; // sform
315 img->quatern[6]=img->sizex; img->quatern[9]=img->sizex;
316 img->quatern[11]=img->sizey; img->quatern[13]=img->sizey;
317 img->quatern[16]=img->sizez; img->quatern[17]=img->sizez;
318 img->mt[0]=image_header.mt_1_1;
319 img->mt[1]=image_header.mt_1_2;
320 img->mt[2]=image_header.mt_1_3;
321 img->mt[3]=image_header.mt_1_4;
322 img->mt[4]=image_header.mt_2_1;
323 img->mt[5]=image_header.mt_2_2;
324 img->mt[6]=image_header.mt_2_3;
325 img->mt[7]=image_header.mt_2_4;
326 img->mt[8]=image_header.mt_3_1;
327 img->mt[9]=image_header.mt_3_2;
328 img->mt[10]=image_header.mt_3_3;
329 img->mt[11]=image_header.mt_3_4;
330 } else {
331 img->_dataType=scan2d_header.data_type;
332 img->start[fi]=scan2d_header.frame_start_time/1000.;
333 img->end[fi]=img->start[fi]+scan2d_header.frame_duration/1000.;
334 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
335 if(scan_header.x_resolution>0.0)
336 img->sampleDistance=10.0*scan_header.x_resolution;
337 else
338 img->sampleDistance=10.0*main_header.bin_size;
339 /* also, correct for dead-time */
340 if(scan2d_header.deadtime_correction_factor>0.0) {
341 fptr=fdata;
342 for(long long i=0; i<pxlNr; i++, fptr++)
343 *fptr*=scan2d_header.deadtime_correction_factor;
344 }
345 img->prompts[fi]=(float)scan_header.prompts;
346 img->randoms[fi]=scan_header.delayed;
347 }
348 /* Copy matrix data */
349 fptr=fdata;
350 for(int yi=0; yi<dimy; yi++) for(int xi=0; xi<dimx; xi++)
351 img->m[pi][yi][xi][fi]= *fptr++;
352 free(fdata);
353 /* prepare for the next matrix */
354 prev_plane=plane; prev_frame=frame;
355 } /* next matrix */
356 }
357 fclose(fp); ecat7EmptyMatlist(&mlist);
358
359 /* Calibrate */
360 if(main_header.ecat_calibration_factor>0.0)
361 for(int pi=0; pi<img->dimz; pi++)
362 for(int yi=0; yi<img->dimy; yi++) for(int xi=0; xi<img->dimx; xi++)
363 for(int fi=0; fi<img->dimt; fi++)
364 img->m[pi][yi][xi][fi]*=main_header.ecat_calibration_factor;
365
366 imgSetStatus(img, STATUS_OK);
367 return(0);
368}
369/*****************************************************************************/
370
371/*****************************************************************************/
382int imgWriteEcat7(const char *fname, IMG *img) {
383 ECAT7_mainheader main_header;
384 ECAT7_imageheader image_header;
385 ECAT7_scanheader scan_header;
386 FILE *fp;
387 int matrixId, ret;
388 float *fdata, *fptr;
389
390
391 if(IMG_TEST) printf("imgWriteEcat7(%s, *img)\n", fname);
392 if(IMG_TEST>1 && ECAT7_TEST==0) ECAT7_TEST=1;
393 /* Check the arguments */
394 if(fname==NULL) return(1);
395 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) {
396 imgSetStatus(img, STATUS_FAULT); return(2);}
397 if(img->type!=IMG_TYPE_RAW && img->type!=IMG_TYPE_IMAGE) {
398 imgSetStatus(img, STATUS_FAULT); return(2);}
399
400 /* Check image size */
401 if(img->dimt>511 || img->dimz>255 || img->dimx>1024 || img->dimy>1024) {
402 imgSetStatus(img, STATUS_INVALIDHEADER); return(2);}
403
404 /* Initiate headers */
405 memset(&main_header, 0, sizeof(ECAT7_mainheader));
406 memset(&image_header,0, sizeof(ECAT7_imageheader));
407 memset(&scan_header, 0, sizeof(ECAT7_scanheader));
408
409 /* Set main header */
410 imgSetEcat7MHeader(img, &main_header);
411 main_header.bin_size=img->sampleDistance/10.0;
412
413 /* Allocate memory for matrix float data */
414 long long pxlNr=img->dimx*img->dimy*img->dimz;
415 fdata=(float*)malloc(pxlNr*sizeof(float));
416 if(fdata==NULL) {imgSetStatus(img, STATUS_NOMEMORY); return(3);}
417
418 /* Open file, write main header and initiate matrix list */
419 fp=ecat7Create(fname, &main_header);
420 if(fp==NULL) {free(fdata); imgSetStatus(img, STATUS_NOWRITEPERM); return(6);}
421
422 /* Set (most of) subheader contents */
423 if(img->type==IMG_TYPE_RAW) {
424 scan_header.x_resolution=img->sampleDistance/10.0;
425 scan_header.num_dimensions=4;
426 if(img->dimz==239) {
427 scan_header.num_z_elements[0]=63;
428 scan_header.num_z_elements[1]=106;
429 scan_header.num_z_elements[2]=70;
430 } else {
431 scan_header.num_z_elements[0]=img->dimz;
432 }
433 scan_header.storage_order=1;
434 scan_header.data_type=ECAT7_SUNI2;
435 scan_header.num_r_elements=img->dimx;
436 scan_header.num_angles=img->dimy;
437 } else if(img->type==IMG_TYPE_IMAGE) {
438 image_header.num_dimensions=3;
439 image_header.z_dimension=img->dimz;
440 image_header.data_type=ECAT7_SUNI2;
441 image_header.x_dimension=img->dimx;
442 image_header.y_dimension=img->dimy;
443 image_header.recon_zoom=img->zoom;
444 image_header.x_pixel_size=0.1*img->sizex;
445 image_header.y_pixel_size=0.1*img->sizey;
446 image_header.z_pixel_size=0.1*img->sizez;
447 image_header.x_resolution=0.1*img->resolutionx;
448 image_header.y_resolution=0.1*img->resolutiony;
449 image_header.z_resolution=0.1*img->resolutionz;
450 img->quatern[6]=img->sizex; img->quatern[9]=img->sizex;
451 img->quatern[11]=img->sizey; img->quatern[13]=img->sizey;
452 img->quatern[16]=img->sizez; img->quatern[17]=img->sizez;
453 image_header.mt_1_1=img->mt[0];
454 image_header.mt_1_2=img->mt[1];
455 image_header.mt_1_3=img->mt[2];
456 image_header.mt_1_4=img->mt[3];
457 image_header.mt_2_1=img->mt[4];
458 image_header.mt_2_2=img->mt[5];
459 image_header.mt_2_3=img->mt[6];
460 image_header.mt_2_4=img->mt[7];
461 image_header.mt_3_1=img->mt[8];
462 image_header.mt_3_2=img->mt[9];
463 image_header.mt_3_3=img->mt[10];
464 image_header.mt_3_4=img->mt[11];
465 }
466
467 /* Write each matrix */
468 for(int fi=0; fi<img->dimt; fi++) {
469
470 /* Create new matrix id (i.e. matnum) */
471 matrixId=ecat7_val_to_id(fi+1, 1, 1, 0, 0);
472
473 /* Copy matrix pixel values to fdata */
474 fptr=fdata;
475 for(int pi=0; pi<img->dimz; pi++)
476 for(int yi=0; yi<img->dimy; yi++)
477 for(int xi=0; xi<img->dimx; xi++)
478 if(isfinite(img->m[pi][yi][xi][fi])) *fptr++=img->m[pi][yi][xi][fi]; else *fptr++=0.0;
479
480 /* Write subheader and data */
481 fptr=fdata;
482 if(img->type==IMG_TYPE_RAW) {
483 scan_header.frame_start_time=(int)temp_roundf(1000.*img->start[fi]);
484 scan_header.frame_duration=
485 (int)temp_roundf(1000.*(img->end[fi]-img->start[fi]));
486 scan_header.prompts=temp_roundf(img->prompts[fi]);
487 scan_header.delayed=temp_roundf(img->randoms[fi]);
488 /*ecat7PrintScanheader(&scan_header, stdout);*/
489 ret=ecat7WriteScanMatrix(fp, matrixId, &scan_header, fptr);
490 } else if(img->type==IMG_TYPE_IMAGE) {
491 image_header.frame_start_time=(int)temp_roundf(1000.*img->start[fi]);
492 image_header.frame_duration=(int)temp_roundf(1000.*(img->end[fi]-img->start[fi]));
494 image_header.decay_corr_fctr=img->decayCorrFactor[fi];
495 else
496 image_header.decay_corr_fctr=0.0;
497 /*ecat7PrintImageheader(&image_header, stdout);*/
498 ret=ecat7WriteImageMatrix(fp, matrixId, &image_header, fptr);
499 } else {
500 free(fdata); fclose(fp); imgSetStatus(img, STATUS_UNSUPPORTED); return(8);
501 }
502 if(ret) {
503 if(IMG_TEST) {printf("matrixId=%d ret=%d\n", matrixId, ret);}
504 free(fdata); fclose(fp); imgSetStatus(img, STATUS_DISKFULL); return(7);
505 }
506
507 } /* next matrix */
508 free(fdata); fclose(fp);
509
510 imgSetStatus(img, STATUS_OK);
511 return(0);
512}
513/*****************************************************************************/
514
515/*****************************************************************************/
526int imgWrite2DEcat7(const char *fname, IMG *img) {
527 ECAT7_mainheader main_header;
528 ECAT7_imageheader image_header;
529 ECAT7_2Dscanheader scan2d_header;
530 FILE *fp;
531 int matrixId, ret;
532 float *fdata, *fptr;
533
534
535 if(IMG_TEST) printf("imgWrite2DEcat7(%s, *img)\n", fname);
536 if(IMG_TEST>1 && ECAT7_TEST==0) ECAT7_TEST=1;
537 /* Check the arguments */
538 if(fname==NULL) {return(1);}
539 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) {
540 imgSetStatus(img, STATUS_FAULT); return(2);}
541
542 /* Check image size */
543 if(img->dimt>511 || img->dimz>255 || img->dimx>1024 || img->dimy>1024) {
544 imgSetStatus(img, STATUS_INVALIDHEADER); return(2);}
545
546 /* Initiate headers */
547 memset(&main_header, 0, sizeof(ECAT7_mainheader));
548 memset(&image_header,0, sizeof(ECAT7_imageheader));
549 memset(&scan2d_header, 0, sizeof(ECAT7_2Dscanheader));
550
551 /* Set main header */
552 imgSetEcat7MHeader(img, &main_header);
553 main_header.bin_size=img->sampleDistance/10.0;
554 if(img->type==IMG_TYPE_RAW) main_header.file_type=ECAT7_2DSCAN;
555 else main_header.file_type=ECAT7_IMAGE16;
556 main_header.num_planes=img->dimz;
557
558 /* Allocate memory for matrix float data */
559 long long pxlNr=img->dimx*img->dimy;
560 fdata=(float*)malloc(pxlNr*sizeof(float));
561 if(fdata==NULL) {imgSetStatus(img, STATUS_NOMEMORY); return(3);}
562
563 /* Open file, write main header and initiate matrix list */
564 fp=ecat7Create(fname, &main_header);
565 if(fp==NULL) {free(fdata); imgSetStatus(img, STATUS_NOWRITEPERM); return(6);}
566
567 /* Set (most of) subheader contents */
568 if(img->type==IMG_TYPE_RAW) {
569 scan2d_header.num_dimensions=2;
570 scan2d_header.num_z_elements=1;
571 scan2d_header.data_type=ECAT7_SUNI2;
572 scan2d_header.num_r_elements=img->dimx;
573 scan2d_header.num_angles=img->dimy;
574 } else if(img->type==IMG_TYPE_IMAGE) {
575 image_header.num_dimensions=2;
576 image_header.z_dimension=1;
577 image_header.data_type=ECAT7_SUNI2;
578 image_header.x_dimension=img->dimx;
579 image_header.y_dimension=img->dimy;
580 image_header.recon_zoom=img->zoom;
581 image_header.x_pixel_size=0.1*img->sizex;
582 image_header.y_pixel_size=0.1*img->sizey;
583 image_header.z_pixel_size=0.1*img->sizez;
584 image_header.x_resolution=0.1*img->resolutionx;
585 image_header.y_resolution=0.1*img->resolutiony;
586 image_header.z_resolution=0.1*img->resolutionz;
587 img->quatern[6]=img->sizex; img->quatern[9]=img->sizex;
588 img->quatern[11]=img->sizey; img->quatern[13]=img->sizey;
589 img->quatern[16]=img->sizez; img->quatern[17]=img->sizez;
590 image_header.mt_1_1=img->mt[0];
591 image_header.mt_1_2=img->mt[1];
592 image_header.mt_1_3=img->mt[2];
593 image_header.mt_1_4=img->mt[3];
594 image_header.mt_2_1=img->mt[4];
595 image_header.mt_2_2=img->mt[5];
596 image_header.mt_2_3=img->mt[6];
597 image_header.mt_2_4=img->mt[7];
598 image_header.mt_3_1=img->mt[8];
599 image_header.mt_3_2=img->mt[9];
600 image_header.mt_3_3=img->mt[10];
601 image_header.mt_3_4=img->mt[11];
602 }
603
604 /* Write each matrix */
605 for(int fi=0; fi<img->dimt; fi++) for(int pi=0; pi<img->dimz; pi++) {
606
607 /* Create new matrix id (i.e. matnum) */
608 matrixId=ecat7_val_to_id(fi+1, img->planeNumber[pi], 1, 0, 0);
609
610 /* Copy matrix pixel values to fdata */
611 fptr=fdata;
612 for(int yi=0; yi<img->dimy; yi++)
613 for(int xi=0; xi<img->dimx; xi++)
614 if(isfinite(img->m[pi][yi][xi][fi])) *fptr++=img->m[pi][yi][xi][fi]; else *fptr++=0.0;
615
616 /* Write subheader and data */
617 fptr=fdata;
618 if(img->type==IMG_TYPE_RAW) {
619 scan2d_header.frame_start_time=(int)temp_roundf(1000.*img->start[fi]);
620 scan2d_header.frame_duration=
621 (int)temp_roundf(1000.*(img->end[fi]-img->start[fi]));
622 scan2d_header.prompts=temp_roundf(img->prompts[fi]);
623 scan2d_header.delayed=temp_roundf(img->randoms[fi]);
624 ret=ecat7Write2DScanMatrix(fp, matrixId, &scan2d_header, fptr);
625 } else if(img->type==IMG_TYPE_IMAGE) {
626 image_header.frame_start_time=(int)temp_roundf(1000.*img->start[fi]);
627 image_header.frame_duration=
628 (int)temp_roundf(1000.*(img->end[fi]-img->start[fi]));
630 image_header.decay_corr_fctr=img->decayCorrFactor[fi];
631 else
632 image_header.decay_corr_fctr=0.0;
633 ret=ecat7WriteImageMatrix(fp, matrixId, &image_header, fptr);
634 } else {
635 free(fdata); fclose(fp); imgSetStatus(img, STATUS_UNSUPPORTED); return(8);
636 }
637 if(ret) {
638 if(IMG_TEST) {printf("matrixId=%d ret=%d\n", matrixId, ret);}
639 free(fdata); fclose(fp); imgSetStatus(img, STATUS_DISKFULL); return(7);
640 }
641
642 } /* next matrix */
643 free(fdata); fclose(fp);
644
645 imgSetStatus(img, STATUS_OK);
646 return(0);
647}
648/*****************************************************************************/
649
650/*****************************************************************************/
661int imgWritePolarmap(const char *fname, IMG *img) {
662 ECAT7_mainheader main_header;
663 ECAT7_polmapheader polmap_header;
664 FILE *fp;
665 int matrixId, ret;
666 float *fdata, *fptr;
667
668
669 if(IMG_TEST) printf("imgWritePolarmap(%s, *img)\n", fname);
670 if(IMG_TEST>1 && ECAT7_TEST==0) ECAT7_TEST=1;
671 /* Check the arguments */
672 if(fname==NULL) return(1);
673 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) {
674 imgSetStatus(img, STATUS_FAULT); return(2);}
675 if(img->type!=IMG_TYPE_POLARMAP) {
676 imgSetStatus(img, STATUS_FAULT); return(2);}
677
678 /* Check image size */
679 if(img->dimt>511 || img->dimz>255 || img->dimx>1024 || img->dimy>1024) {
680 imgSetStatus(img, STATUS_INVALIDHEADER); return(2);}
681
682 /* Initiate headers */
683 memset(&main_header, 0, sizeof(ECAT7_mainheader));
684 memset(&polmap_header,0, sizeof(ECAT7_polmapheader));
685
686 /* Set main header */
687 imgSetEcat7MHeader(img, &main_header);
688 main_header.bin_size=img->sampleDistance/10.0;
689
690 /* Allocate memory for matrix float data */
691 long long pxlNr=img->dimx*img->dimy*img->dimz;
692 fdata=(float*)malloc(pxlNr*sizeof(float));
693 if(fdata==NULL) {imgSetStatus(img, STATUS_NOMEMORY); return(3);}
694
695 /* Open file, write main header and initiate matrix list */
696 fp=ecat7Create(fname, &main_header);
697 if(fp==NULL) {free(fdata); imgSetStatus(img, STATUS_NOWRITEPERM); return(6);}
698
699 /* Set (most of) subheader contents */
700 imgSetEcat7SHeader(img, &polmap_header);
701
702 /* Write each matrix */
703 for(int fi=0; fi<img->dimt; fi++) {
704
705 /* Create new matrix id (i.e. matnum) */
706 matrixId=ecat7_val_to_id(fi+1, 1, 1, 0, 0);
707
708 /* Copy matrix pixel values to fdata */
709 fptr=fdata;
710 for(int pi=0; pi<img->dimz; pi++)
711 for(int yi=0; yi<img->dimy; yi++)
712 for(int xi=0; xi<img->dimx; xi++)
713 if(isfinite(img->m[pi][yi][xi][fi])) *fptr++=img->m[pi][yi][xi][fi]; else *fptr++=0.0;
714
715 /* Write subheader and data */
716 fptr=fdata;
717 polmap_header.frame_start_time=(int)temp_roundf(1000.*img->start[fi]);
718 polmap_header.frame_duration=
719 (int)temp_roundf(1000.*(img->end[fi]-img->start[fi]));
720 /*ecat7PrintImageheader(&image_header, stdout);*/
721 ret=ecat7WritePolarmapMatrix(fp, matrixId, &polmap_header, fptr);
722 if(ret) {
723 if(IMG_TEST) {printf("matrixId=%d ret=%d\n", matrixId, ret);}
724 free(fdata); fclose(fp); imgSetStatus(img, STATUS_DISKFULL); return(7);
725 }
726
727 } /* next matrix */
728 free(fdata); fclose(fp);
729
730 imgSetStatus(img, STATUS_OK);
731 return(0);
732}
733/*****************************************************************************/
734
735/*****************************************************************************/
743{
744 img->scanner=h->system_type;
745 imgUnitFromEcat7(img, h);
749 img->axialFOV=10.0*h->distance_scanned;
750 img->transaxialFOV=10.0*h->transaxial_fov;
752 strlcpy(img->patientName, h->patient_name, 32);
753 strncpy(img->patientID, h->patient_id, 16);
754 img->sizez=10.0*h->plane_separation;
755 switch(h->file_type) {
756 case ECAT7_IMAGE8:
757 case ECAT7_IMAGE16:
758 case ECAT7_VOLUME8:
759 case ECAT7_VOLUME16: img->type=IMG_TYPE_IMAGE; break;
760 case ECAT7_POLARMAP: img->type=IMG_TYPE_POLARMAP; break;
761 default: img->type=IMG_TYPE_RAW;
762 }
765 strncpy(img->userProcessCode, h->user_process_code, 10);
766 img->userProcessCode[10]=(char)0;
767 /* If valid study number is found in user_process_code, then take it */
771}
772/*****************************************************************************/
773
774/*****************************************************************************/
782{
783 h->sw_version=72;
784 if(img->type==IMG_TYPE_POLARMAP) {
785 strcpy(h->magic_number, ECAT7V_MAGICNR);
787 } else if(img->type==IMG_TYPE_RAW) {
788 strcpy(h->magic_number, ECAT7S_MAGICNR);
790 else h->file_type=ECAT7_3DSCAN;
791 } else {
792 strcpy(h->magic_number, ECAT7V_MAGICNR);
795 }
796 h->system_type=img->scanner;
799 imgUnitToEcat7(img, h);
801 h->transaxial_fov=img->transaxialFOV/10.0;
802 h->num_planes=img->dimz; /* h->num_planes=1; */
803 h->num_frames=img->dimt;
804 h->num_gates=1;
805 h->num_bed_pos=0;
806 h->distance_scanned=img->axialFOV/10.0;
807 h->plane_separation=img->sizez/10.0;
808 strncpy(h->radiopharmaceutical, img->radiopharmaceutical, 32);
809 strcpy(h->isotope_name, imgIsotope(img));
810 strlcpy(h->study_type, img->studyNr, 12);
811 strcpy(h->patient_name, img->patientName);
812 strcpy(h->patient_id, img->patientID);
814 strcpy(h->study_description, img->studyDescription);
817}
818/*****************************************************************************/
819
820/*****************************************************************************/
828 int fileFormat=IMG_UNKNOWN;
829 switch(h->file_type) {
830 case ECAT7_IMAGE8:
831 case ECAT7_IMAGE16:
832 fileFormat=IMG_E7_2D; break;
833 case ECAT7_VOLUME8:
834 case ECAT7_VOLUME16:
835 fileFormat=IMG_E7; break;
836 case ECAT7_2DSCAN:
837 fileFormat=IMG_E7_2D; break;
838 case ECAT7_3DSCAN:
839 case ECAT7_3DSCAN8:
840 case ECAT7_3DSCANFIT:
841 fileFormat=IMG_E7; break;
842 case ECAT7_POLARMAP:
843 fileFormat=IMG_POLARMAP; break;
844 default:
845 fileFormat=IMG_UNKNOWN; break;
846 }
847 return fileFormat;
848}
849/*****************************************************************************/
860int imgReadEcat7Header(const char *fname, IMG *img) {
861 FILE *fp;
862 int ret, m;
863 int planeNr, frameNr, blkNr=0;
864 ECAT7_mainheader main_header;
865 ECAT7_imageheader image_header;
866 ECAT7_2Dscanheader scan2d_header;
867 ECAT7_scanheader scan_header;
868 ECAT7_polmapheader polmap_header;
869 ECAT7_MATRIXLIST mlist;
870
871
872 if(IMG_TEST) printf("\nimgReadEcat7Header(%s, *img)\n", fname);
873
874 /* Check the arguments */
875 if(img==NULL) return STATUS_FAULT;
876 if(img->status!=IMG_STATUS_INITIALIZED) return STATUS_FAULT;
877 imgSetStatus(img, STATUS_FAULT);
878 if(fname==NULL) return STATUS_FAULT;
879
880 /* Open the file */
881 if((fp=fopen(fname, "rb")) == NULL) return STATUS_NOFILE;
882
883 /* Read main header */
884 ret=ecat7ReadMainheader(fp, &main_header);
885 if(ret) {fclose(fp); return STATUS_NOMAINHEADER;}
886 /* Check for magic number */
887 if(strncmp(main_header.magic_number, ECAT7V_MAGICNR, 7)!=0) {
888 fclose(fp); return STATUS_UNKNOWNFORMAT;}
889 /* Check if file_type is supported */
890 if(imgEcat7Supported(&main_header)==0) {fclose(fp); return STATUS_UNSUPPORTED;}
891 /* Copy main header information into IMG; sets also img.type */
892 imgGetEcat7MHeader(img, &main_header);
893 if(IMG_TEST>7) printf("img.type := %d\n", img->type);
894 img->_fileFormat=imgGetEcat7Fileformat(&main_header);
895 if(IMG_TEST>7) printf("img._fileFormat := %d\n", img->_fileFormat);
896 if(img->_fileFormat==IMG_UNKNOWN) {fclose(fp); return STATUS_UNSUPPORTED;}
897
898 /* Read matrix list */
899 ecat7InitMatlist(&mlist);
900 ret=ecat7ReadMatlist(fp, &mlist, IMG_TEST-1);
901 if(ret || mlist.matrixNr<1 || ecat7CheckMatlist(&mlist)) {
902 fclose(fp); return STATUS_INVALIDMATLIST;}
903 /* Make sure that plane and frame numbers are continuous */
904 ecat7GatherMatlist(&mlist, 1, 1, 1, 1);
905 /* Get plane and frame numbers and check that volume is full */
906 ret=ecat7GetPlaneAndFrameNr(&mlist, &main_header, &planeNr, &frameNr);
907 if(ret) {ecat7EmptyMatlist(&mlist); fclose(fp); return ret;}
908 img->dimz=planeNr;
909 img->dimt=frameNr;
910 /* Get and check the size of data matrices */
911 ret=ecat7GetMatrixBlockSize(&mlist, &blkNr);
912 if(ret) {ecat7EmptyMatlist(&mlist); fclose(fp); return ret;}
913
914 /* Read one subheader */
915 if(IMG_TEST>5) printf("main_header.file_type := %d\n", main_header.file_type);
916 m=0;
917 switch(main_header.file_type) {
918 case ECAT7_IMAGE8:
919 case ECAT7_IMAGE16:
920 case ECAT7_VOLUME8:
921 case ECAT7_VOLUME16:
922 ret=ecat7ReadImageheader(fp, mlist.matdir[m].strtblk, &image_header);
923 break;
924 case ECAT7_2DSCAN:
925 ret=ecat7Read2DScanheader(fp, mlist.matdir[m].strtblk, &scan2d_header);
926 break;
927 case ECAT7_3DSCAN:
928 case ECAT7_3DSCAN8:
929 case ECAT7_3DSCANFIT:
930 ret=ecat7ReadScanheader(fp, mlist.matdir[m].strtblk, &scan_header);
931 break;
932 case ECAT7_POLARMAP:
933 ret=ecat7ReadPolmapheader(fp, mlist.matdir[m].strtblk, &polmap_header);
934 break;
935 default: ret=-1;
936 }
937 /* Free locally allocated memory and close the file */
938 ecat7EmptyMatlist(&mlist); fclose(fp);
939 /* Check whether subheader was read */
940 if(ret) return STATUS_NOSUBHEADER;
941
942 /* Get the following information in the subheader:
943 dimensions x, y and z; datatype;
944 image decay correction on/off, zoom, pixel size and resolution;
945 sinogram sample distance; matrix transformation parameters.
946 */
947 switch(main_header.file_type) {
948 case ECAT7_IMAGE8:
949 case ECAT7_IMAGE16:
950 case ECAT7_VOLUME8:
951 case ECAT7_VOLUME16:
952 img->dimx=image_header.x_dimension; img->dimy=image_header.y_dimension;
953 if(image_header.num_dimensions>2 && image_header.z_dimension>1)
954 /*planeNr=*/ img->dimz=image_header.z_dimension;
955 img->_dataType=image_header.data_type;
956 if(image_header.decay_corr_fctr>1.0) img->decayCorrection=IMG_DC_CORRECTED;
957 img->zoom=image_header.recon_zoom;
958 img->sizex=10.*image_header.x_pixel_size;
959 img->sizey=10.*image_header.y_pixel_size;
960 img->sizez=10.*image_header.z_pixel_size;
961 img->resolutionx=10.*image_header.x_resolution;
962 img->resolutiony=10.*image_header.y_resolution;
963 img->resolutionz=10.*image_header.z_resolution;
966 img->quatern[6]=img->sizex; img->quatern[9]=img->sizex;
967 img->quatern[11]=img->sizey; img->quatern[13]=img->sizey;
968 img->quatern[16]=img->sizez; img->quatern[17]=img->sizez;
969 img->mt[0]=image_header.mt_1_1;
970 img->mt[1]=image_header.mt_1_2;
971 img->mt[2]=image_header.mt_1_3;
972 img->mt[3]=image_header.mt_1_4;
973 img->mt[4]=image_header.mt_2_1;
974 img->mt[5]=image_header.mt_2_2;
975 img->mt[6]=image_header.mt_2_3;
976 img->mt[7]=image_header.mt_2_4;
977 img->mt[8]=image_header.mt_3_1;
978 img->mt[9]=image_header.mt_3_2;
979 img->mt[10]=image_header.mt_3_3;
980 img->mt[11]=image_header.mt_3_4;
981 break;
982 case ECAT7_2DSCAN:
983 img->dimx=scan2d_header.num_r_elements;
984 img->dimy=scan2d_header.num_angles;
985 if(scan2d_header.num_dimensions>2 && scan2d_header.num_z_elements>1)
986 planeNr=img->dimz=scan2d_header.num_z_elements;
987 img->_dataType=scan2d_header.data_type;
988 if(scan2d_header.x_resolution>0.0)
989 img->sampleDistance=10.0*scan2d_header.x_resolution;
990 else
991 img->sampleDistance=10.0*main_header.bin_size;
992 break;
993 case ECAT7_3DSCAN:
994 case ECAT7_3DSCAN8:
995 case ECAT7_3DSCANFIT:
996 img->dimx=scan_header.num_r_elements; img->dimy=scan_header.num_angles;
997 for(int i=img->dimz=0; i<64; i++) img->dimz+=scan_header.num_z_elements[i];
998 /* planeNr=img->dimz; */
999 img->_dataType=scan_header.data_type;
1000 if(scan_header.x_resolution>0.0)
1001 img->sampleDistance=10.0*scan_header.x_resolution;
1002 else
1003 img->sampleDistance=10.0*main_header.bin_size;
1004 break;
1005 case ECAT7_POLARMAP:
1006 img->dimy=img->dimz=1;
1007 img->polarmap_num_rings=polmap_header.num_rings;
1009 return STATUS_INVALIDPOLARMAP;
1010 for(int i=0; i<img->polarmap_num_rings; i++) {
1011 img->polarmap_sectors_per_ring[i]=polmap_header.sectors_per_ring[i];
1012 img->polarmap_ring_position[i]=polmap_header.ring_position[i];
1013 img->polarmap_ring_angle[i]=polmap_header.ring_angle[i];
1014 }
1015 img->polarmap_start_angle=polmap_header.start_angle;
1016 img->dimx=0;
1017 for(int i=0; i<img->polarmap_num_rings; i++)
1018 img->dimx+=img->polarmap_sectors_per_ring[i];
1019 /* pixel_size actually contains volume, in cubic cm */
1020 img->sizex=img->sizey=img->sizez=0.001*polmap_header.pixel_size;
1021 break;
1022 }
1023
1024 imgSetStatus(img, STATUS_OK);
1025 return STATUS_OK;
1026}
1027/*****************************************************************************/
1028
1029/*****************************************************************************/
1037 if(h==NULL) return(0);
1038 if(h->file_type==ECAT7_VOLUME8) return(1);
1039 if(h->file_type==ECAT7_VOLUME16) return(1);
1040 if(h->file_type==ECAT7_IMAGE8) return(1);
1041 if(h->file_type==ECAT7_IMAGE16) return(1);
1042 if(h->file_type==ECAT7_2DSCAN) return(1);
1043 if(h->file_type==ECAT7_3DSCAN) return(1);
1044 if(h->file_type==ECAT7_3DSCAN8) return(1);
1045 if(h->file_type==ECAT7_3DSCANFIT) return(1);
1046 if(h->file_type==ECAT7_POLARMAP) return(1);
1047 return(0);
1048}
1049/*****************************************************************************/
1050
1051/*****************************************************************************/
1060int imgReadEcat7FirstFrame(const char *fname, IMG *img) {
1061 int ret=0;
1062
1063 if(IMG_TEST) printf("\nimgReadEcat7FirstFrame(%s, *img)\n", fname);
1064 /* Check the input */
1065 if(img==NULL) return STATUS_FAULT;
1066 if(img->status!=IMG_STATUS_INITIALIZED) return STATUS_FAULT;
1067 imgSetStatus(img, STATUS_FAULT);
1068 if(fname==NULL) return STATUS_FAULT;
1069
1070 /* Read header information from file */
1071 ret=imgReadEcat7Header(fname, img); if(ret) return(ret);
1072 if(IMG_TEST>3) imgInfo(img);
1073
1074 /* Allocate memory for one frame */
1075 img->dimt=1;
1076 ret=imgAllocate(img, img->dimz, img->dimy, img->dimx, img->dimt);
1077 if(ret) return STATUS_NOMEMORY;
1078
1079 /* Read the first frame */
1080 ret=imgReadEcat7Frame(fname, 1, img, 0); if(ret) return(ret);
1081
1082 /* All went well */
1083 imgSetStatus(img, STATUS_OK);
1084 return STATUS_OK;
1085}
1086/*****************************************************************************/
1087
1088/*****************************************************************************/
1104 const char *fname, int frame_to_read, IMG *img, int frame_index
1105) {
1106 FILE *fp;
1107 int ret, frame, plane, seqplane;
1108 /* int blkNr=0; */
1109 ECAT7_mainheader main_header;
1110 ECAT7_imageheader image_header;
1111 ECAT7_2Dscanheader scan2d_header;
1112 ECAT7_scanheader scan_header;
1113 ECAT7_polmapheader polmap_header;
1114 ECAT7_MATRIXLIST mlist;
1115 ECAT7_Matval matval;
1116 float *fdata=NULL, *fptr;
1117
1118
1119 if(IMG_TEST) printf("\nimgReadEcat7Frame(%s, %d, *img, %d)\n",
1120 fname, frame_to_read, frame_index);
1121
1122 /* Check the input */
1123 if(img==NULL) return STATUS_FAULT;
1124 if(img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
1125 if(fname==NULL) return STATUS_FAULT;
1126 if(frame_index<0 || frame_index>img->dimt-1) return STATUS_FAULT;
1127 if(frame_to_read<1) return STATUS_FAULT;
1128
1129 /* Open file for read */
1130 if((fp=fopen(fname, "rb")) == NULL) return STATUS_NOFILE;
1131
1132 /* Read main header */
1133 ret=ecat7ReadMainheader(fp, &main_header);
1134 if(ret) {fclose(fp); return STATUS_NOMAINHEADER;}
1135 /* Check for magic number */
1136 if(strncmp(main_header.magic_number, ECAT7V_MAGICNR, 7)!=0) {
1137 fclose(fp); return STATUS_UNKNOWNFORMAT;}
1138 /* Check if file_type is supported */
1139 if(imgEcat7Supported(&main_header)==0) {
1140 fclose(fp); return STATUS_UNSUPPORTED;}
1141 /* Read matrix list and nr and sort it */
1142 ecat7InitMatlist(&mlist);
1143 ret=ecat7ReadMatlist(fp, &mlist, IMG_TEST-1);
1144 if(ret) {fclose(fp); return STATUS_NOMATLIST;}
1145 if(mlist.matrixNr<=0 || ecat7CheckMatlist(&mlist)) {
1146 fclose(fp); ecat7EmptyMatlist(&mlist); return STATUS_INVALIDMATLIST;}
1147 /* Make sure that plane and frame numbers are continuous */
1148 ecat7GatherMatlist(&mlist, 1, 1, 1, 1);
1149 ecat7SortMatlistByFrame(&mlist); /* printf("matlist sorted\n"); */
1150 /* Calculate and check the size of one data matrix */
1151 /*ret=ecat7GetMatrixBlockSize(&mlist, &blkNr);
1152 if(ret) {fclose(fp); return ret;}*/
1153
1154 /* Read all matrices that belong to the required frame */
1155 /*blkNr=-1;*/
1156 ret=0; seqplane=-1;
1157 long long pxlNr=img->dimx*img->dimy;
1158 for(int m=0; m<mlist.matrixNr; m++) {
1159 /* get frame and plane */
1160 ecat7_id_to_val(mlist.matdir[m].id, &matval); plane=matval.plane;
1161 if(main_header.num_frames>=main_header.num_gates) frame=matval.frame;
1162 else frame=matval.gate; /* printf("frame=%d plane=%d\n", frame, plane); */
1163 if(frame!=frame_to_read) continue; /* do not process other frames */
1164 /*if(img->dimz>1) seqplane++; else seqplane=plane-1; */
1165 if(img->_fileFormat==IMG_E7_2D) seqplane=plane-1; else seqplane++;
1166
1167 /* Read subheader and data */
1168 if(IMG_TEST>4) printf("reading matrix %d,%d\n", frame, plane);
1169 if(img->type==IMG_TYPE_IMAGE) { /* 2D or 3D image */
1170 ret=ecat7ReadImageMatrix(fp, mlist.matdir[m].strtblk,
1171 mlist.matdir[m].endblk, &image_header, &fdata);
1172 } else if(img->type==IMG_TYPE_POLARMAP) { /* polarmap */
1173 ret=ecat7ReadPolarmapMatrix(fp, mlist.matdir[m].strtblk,
1174 mlist.matdir[m].endblk, &polmap_header, &fdata);
1175 } else if(img->dimz>1) { /* 3D sinogram */
1176 ret=ecat7ReadScanMatrix(fp, mlist.matdir[m].strtblk,
1177 mlist.matdir[m].endblk, &scan_header, &fdata);
1178 } else { /* 2D sinogram */
1179 ret=ecat7Read2DScanMatrix(fp, mlist.matdir[m].strtblk,
1180 mlist.matdir[m].endblk, &scan2d_header, &fdata);
1181 }
1182 if(ret || fdata==NULL) {
1183 fclose(fp); ecat7EmptyMatlist(&mlist); return STATUS_NOMATRIX;}
1184
1185 /* Copy information concerning this frame and make correction to data */
1186 if(img->type==IMG_TYPE_IMAGE) {
1187 img->start[frame_index]=image_header.frame_start_time/1000.;
1188 img->end[frame_index]=
1189 img->start[frame_index]+image_header.frame_duration/1000.;
1190 img->mid[frame_index]=0.5*(img->start[frame_index]+img->end[frame_index]);
1191 if(image_header.decay_corr_fctr>1.0) {
1192 img->decayCorrFactor[frame_index]=image_header.decay_corr_fctr;
1194 } else {
1195 img->decayCorrFactor[frame_index]=0.0;
1197 }
1198 } else if(img->type==IMG_TYPE_POLARMAP) { /* polarmap */
1199 img->start[frame_index]=polmap_header.frame_start_time/1000.;
1200 img->end[frame_index]=
1201 img->start[frame_index]+polmap_header.frame_duration/1000.;
1202 img->mid[frame_index]=0.5*(img->start[frame_index]+img->end[frame_index]);
1203 } else if(img->dimz>1) {
1204 img->start[frame_index]=scan_header.frame_start_time/1000.;
1205 img->end[frame_index]=
1206 img->start[frame_index]+scan_header.frame_duration/1000.;
1207 img->mid[frame_index]=0.5*(img->start[frame_index]+img->end[frame_index]);
1208 /* also, correct for dead-time */
1209 if(scan_header.deadtime_correction_factor>0.0) {
1210 fptr=fdata;
1211 for(long long i=0; i<img->dimz*pxlNr; i++, fptr++)
1212 *fptr*=scan_header.deadtime_correction_factor;
1213 }
1214 img->prompts[frame_index]=(float)scan_header.prompts;
1215 img->randoms[frame_index]=scan_header.delayed;
1216 } else {
1217 img->start[frame_index]=scan2d_header.frame_start_time/1000.;
1218 img->end[frame_index]=
1219 img->start[frame_index]+scan2d_header.frame_duration/1000.;
1220 img->mid[frame_index]=0.5*(img->start[frame_index]+img->end[frame_index]);
1221 /* also, correct for dead-time */
1222 if(scan2d_header.deadtime_correction_factor>0.0) {
1223 fptr=fdata;
1224 for(long long i=0; i<pxlNr; i++, fptr++)
1225 *fptr*=scan2d_header.deadtime_correction_factor;
1226 }
1227 img->prompts[frame_index]=(float)scan2d_header.prompts;
1228 img->randoms[frame_index]=scan2d_header.delayed;
1229 }
1230 /* Copy matrix data through volume planes */
1231 if(img->_fileFormat!=IMG_E7_2D) {
1232 /* if(img->dimz>1) { */
1233 for(int pi=0; pi<img->dimz; pi++) {
1234 if(IMG_TEST>5)
1235 printf(" putting data into m[%d][][][%d]\n", pi, frame_index);
1236 fptr=fdata+pi*pxlNr;
1237 for(int yi=0; yi<img->dimy; yi++)
1238 for(int xi=0; xi<img->dimx; xi++)
1239 img->m[pi][yi][xi][frame_index]= *fptr++;
1240 }
1241 } else {
1242 if(IMG_TEST>5)
1243 printf(" putting data into m[%d][][][%d]\n", seqplane, frame_index);
1244 fptr=fdata;
1245 for(int yi=0; yi<img->dimy; yi++)
1246 for(int xi=0; xi<img->dimx; xi++)
1247 img->m[seqplane][yi][xi][frame_index]= *fptr++;
1248 img->planeNumber[seqplane]=plane;
1249 }
1250 free(fdata);
1251 /* Calibrate */
1252 if(main_header.ecat_calibration_factor>0.0)
1253 for(int pi=0; pi<img->dimz; pi++)
1254 for(int yi=0; yi<img->dimy; yi++) for(int xi=0; xi<img->dimx; xi++)
1255 img->m[pi][yi][xi][frame_index]*=main_header.ecat_calibration_factor;
1256 } /* next matrix */
1257 if(IMG_TEST>3) printf("end of matrices.\n");
1258 ecat7EmptyMatlist(&mlist);
1259 fclose(fp);
1260
1261 /* seqplane is <0 only if this frame did not exist at all; return -1 */
1262 if(IMG_TEST>4) printf("last_seqplane := %d.\n", seqplane);
1263 if(seqplane<0) return STATUS_NOMATRIX;
1264
1265 /* check that correct number of planes was read */
1266 if(seqplane>0 && (seqplane+1 != img->dimz)) return STATUS_MISSINGMATRIX;
1267
1268 /* All went well */
1269 imgSetStatus(img, STATUS_OK);
1270 return STATUS_OK;
1271}
1272/*****************************************************************************/
1273
1274/*****************************************************************************/
1296 const char *fname, int frame_to_write, IMG *img, int frame_index
1297) {
1298 IMG test_img;
1299 int ret=0, matrixId;
1300 ECAT7_mainheader main_header;
1301 ECAT7_imageheader image_header;
1302 ECAT7_scanheader scan_header;
1303 ECAT7_2Dscanheader scan2d_header;
1304 ECAT7_polmapheader polmap_header;
1305 void *sub_header=NULL;
1306 FILE *fp;
1307 float *fdata=NULL, *fptr;
1308
1309
1310 if(IMG_TEST) printf("\nimgWriteEcat7Frame(%s, %d, *img, %d)\n",
1311 fname, frame_to_write, frame_index);
1312
1313 /*
1314 * Check the input
1315 */
1316 if(fname==NULL) return STATUS_FAULT;
1317 if(img==NULL) return STATUS_FAULT;
1318 if(img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
1319 if(frame_to_write<0) return STATUS_FAULT;
1320 if(frame_index<0 || frame_index>=img->dimt) return STATUS_FAULT;
1321 if(img->_fileFormat!=IMG_E7 &&
1322 img->_fileFormat!=IMG_POLARMAP &&
1323 img->_fileFormat!=IMG_E7_2D) return STATUS_FAULT;
1324
1325 /* Check image size */
1326 if(img->dimt>511 || img->dimz>255 || img->dimx>1024 || img->dimy>1024)
1327 return STATUS_INVALIDHEADER;
1328
1329 /* Initiate headers */
1330 memset(&main_header, 0, sizeof(ECAT7_mainheader));
1331 memset(&image_header,0, sizeof(ECAT7_imageheader));
1332 memset(&scan_header, 0, sizeof(ECAT7_scanheader));
1333 memset(&scan2d_header, 0, sizeof(ECAT7_2Dscanheader));
1334 memset(&polmap_header,0, sizeof(ECAT7_polmapheader));
1335 imgInit(&test_img);
1336
1337
1338 /*
1339 * If file does not exist, then create it with new mainheader,
1340 * and if it does exist, then read and check header information.
1341 * Create or edit mainheader to contain correct frame nr.
1342 * In any case, leave file pointer open for write.
1343 */
1344 if(access(fname, 0) == -1) { /* file does not exist */
1345
1346 /* Set main header */
1347 imgSetEcat7MHeader(img, &main_header);
1348 main_header.bin_size=img->sampleDistance/10.0;
1349 if(frame_to_write==0) frame_to_write=1;
1350 main_header.num_frames=frame_to_write;
1351
1352 /* Open file, write main header and initiate matrix list */
1353 fp=ecat7Create(fname, &main_header); if(fp==NULL) return STATUS_NOWRITEPERM;
1354
1355 } else { /* file exists */
1356
1357 /* Read header information for checking */
1358 ret=imgReadEcat7Header(fname, &test_img); if(ret!=0) return ret;
1359 /* Check that file format is the same */
1360 if(img->_fileFormat!=test_img._fileFormat || img->type!=test_img.type)
1361 return STATUS_WRONGFILETYPE;
1362 /* Check that matrix sizes are the same */
1363 if(img->dimz!=test_img.dimz || img->dimx!=test_img.dimx ||
1364 img->dimy!=test_img.dimy)
1365 return STATUS_VARMATSIZE;
1366 imgEmpty(&test_img);
1367
1368 /* Open the file for read and write */
1369 if((fp=fopen(fname, "r+b"))==NULL) return STATUS_NOWRITEPERM;
1370
1371 /* Read the mainheader, set new frame number, and write it back */
1372 if((ret=ecat7ReadMainheader(fp, &main_header))!=0)
1373 return STATUS_NOMAINHEADER;
1374 if(frame_to_write==0) frame_to_write=main_header.num_frames+1;
1375 if(main_header.num_frames<frame_to_write)
1376 main_header.num_frames=frame_to_write;
1377 if((ret=ecat7WriteMainheader(fp, &main_header))!=0)
1378 return STATUS_NOWRITEPERM;
1379
1380 }
1381 if(IMG_TEST>2) {
1382 printf("frame_to_write := %d\n", frame_to_write);
1383 }
1384
1385 /* Allocate memory for matrix float data */
1386 long long pxlNr=img->dimx*img->dimy*img->dimz; /* for 2D too! */
1387 fdata=(float*)malloc(pxlNr*sizeof(float));
1388 if(fdata==NULL) {fclose(fp); return STATUS_NOMEMORY;}
1389
1390 /* Set matrix subheader */
1391 if(img->_fileFormat==IMG_E7) {
1392 if(img->type==IMG_TYPE_RAW) sub_header=(void*)&scan_header;
1393 else sub_header=&image_header;
1394 } else if(img->_fileFormat==IMG_E7_2D) {
1395 if(img->type==IMG_TYPE_RAW) sub_header=(void*)&scan_header;
1396 else sub_header=(void*)&image_header;
1397 } else if(img->_fileFormat==IMG_POLARMAP) {
1398 sub_header=(void*)&polmap_header;
1399 } else {fclose(fp); return STATUS_FAULT;}
1400 imgSetEcat7SHeader(img, sub_header);
1401
1402 /* Copy matrix pixel values to fdata */
1403 fptr=fdata;
1404 for(int zi=0; zi<img->dimz; zi++)
1405 for(int yi=0; yi<img->dimy; yi++)
1406 for(int xi=0; xi<img->dimx; xi++)
1407 if(isfinite(img->m[zi][yi][xi][frame_index])) *fptr++=img->m[zi][yi][xi][frame_index]; else *fptr++=0.0;
1408
1409 /* Write subheader and data, and set the rest of subheader contents */
1410 fptr=fdata; ret=-1;
1411 if(img->_fileFormat==IMG_E7) {
1412 /* Create new matrix id (i.e. matnum) */
1413 matrixId=ecat7_val_to_id(frame_to_write, 1, 1, 0, 0);
1414 if(img->type==IMG_TYPE_RAW) {
1415 scan_header.frame_start_time=
1416 (int)temp_roundf(1000.*img->start[frame_index]);
1417 scan_header.frame_duration=
1418 (int)temp_roundf(1000.*(img->end[frame_index]-img->start[frame_index]));
1419 scan_header.prompts=temp_roundf(img->prompts[frame_index]);
1420 scan_header.delayed=temp_roundf(img->randoms[frame_index]);
1421 ret=ecat7WriteScanMatrix(fp, matrixId, &scan_header, fptr);
1422 } else {
1423 image_header.frame_start_time=
1424 (int)temp_roundf(1000.*img->start[frame_index]);
1425 image_header.frame_duration=
1426 (int)temp_roundf(1000.*(img->end[frame_index]-img->start[frame_index]));
1428 image_header.decay_corr_fctr=img->decayCorrFactor[frame_index];
1429 else
1430 image_header.decay_corr_fctr=0.0;
1431 /*ecat7PrintImageheader(&image_header, stdout);*/
1432 ret=ecat7WriteImageMatrix(fp, matrixId, &image_header, fptr);
1433 }
1434 } else if(img->_fileFormat==IMG_E7_2D) {
1435 for(int zi=0; zi<img->dimz; zi++, fptr+=img->dimx*img->dimy) {
1436 /* Create new matrix id (i.e. matnum) */
1437 matrixId=ecat7_val_to_id(frame_to_write, img->planeNumber[zi], 1, 0, 0);
1438 if(img->type==IMG_TYPE_RAW) {
1439 scan2d_header.frame_start_time=
1440 (int)temp_roundf(1000.*img->start[frame_index]);
1441 scan2d_header.frame_duration=
1442 (int)temp_roundf(1000.*(img->end[frame_index]-img->start[frame_index]));
1443 scan2d_header.prompts=temp_roundf(img->prompts[frame_index]);
1444 scan2d_header.delayed=temp_roundf(img->randoms[frame_index]);
1445 ret=ecat7Write2DScanMatrix(fp, matrixId, &scan2d_header, fptr);
1446 } else {
1447 image_header.frame_start_time=
1448 (int)temp_roundf(1000.*img->start[frame_index]);
1449 image_header.frame_duration=
1450 (int)temp_roundf(1000.*(img->end[frame_index]-img->start[frame_index]));
1452 image_header.decay_corr_fctr=img->decayCorrFactor[frame_index];
1453 else
1454 image_header.decay_corr_fctr=0.0;
1455 ret=ecat7WriteImageMatrix(fp, matrixId, &image_header, fptr);
1456 }
1457 if(ret!=0) break;
1458 } /* next plane */
1459 } else if(img->_fileFormat==IMG_POLARMAP) {
1460 /* Create new matrix id (i.e. matnum) */
1461 matrixId=ecat7_val_to_id(frame_to_write, 1, 1, 0, 0);
1462 polmap_header.frame_start_time=
1463 (int)temp_roundf(1000.*img->start[frame_index]);
1464 polmap_header.frame_duration=
1465 (int)temp_roundf(1000.*(img->end[frame_index]-img->start[frame_index]));
1466 ret=ecat7WritePolarmapMatrix(fp, matrixId, &polmap_header, fptr);
1467 }
1468 free(fdata); fclose(fp);
1469 if(ret) return STATUS_DISKFULL;
1470
1471 return STATUS_OK;
1472}
1473/*****************************************************************************/
1474
1475/*****************************************************************************/
1482void imgSetEcat7SHeader(IMG *img, void *h) {
1483 ECAT7_imageheader *image_header;
1484 ECAT7_scanheader *scan_header;
1485 ECAT7_2Dscanheader *scan2d_header;
1486 ECAT7_polmapheader *polmap_header;
1487
1488 if(img->type==IMG_TYPE_POLARMAP) {
1489 polmap_header=(ECAT7_polmapheader*)h;
1490 polmap_header->data_type=ECAT7_SUNI2;
1491 polmap_header->num_rings=img->polarmap_num_rings;
1492 if(polmap_header->num_rings>32) polmap_header->num_rings=32;
1493 for(int i=0; i<polmap_header->num_rings; i++) {
1494 polmap_header->sectors_per_ring[i]=img->polarmap_sectors_per_ring[i];
1495 polmap_header->ring_position[i]=img->polarmap_ring_position[i];
1496 polmap_header->ring_angle[i]=img->polarmap_ring_angle[i];
1497 }
1498 polmap_header->start_angle=258;
1499 polmap_header->pixel_size=1000.0*img->sizex;
1500 polmap_header->quant_units=0; /* default, see main header */
1501 } else if(img->type==IMG_TYPE_RAW) {
1502 if(img->_fileFormat==IMG_E7_2D) {
1503 scan2d_header=(ECAT7_2Dscanheader*)h;
1504 scan2d_header->num_dimensions=2;
1505 scan2d_header->num_z_elements=1;
1506 scan2d_header->data_type=ECAT7_SUNI2;
1507 scan2d_header->num_r_elements=img->dimx;
1508 scan2d_header->num_angles=img->dimy;
1509 } else {
1510 scan_header=(ECAT7_scanheader*)h;
1511 scan_header->x_resolution=img->sampleDistance/10.0;
1512 scan_header->num_dimensions=4;
1513 if(img->dimz==239) {
1514 scan_header->num_z_elements[0]=63;
1515 scan_header->num_z_elements[1]=106;
1516 scan_header->num_z_elements[2]=70;
1517 } else {
1518 scan_header->num_z_elements[0]=img->dimz;
1519 }
1520 scan_header->storage_order=1;
1521 scan_header->data_type=ECAT7_SUNI2;
1522 scan_header->num_r_elements=img->dimx;
1523 scan_header->num_angles=img->dimy;
1524 }
1525 } else {
1526 image_header=(ECAT7_imageheader*)h;
1527 image_header->data_type=ECAT7_SUNI2;
1528 image_header->x_dimension=img->dimx;
1529 image_header->y_dimension=img->dimy;
1530 image_header->recon_zoom=img->zoom;
1531 image_header->x_pixel_size=0.1*img->sizex;
1532 image_header->y_pixel_size=0.1*img->sizey;
1533 image_header->z_pixel_size=0.1*img->sizez;
1534 image_header->x_resolution=0.1*img->resolutionx;
1535 image_header->y_resolution=0.1*img->resolutiony;
1536 image_header->z_resolution=0.1*img->resolutionz;
1537 image_header->mt_1_1=img->mt[0];
1538 image_header->mt_1_2=img->mt[1];
1539 image_header->mt_1_3=img->mt[2];
1540 image_header->mt_1_4=img->mt[3];
1541 image_header->mt_2_1=img->mt[4];
1542 image_header->mt_2_2=img->mt[5];
1543 image_header->mt_2_3=img->mt[6];
1544 image_header->mt_2_4=img->mt[7];
1545 image_header->mt_3_1=img->mt[8];
1546 image_header->mt_3_2=img->mt[9];
1547 image_header->mt_3_3=img->mt[10];
1548 image_header->mt_3_4=img->mt[11];
1549 if(img->_fileFormat==IMG_E7_2D) {
1550 image_header->num_dimensions=2;
1551 image_header->z_dimension=1;
1552 } else {
1553 image_header->num_dimensions=3;
1554 image_header->z_dimension=img->dimz;
1555 }
1556 for(int i=0; i<49; i++) image_header->fill_user[i]=0;
1557 }
1558}
1559/*****************************************************************************/
1560
1561/*****************************************************************************/
char ecat7errmsg[128]
Definition ecat7h.c:7
int ECAT7_TEST
Definition ecat7h.c:6
void ecat7InitMatlist(ECAT7_MATRIXLIST *mlist)
Definition ecat7ml.c:15
void ecat7SortMatlistByFrame(ECAT7_MATRIXLIST *ml)
Definition ecat7ml.c:303
int ecat7GetPlaneAndFrameNr(ECAT7_MATRIXLIST *mlist, ECAT7_mainheader *h, int *plane_nr, int *frame_nr)
Definition ecat7ml.c:372
int ecat7GetMatrixBlockSize(ECAT7_MATRIXLIST *mlist, int *blk_nr)
Definition ecat7ml.c:418
void ecat7SortMatlistByPlane(ECAT7_MATRIXLIST *ml)
Definition ecat7ml.c:277
void ecat7_id_to_val(int matrix_id, ECAT7_Matval *matval)
Definition ecat7ml.c:262
int ecat7ReadMatlist(FILE *fp, ECAT7_MATRIXLIST *ml, int verbose)
Definition ecat7ml.c:41
void ecat7EmptyMatlist(ECAT7_MATRIXLIST *mlist)
Definition ecat7ml.c:26
int ecat7_val_to_id(int frame, int plane, int gate, int data, int bed)
Definition ecat7ml.c:245
int ecat7GatherMatlist(ECAT7_MATRIXLIST *ml, short int do_planes, short int do_frames, short int do_gates, short int do_beds)
Definition ecat7ml.c:535
void ecat7PrintMatlist(ECAT7_MATRIXLIST *ml)
Definition ecat7ml.c:112
int ecat7CheckMatlist(ECAT7_MATRIXLIST *ml)
Definition ecat7ml.c:329
int ecat7Read2DScanMatrix(FILE *fp, int first_block, int last_block, ECAT7_2Dscanheader *h, float **fdata)
Definition ecat7r.c:959
int ecat7ReadScanheader(FILE *fp, int blk, ECAT7_scanheader *h)
Definition ecat7r.c:536
int ecat7ReadPolmapheader(FILE *fp, int blk, ECAT7_polmapheader *h)
Definition ecat7r.c:397
int ecat7ReadMainheader(FILE *fp, ECAT7_mainheader *h)
Definition ecat7r.c:15
int ecat7ReadPolarmapMatrix(FILE *fp, int first_block, int last_block, ECAT7_polmapheader *h, float **fdata)
Definition ecat7r.c:1154
int ecat7Read2DScanheader(FILE *fp, int blk, ECAT7_2Dscanheader *h)
Definition ecat7r.c:631
int ecat7ReadImageMatrix(FILE *fp, int first_block, int last_block, ECAT7_imageheader *h, float **fdata)
Definition ecat7r.c:858
int ecat7ReadImageheader(FILE *fp, int blk, ECAT7_imageheader *h)
Definition ecat7r.c:162
int ecat7ReadScanMatrix(FILE *fp, int first_block, int last_block, ECAT7_scanheader *h, float **fdata)
Definition ecat7r.c:1055
int ecat7WriteImageMatrix(FILE *fp, int matrix_id, ECAT7_imageheader *h, float *fdata)
Definition ecat7w.c:635
int ecat7WriteScanMatrix(FILE *fp, int matrix_id, ECAT7_scanheader *h, float *fdata)
Definition ecat7w.c:802
int ecat7WritePolarmapMatrix(FILE *fp, int matrix_id, ECAT7_polmapheader *h, float *fdata)
Definition ecat7w.c:888
int ecat7Write2DScanMatrix(FILE *fp, int matrix_id, ECAT7_2Dscanheader *h, float *fdata)
Definition ecat7w.c:719
FILE * ecat7Create(const char *fname, ECAT7_mainheader *h)
Definition ecat7w.c:567
int ecat7WriteMainheader(FILE *fp, ECAT7_mainheader *h)
Definition ecat7w.c:16
int IMG_TEST
Definition img.c:6
void imgInfo(IMG *image)
Definition img.c:359
int imgAllocate(IMG *image, int planes, int rows, int columns, int frames)
Definition img.c:194
void imgSetStatus(IMG *img, int status_index)
Definition img.c:345
void imgEmpty(IMG *image)
Definition img.c:121
void imgInit(IMG *image)
Definition img.c:60
int imgWrite2DEcat7(const char *fname, IMG *img)
Definition img_e7.c:526
void imgGetEcat7MHeader(IMG *img, ECAT7_mainheader *h)
Definition img_e7.c:742
int imgWriteEcat7(const char *fname, IMG *img)
Definition img_e7.c:382
int imgReadEcat7Frame(const char *fname, int frame_to_read, IMG *img, int frame_index)
Definition img_e7.c:1103
int imgEcat7Supported(ECAT7_mainheader *h)
Definition img_e7.c:1036
int imgReadEcat7FirstFrame(const char *fname, IMG *img)
Definition img_e7.c:1060
int imgReadEcat7(const char *fname, IMG *img)
Definition img_e7.c:19
int imgReadEcat7Header(const char *fname, IMG *img)
Definition img_e7.c:860
int imgGetEcat7Fileformat(ECAT7_mainheader *h)
Definition img_e7.c:827
int imgWriteEcat7Frame(const char *fname, int frame_to_write, IMG *img, int frame_index)
Definition img_e7.c:1295
int imgWritePolarmap(const char *fname, IMG *img)
Definition img_e7.c:661
void imgSetEcat7MHeader(IMG *img, ECAT7_mainheader *h)
Definition img_e7.c:781
void imgSetEcat7SHeader(IMG *img, void *h)
Definition img_e7.c:1482
char * imgIsotope(IMG *img)
Definition imgdecayc.c:76
void imgUnitToEcat7(IMG *img, ECAT7_mainheader *h)
Definition imgunits.c:209
void imgUnitFromEcat7(IMG *img, ECAT7_mainheader *h)
Definition imgunits.c:149
Header file for libtpcimgio.
#define IMG_TYPE_RAW
#define NIFTI_XFORM_UNKNOWN
#define ECAT7_VOLUME8
#define IMG_E7
#define IMG_STATUS_OCCUPIED
#define IMG_UNKNOWN
#define IMG_E7_2D
#define ECAT7_3DSCAN
#define IMG_DC_UNKNOWN
#define ECAT7_3DSCAN8
#define IMG_DC_CORRECTED
#define IMG_TYPE_POLARMAP
#define ECAT7_IMAGE16
#define ECAT7_3DSCANFIT
#define ECAT7_VOLUME16
#define IMG_STATUS_INITIALIZED
#define ECAT7_IMAGE8
#define IMG_POLARMAP
#define NIFTI_XFORM_SCANNER_ANAT
#define MAX_POLARMAP_NUM_RINGS
#define ECAT7_POLARMAP
#define IMG_TYPE_IMAGE
#define ECAT7_SUNI2
#define ECAT7_2DSCAN
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition strext.c:245
#define MAX_STUDYNR_LEN
Definition libtpcmisc.h:163
int studynr_validity_check(char *studynr)
Definition studynr.c:196
int temp_roundf(float e)
Definition petc99.c:20
float deadtime_correction_factor
short int num_z_elements
short int num_r_elements
short int num_dimensions
ECAT7_MatDir * matdir
short int fill_user[49]
short int y_dimension
short int z_dimension
short int num_dimensions
short int x_dimension
short int data_type
short int file_type
short int system_type
short int num_frames
char magic_number[14]
char study_type[12]
char user_process_code[10]
char patient_name[32]
short int num_gates
short int num_planes
short int num_bed_pos
float ecat_calibration_factor
short int sw_version
char study_description[32]
char patient_id[16]
char radiopharmaceutical[32]
short int patient_orientation
short int ring_angle[32]
short int sectors_per_ring[32]
short int start_angle
float ring_position[32]
short int quant_units
short int num_r_elements
short int num_angles
short int data_type
float deadtime_correction_factor
short int num_dimensions
short int storage_order
short int num_z_elements[64]
float sizex
int polarmap_num_rings
unsigned short int dimx
float branchingFraction
char type
float resolutionx
char patientName[32]
float resolutiony
char studyDescription[32]
float sampleDistance
short int polarmap_start_angle
float **** m
char decayCorrection
float transaxialFOV
short int xform[2]
char status
time_t scanStart
int _fileFormat
float * prompts
char userProcessCode[11]
unsigned short int dimt
int _dataType
int * planeNumber
char patientID[16]
int scanner
float sizey
float * start
unsigned short int dimz
int polarmap_sectors_per_ring[MAX_POLARMAP_NUM_RINGS]
unsigned short int dimy
int orientation
float * end
float mt[12]
float quatern[18]
float zoom
char radiopharmaceutical[32]
float * decayCorrFactor
float isotopeHalflife
short int polarmap_ring_angle[MAX_POLARMAP_NUM_RINGS]
char studyNr[MAX_STUDYNR_LEN+1]
float * randoms
float axialFOV
float * mid
float polarmap_ring_position[MAX_POLARMAP_NUM_RINGS]
float sizez
float resolutionz