ecat7w.c
Go to the documentation of this file.
1 /******************************************************************************
2 
3  Copyright (c) 2003-2008 Turku PET Centre
4 
5  Library file: ecat7w.c
6  Description: Functions for writing ECAT 7.x format.
7 
8  This program is free software; you can redistribute it and/or modify it under
9  the terms of the GNU General Public License as published by the Free Software
10  Foundation; either version 2 of the License, or (at your option) any later
11  version.
12 
13  This program is distributed in the hope that it will be useful, but WITHOUT
14  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License along with
18  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19  Place, Suite 330, Boston, MA 02111-1307 USA.
20 
21  Turku PET Centre hereby disclaims all copyright interest in the program.
22  Juhani Knuuti
23  Director, Professor
24  Turku PET Centre, Turku, Finland, http://www.turkupetcentre.fi/
25 
26  Modification history:
27  2003-07-24 Vesa Oikonen
28  First created.
29  2003-09-04 VO
30  Added support for 3D sinograms, ecat7WriteScanMatrix().
31  Removed functions ecat7wFloat() and ecat7wInt().
32  2003-11-30 VO
33  For now, calls temp_roundf() instead of roundf().
34  2004-01-07 VO
35  ecat7WriteImageMatrix(): corrected img min&max in header.
36  2004-09-17 VO
37  Changes in comment style.
38  Removed code that was previously commented out.
39  2004-12-28 VO
40  Included function ecat7_is_scaling_needed().
41  This function is applied to determine whether scal factor can be set to
42  one in case that all pixel values are close to integers and small enough.
43  2007-01-27 VO
44  Unsigned char pointer was corrected to signed in ecat7WriteMatrixdata().
45  2007-03-27 VO
46  Added ecat7WritePolarmapMatrix().
47  2007-09-02 VO
48  Backup file extension changed from % to .bak.
49 
50 ******************************************************************************/
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <math.h>
54 #include <string.h>
55 #include <unistd.h>
56 #include <time.h>
57 /*****************************************************************************/
58 #include "swap.h"
59 #include "petc99.h"
60 #include "include/ecat7.h"
61 /*****************************************************************************/
62 
63 /*****************************************************************************/
74  unsigned char buf[MatBLKSIZE];
75  int little;
76 
77  if(ECAT7_TEST) printf("ecat7WriteMainheader()\n");
78  /* Check arguments */
79  if(fp==NULL || h==NULL) return(1);
80  little=little_endian();
81  /* Clear buf */
82  memset(buf, 0, MatBLKSIZE);
83 
84  /* Copy header contents into buffer and change byte order if necessary */
85  memcpy(buf+0, &h->magic_number, 14);
86  memcpy(buf+14, &h->original_file_name, 32);
87  memcpy(buf+46, &h->sw_version, 2); if(little) swabip(buf+46, 2);
88  memcpy(buf+48, &h->system_type, 2); if(little) swabip(buf+48, 2);
89  memcpy(buf+50, &h->file_type, 2); if(little) swabip(buf+50, 2);
90  memcpy(buf+52, &h->serial_number, 10);
91  memcpy(buf+62, &h->scan_start_time, 4); if(little) swawbip(buf+62, 4);
92  memcpy(buf+66, &h->isotope_name, 8);
93  memcpy(buf+74, &h->isotope_halflife, 4); if(little) swawbip(buf+74, 4);
94  memcpy(buf+78, &h->radiopharmaceutical, 32);
95  memcpy(buf+110, &h->gantry_tilt, 4); if(little) swawbip(buf+110, 4);
96  memcpy(buf+114, &h->gantry_rotation, 4); if(little) swawbip(buf+114, 4);
97  memcpy(buf+118, &h->bed_elevation, 4); if(little) swawbip(buf+118, 4);
98  memcpy(buf+122, &h->intrinsic_tilt, 4); if(little) swawbip(buf+122, 4);
99  memcpy(buf+126, &h->wobble_speed, 2); if(little) swabip(buf+126, 2);
100  memcpy(buf+128, &h->transm_source_type, 2); if(little) swabip(buf+128, 2);
101  memcpy(buf+130, &h->distance_scanned, 4); if(little) swawbip(buf+130, 4);
102  memcpy(buf+134, &h->transaxial_fov, 4); if(little) swawbip(buf+134, 4);
103  memcpy(buf+138, &h->angular_compression, 2); if(little) swabip(buf+138, 2);
104  memcpy(buf+140, &h->coin_samp_mode, 2); if(little) swabip(buf+140, 2);
105  memcpy(buf+142, &h->axial_samp_mode, 2); if(little) swabip(buf+142, 2);
106  memcpy(buf+144, &h->ecat_calibration_factor, 4); if(little) swawbip(buf+144, 4);
107  memcpy(buf+148, &h->calibration_units, 2); if(little) swabip(buf+148, 2);
108  memcpy(buf+150, &h->calibration_units_label, 2); if(little) swabip(buf+150, 2);
109  memcpy(buf+152, &h->compression_code, 2); if(little) swabip(buf+152, 2);
110  memcpy(buf+154, &h->study_type, 12);
111  memcpy(buf+166, &h->patient_id, 16);
112  memcpy(buf+182, &h->patient_name, 32);
113  memcpy(buf+214, &h->patient_sex, 1);
114  memcpy(buf+215, &h->patient_dexterity, 1);
115  memcpy(buf+216, &h->patient_age, 4); if(little) swawbip(buf+216, 4);
116  memcpy(buf+220, &h->patient_height, 4); if(little) swawbip(buf+220, 4);
117  memcpy(buf+224, &h->patient_weight, 4); if(little) swawbip(buf+224, 4);
118  memcpy(buf+228, &h->patient_birth_date, 4); if(little) swawbip(buf+228, 4);
119  memcpy(buf+232, &h->physician_name, 32);
120  memcpy(buf+264, &h->operator_name, 32);
121  memcpy(buf+296, &h->study_description, 32);
122  memcpy(buf+328, &h->acquisition_type, 2); if(little) swabip(buf+328, 2);
123  memcpy(buf+330, &h->patient_orientation, 2); if(little) swabip(buf+330, 2);
124  memcpy(buf+332, &h->facility_name, 20);
125  memcpy(buf+352, &h->num_planes, 2); if(little) swabip(buf+352, 2);
126  memcpy(buf+354, &h->num_frames, 2); if(little) swabip(buf+354, 2);
127  memcpy(buf+356, &h->num_gates, 2); if(little) swabip(buf+356, 2);
128  memcpy(buf+358, &h->num_bed_pos, 2); if(little) swabip(buf+358, 2);
129  memcpy(buf+360, &h->init_bed_position, 4); if(little) swawbip(buf+360, 4);
130  memcpy(buf+364, h->bed_position, 15*4); if(little) swawbip(buf+364, 15*4);
131  memcpy(buf+424, &h->plane_separation, 4); if(little) swawbip(buf+424, 4);
132  memcpy(buf+428, &h->lwr_sctr_thres, 2); if(little) swabip(buf+428, 2);
133  memcpy(buf+430, &h->lwr_true_thres, 2); if(little) swabip(buf+430, 2);
134  memcpy(buf+432, &h->upr_true_thres, 2); if(little) swabip(buf+432, 2);
135  memcpy(buf+434, &h->user_process_code, 10);
136  memcpy(buf+444, &h->acquisition_mode, 2); if(little) swabip(buf+444, 2);
137  memcpy(buf+446, &h->bin_size, 4); if(little) swawbip(buf+446, 4);
138  memcpy(buf+450, &h->branching_fraction, 4); if(little) swawbip(buf+450, 4);
139  memcpy(buf+454, &h->dose_start_time, 4); if(little) swawbip(buf+454, 4);
140  memcpy(buf+458, &h->dosage, 4); if(little) swawbip(buf+458, 4);
141  memcpy(buf+462, &h->well_counter_corr_factor, 4); if(little) swawbip(buf+462, 4);
142  memcpy(buf+466, &h->data_units, 32);
143  memcpy(buf+498, &h->septa_state, 2); if(little) swabip(buf+498, 2);
144  memcpy(buf+500, &h->fill_cti, 12);
145 
146  /* Write main header */
147  fseek(fp, 0*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=0*MatBLKSIZE) return(4);
148  if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
149 
150  return(0);
151 }
152 /*****************************************************************************/
153 
154 /*****************************************************************************/
164 int ecat7WriteImageheader(FILE *fp, int blk, ECAT7_imageheader *h) {
165  unsigned char buf[MatBLKSIZE];
166  int little; /* 1 if current platform is little endian (i386), else 0 */
167 
168  if(ECAT7_TEST) printf("ecat7WriteImageheader()\n");
169  if(fp==NULL || blk<2 || h==NULL) return(1);
170  little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
171  /* Clear buf */
172  memset(buf, 0, MatBLKSIZE);
174  else if(h->data_type==ECAT7_VAXI4) h->data_type=ECAT7_SUNI4;
176 
177  /* Copy the header fields and swap if necessary */
178  memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
179  memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
180  memcpy(buf+4, &h->x_dimension, 2); if(little) swabip(buf+4, 2);
181  memcpy(buf+6, &h->y_dimension, 2); if(little) swabip(buf+6, 2);
182  memcpy(buf+8, &h->z_dimension, 2); if(little) swabip(buf+8, 2);
183  memcpy(buf+10, &h->x_offset, 4); if(little) swawbip(buf+10, 4);
184  memcpy(buf+14, &h->y_offset, 4); if(little) swawbip(buf+14, 4);
185  memcpy(buf+18, &h->z_offset, 4); if(little) swawbip(buf+18, 4);
186  memcpy(buf+22, &h->recon_zoom, 4); if(little) swawbip(buf+22, 4);
187  memcpy(buf+26, &h->scale_factor, 4); if(little) swawbip(buf+26, 4);
188  memcpy(buf+30, &h->image_min, 2); if(little) swabip(buf+30, 2);
189  memcpy(buf+32, &h->image_max, 2); if(little) swabip(buf+32, 2);
190  memcpy(buf+34, &h->x_pixel_size, 4); if(little) swawbip(buf+34, 4);
191  memcpy(buf+38, &h->y_pixel_size, 4); if(little) swawbip(buf+38, 4);
192  memcpy(buf+42, &h->z_pixel_size, 4); if(little) swawbip(buf+42, 4);
193  memcpy(buf+46, &h->frame_duration, 4); if(little) swawbip(buf+46, 4);
194  memcpy(buf+50, &h->frame_start_time, 4); if(little) swawbip(buf+50, 4);
195  memcpy(buf+54, &h->filter_code, 2); if(little) swabip(buf+54, 2);
196  memcpy(buf+56, &h->x_resolution, 4); if(little) swawbip(buf+56, 4);
197  memcpy(buf+60, &h->y_resolution, 4); if(little) swawbip(buf+60, 4);
198  memcpy(buf+64, &h->z_resolution, 4); if(little) swawbip(buf+64, 4);
199  memcpy(buf+68, &h->num_r_elements, 4); if(little) swawbip(buf+68, 4);
200  memcpy(buf+72, &h->num_angles, 4); if(little) swawbip(buf+72, 4);
201  memcpy(buf+76, &h->z_rotation_angle, 4); if(little) swawbip(buf+76, 4);
202  memcpy(buf+80, &h->decay_corr_fctr, 4); if(little) swawbip(buf+80, 4);
203  memcpy(buf+84, &h->processing_code, 4); if(little) swawbip(buf+84, 4);
204  memcpy(buf+88, &h->gate_duration, 4); if(little) swawbip(buf+88, 4);
205  memcpy(buf+92, &h->r_wave_offset, 4); if(little) swawbip(buf+92, 4);
206  memcpy(buf+96, &h->num_accepted_beats, 4); if(little) swawbip(buf+96, 4);
207  memcpy(buf+100, &h->filter_cutoff_frequency, 4); if(little) swawbip(buf+100, 4);
208  memcpy(buf+104, &h->filter_resolution, 4); if(little) swawbip(buf+104, 4);
209  memcpy(buf+108, &h->filter_ramp_slope, 4); if(little) swawbip(buf+108, 4);
210  memcpy(buf+112, &h->filter_order, 2); if(little) swabip(buf+112, 2);
211  memcpy(buf+114, &h->filter_scatter_fraction, 4); if(little) swawbip(buf+114, 4);
212  memcpy(buf+118, &h->filter_scatter_slope, 4); if(little) swawbip(buf+118, 4);
213  memcpy(buf+122, &h->annotation, 40);
214  memcpy(buf+162, &h->mt_1_1, 4); if(little) swawbip(buf+162, 4);
215  memcpy(buf+166, &h->mt_1_2, 4); if(little) swawbip(buf+166, 4);
216  memcpy(buf+170, &h->mt_1_3, 4); if(little) swawbip(buf+170, 4);
217  memcpy(buf+174, &h->mt_2_1, 4); if(little) swawbip(buf+174, 4);
218  memcpy(buf+178, &h->mt_2_2, 4); if(little) swawbip(buf+178, 4);
219  memcpy(buf+182, &h->mt_2_3, 4); if(little) swawbip(buf+182, 4);
220  memcpy(buf+186, &h->mt_3_1, 4); if(little) swawbip(buf+186, 4);
221  memcpy(buf+190, &h->mt_3_2, 4); if(little) swawbip(buf+190, 4);
222  memcpy(buf+194, &h->mt_3_3, 4); if(little) swawbip(buf+194, 4);
223  memcpy(buf+198, &h->rfilter_cutoff, 4); if(little) swawbip(buf+198, 4);
224  memcpy(buf+202, &h->rfilter_resolution, 4); if(little) swawbip(buf+202, 4);
225  memcpy(buf+206, &h->rfilter_code, 2); if(little) swabip(buf+206, 2);
226  memcpy(buf+208, &h->rfilter_order, 2); if(little) swabip(buf+208, 2);
227  memcpy(buf+210, &h->zfilter_cutoff, 4); if(little) swawbip(buf+210, 4);
228  memcpy(buf+214, &h->zfilter_resolution, 4); if(little) swawbip(buf+214, 4);
229  memcpy(buf+218, &h->zfilter_code, 2); if(little) swabip(buf+218, 2);
230  memcpy(buf+220, &h->zfilter_order, 2); if(little) swabip(buf+220, 2);
231  memcpy(buf+222, &h->mt_1_4, 4); if(little) swawbip(buf+222, 4);
232  memcpy(buf+226, &h->mt_2_4, 4); if(little) swawbip(buf+226, 4);
233  memcpy(buf+230, &h->mt_3_4, 4); if(little) swawbip(buf+230, 4);
234  memcpy(buf+234, &h->scatter_type, 2); if(little) swabip(buf+234, 2);
235  memcpy(buf+236, &h->recon_type, 2); if(little) swabip(buf+236, 2);
236  memcpy(buf+238, &h->recon_views, 2); if(little) swabip(buf+238, 2);
237  memcpy(buf+240, &h->fill_cti, 87);
238  memcpy(buf+414, &h->fill_user, 48);
239 
240  /* Write header */
241  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(4);
242  if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
243 
244  return(0);
245 }
246 /*****************************************************************************/
247 
248 /*****************************************************************************/
258 int ecat7WriteAttenheader(FILE *fp, int blk, ECAT7_attenheader *h) {
259  unsigned char buf[MatBLKSIZE];
260  int little; /* 1 if current platform is little endian (i386), else 0 */
261 
262  if(ECAT7_TEST) printf("ecat7WriteAttenheader()\n");
263  if(fp==NULL || blk<2 || h==NULL) return(1);
264  little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
265  /* Clear buf */
266  memset(buf, 0, MatBLKSIZE);
268  else if(h->data_type==ECAT7_VAXI4) h->data_type=ECAT7_SUNI4;
270 
271  /* Copy the header fields and swap if necessary */
272  memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
273  memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
274  memcpy(buf+4, &h->attenuation_type, 2); if(little) swabip(buf+4, 2);
275  memcpy(buf+6, &h->num_r_elements, 2); if(little) swabip(buf+6, 2);
276  memcpy(buf+8, &h->num_angles, 2); if(little) swabip(buf+8, 2);
277  memcpy(buf+10, &h->num_z_elements, 2); if(little) swabip(buf+10, 2);
278  memcpy(buf+12, &h->ring_difference, 2); if(little) swabip(buf+12, 2);
279  memcpy(buf+14, &h->x_resolution, 4); if(little) swawbip(buf+14, 4);
280  memcpy(buf+18, &h->y_resolution, 4); if(little) swawbip(buf+18, 4);
281  memcpy(buf+22, &h->z_resolution, 4); if(little) swawbip(buf+22, 4);
282  memcpy(buf+26, &h->w_resolution, 4); if(little) swawbip(buf+26, 4);
283  memcpy(buf+30, &h->scale_factor, 4); if(little) swawbip(buf+30, 4);
284  memcpy(buf+34, &h->x_offset, 4); if(little) swawbip(buf+34, 4);
285  memcpy(buf+38, &h->y_offset, 4); if(little) swawbip(buf+38, 4);
286  memcpy(buf+42, &h->x_radius, 4); if(little) swawbip(buf+42, 4);
287  memcpy(buf+46, &h->y_radius, 4); if(little) swawbip(buf+46, 4);
288  memcpy(buf+50, &h->tilt_angle, 4); if(little) swawbip(buf+50, 4);
289  memcpy(buf+54, &h->attenuation_coeff, 4); if(little) swawbip(buf+54, 4);
290  memcpy(buf+58, &h->attenuation_min, 4); if(little) swawbip(buf+58, 4);
291  memcpy(buf+62, &h->attenuation_max, 4); if(little) swawbip(buf+62, 4);
292  memcpy(buf+66, &h->skull_thickness, 4); if(little) swawbip(buf+66, 4);
293  memcpy(buf+70, &h->num_additional_atten_coeff, 2); if(little) swabip(buf+70, 2);
294  memcpy(buf+72, h->additional_atten_coeff, 8*4); if(little) swawbip(buf+72, 8*4);
295  memcpy(buf+104, &h->edge_finding_threshold, 4); if(little) swawbip(buf+104, 4);
296  memcpy(buf+108, &h->storage_order, 2); if(little) swabip(buf+108, 2);
297  memcpy(buf+110, &h->span, 2); if(little) swabip(buf+110, 2);
298  memcpy(buf+112, h->z_elements, 64*2); if(little) swabip(buf+112, 64*2);
299  memcpy(buf+240, h->fill_cti, 86*2); if(little) swabip(buf+240, 86*2);
300  memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
301 
302  /* Write header */
303  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
304  if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(4);
305  if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
306 
307  return(0);
308 }
309 /*****************************************************************************/
310 
311 /*****************************************************************************/
321 int ecat7WritePolmapheader(FILE *fp, int blk, ECAT7_polmapheader *h) {
322  unsigned char buf[MatBLKSIZE];
323  int little; /* 1 if current platform is little endian (i386), else 0 */
324 
325  if(ECAT7_TEST) printf("ecat7WritePolmapheader()\n");
326  if(fp==NULL || blk<2 || h==NULL) return(1);
327  little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
328  /* Clear buf */
329  memset(buf, 0, MatBLKSIZE);
331  else if(h->data_type==ECAT7_VAXI4) h->data_type=ECAT7_SUNI4;
333 
334  /* Copy the header fields and swap if necessary */
335  memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
336  memcpy(buf+2, &h->polar_map_type, 2); if(little) swabip(buf+2, 2);
337  memcpy(buf+4, &h->num_rings, 2); if(little) swabip(buf+4, 2);
338  memcpy(buf+6, h->sectors_per_ring, 32*2); if(little) swabip(buf+6, 32*2);
339  memcpy(buf+70, h->ring_position, 32*4); if(little) swawbip(buf+70, 32*4);
340  memcpy(buf+198, h->ring_angle, 32*2); if(little) swabip(buf+198, 32*2);
341  memcpy(buf+262, &h->start_angle, 2); if(little) swabip(buf+262, 2);
342  memcpy(buf+264, h->long_axis_left, 3*2); if(little) swabip(buf+264, 3*2);
343  memcpy(buf+270, h->long_axis_right, 3*2); if(little) swabip(buf+270, 3*2);
344  memcpy(buf+276, &h->position_data, 2); if(little) swabip(buf+276, 2);
345  memcpy(buf+278, &h->image_min, 2); if(little) swabip(buf+278, 2);
346  memcpy(buf+280, &h->image_max, 2); if(little) swabip(buf+280, 2);
347  memcpy(buf+282, &h->scale_factor, 4); if(little) swawbip(buf+282, 4);
348  memcpy(buf+286, &h->pixel_size, 4); if(little) swawbip(buf+286, 4);
349  memcpy(buf+290, &h->frame_duration, 4); if(little) swawbip(buf+290, 4);
350  memcpy(buf+294, &h->frame_start_time, 4); if(little) swawbip(buf+294, 4);
351  memcpy(buf+298, &h->processing_code, 2); if(little) swabip(buf+298, 2);
352  memcpy(buf+300, &h->quant_units, 2); if(little) swabip(buf+300, 2);
353  memcpy(buf+302, h->annotation, 40);
354  memcpy(buf+342, &h->gate_duration, 4); if(little) swawbip(buf+342, 4);
355  memcpy(buf+346, &h->r_wave_offset, 4); if(little) swawbip(buf+346, 4);
356  memcpy(buf+350, &h->num_accepted_beats, 4); if(little) swawbip(buf+350, 4);
357  memcpy(buf+354, h->polar_map_protocol, 20);
358  memcpy(buf+374, h->database_name, 30);
359  memcpy(buf+404, h->fill_cti, 27*2); if(little) swabip(buf+404, 27*2);
360 
361  /* Write header */
362  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
363  if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(4);
364  if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
365 
366  return(0);
367 }
368 /*****************************************************************************/
369 
370 /*****************************************************************************/
380 int ecat7WriteNormheader(FILE *fp, int blk, ECAT7_normheader *h) {
381  unsigned char buf[MatBLKSIZE];
382  int little; /* 1 if current platform is little endian (i386), else 0 */
383 
384  if(ECAT7_TEST) printf("ecat7WriteNormheader()\n");
385  if(fp==NULL || blk<2 || h==NULL) return(1);
386  little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
387  /* Clear buf */
388  memset(buf, 0, MatBLKSIZE);
390  else if(h->data_type==ECAT7_VAXI4) h->data_type=ECAT7_SUNI4;
392 
393  /* Copy the header fields and swap if necessary */
394  memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
395  memcpy(buf+2, &h->num_r_elements, 2); if(little) swabip(buf+2, 2);
396  memcpy(buf+4, &h->num_transaxial_crystals, 2); if(little) swabip(buf+4, 2);
397  memcpy(buf+6, &h->num_crystal_rings, 2); if(little) swabip(buf+6, 2);
398  memcpy(buf+8, &h->crystals_per_ring, 2); if(little) swabip(buf+8, 2);
399  memcpy(buf+10, &h->num_geo_corr_planes, 2); if(little) swabip(buf+10, 2);
400  memcpy(buf+12, &h->uld, 2); if(little) swabip(buf+12, 2);
401  memcpy(buf+14, &h->lld, 2); if(little) swabip(buf+14, 2);
402  memcpy(buf+16, &h->scatter_energy, 2); if(little) swabip(buf+16, 2);
403  memcpy(buf+18, &h->norm_quality_factor, 4); if(little) swawbip(buf+18, 4);
404  memcpy(buf+22, &h->norm_quality_factor_code, 2); if(little) swabip(buf+22, 2);
405  memcpy(buf+24, h->ring_dtcor1, 32*4); if(little) swawbip(buf+24, 32*4);
406  memcpy(buf+152, h->ring_dtcor2, 32*4); if(little) swawbip(buf+152, 32*4);
407  memcpy(buf+280, h->crystal_dtcor, 8*4); if(little) swawbip(buf+280, 8*4);
408  memcpy(buf+312, &h->span, 2); if(little) swabip(buf+312, 2);
409  memcpy(buf+314, &h->max_ring_diff, 2); if(little) swabip(buf+314, 2);
410  memcpy(buf+316, h->fill_cti, 48*2); if(little) swabip(buf+316, 48*2);
411  memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
412 
413  /* Write header */
414  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
415  if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(4);
416  if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
417 
418  return(0);
419 }
420 /*****************************************************************************/
421 
422 /*****************************************************************************/
433 int ecat7WriteScanheader(FILE *fp, int blk, ECAT7_scanheader *h) {
434  unsigned char buf[2*MatBLKSIZE];
435  int little; /* 1 if current platform is little endian (i386), else 0 */
436 
437  if(ECAT7_TEST) printf("ecat7WriteScanheader()\n");
438  if(fp==NULL || blk<2 || h==NULL) return(1);
439  little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
440  /* Clear buf */
441  memset(buf, 0, 2*MatBLKSIZE);
443  else if(h->data_type==ECAT7_VAXI4) h->data_type=ECAT7_SUNI4;
445 
446  /* Copy the header fields and swap if necessary */
447  memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
448  memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
449  memcpy(buf+4, &h->num_r_elements, 2); if(little) swabip(buf+4, 2);
450  memcpy(buf+6, &h->num_angles, 2); if(little) swabip(buf+6, 2);
451  memcpy(buf+8, &h->corrections_applied, 2); if(little) swabip(buf+8, 2);
452  memcpy(buf+10, h->num_z_elements, 64*2); if(little) swabip(buf+10, 64*2);
453  memcpy(buf+138, &h->ring_difference, 2); if(little) swabip(buf+138, 2);
454  memcpy(buf+140, &h->storage_order, 2); if(little) swabip(buf+140, 2);
455  memcpy(buf+142, &h->axial_compression, 2); if(little) swabip(buf+142, 2);
456  memcpy(buf+144, &h->x_resolution, 4); if(little) swawbip(buf+144, 4);
457  memcpy(buf+148, &h->v_resolution, 4); if(little) swawbip(buf+148, 4);
458  memcpy(buf+152, &h->z_resolution, 4); if(little) swawbip(buf+152, 4);
459  memcpy(buf+156, &h->w_resolution, 4); if(little) swawbip(buf+156, 4);
460  memcpy(buf+160, h->fill_gate, 6*2); if(little) swabip(buf+160, 6*2);
461  memcpy(buf+172, &h->gate_duration, 4); if(little) swawbip(buf+172, 4);
462  memcpy(buf+176, &h->r_wave_offset, 4); if(little) swawbip(buf+176, 4);
463  memcpy(buf+180, &h->num_accepted_beats, 4); if(little) swawbip(buf+180, 4);
464  memcpy(buf+184, &h->scale_factor, 4); if(little) swawbip(buf+184, 4);
465  memcpy(buf+188, &h->scan_min, 2); if(little) swabip(buf+188, 2);
466  memcpy(buf+190, &h->scan_max, 2); if(little) swabip(buf+190, 2);
467  memcpy(buf+192, &h->prompts, 4); if(little) swawbip(buf+192, 4);
468  memcpy(buf+196, &h->delayed, 4); if(little) swawbip(buf+196, 4);
469  memcpy(buf+200, &h->multiples, 4); if(little) swawbip(buf+200, 4);
470  memcpy(buf+204, &h->net_trues, 4); if(little) swawbip(buf+204, 4);
471  memcpy(buf+208, &h->tot_avg_cor, 4); if(little) swawbip(buf+208, 4);
472  memcpy(buf+212, &h->tot_avg_uncor, 4); if(little) swawbip(buf+212, 4);
473  memcpy(buf+216, &h->total_coin_rate, 4); if(little) swawbip(buf+216, 4);
474  memcpy(buf+220, &h->frame_start_time, 4); if(little) swawbip(buf+220, 4);
475  memcpy(buf+224, &h->frame_duration, 4); if(little) swawbip(buf+224, 4);
476  memcpy(buf+228, &h->deadtime_correction_factor, 4); if(little) swawbip(buf+228, 4);
477  memcpy(buf+232, h->fill_cti, 90*2); if(little) swabip(buf+232, 90*2);
478  memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
479  memcpy(buf+512, h->uncor_singles, 128*4); if(little) swawbip(buf+512, 128*4);
480 
481  /* Write 3D scan header */
482  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(4);
483  if(fwrite(buf, 1, 2*MatBLKSIZE, fp) != 2*MatBLKSIZE) return(5);
484 
485  return(0);
486 }
487 /*****************************************************************************/
488 
489 /*****************************************************************************/
499 int ecat7Write2DScanheader(FILE *fp, int blk, ECAT7_2Dscanheader *h) {
500  unsigned char buf[MatBLKSIZE];
501  int little; /* 1 if current platform is little endian (i386), else 0 */
502 
503  if(ECAT7_TEST) printf("ecat7Write2DScanheader()\n");
504  if(fp==NULL || blk<2 || h==NULL) return(1);
505  little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
506  /* Clear buf */
507  memset(buf, 0, MatBLKSIZE);
509  else if(h->data_type==ECAT7_VAXI4) h->data_type=ECAT7_SUNI4;
511 
512  /* Copy the header fields and swap if necessary */
513  memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
514  memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
515  memcpy(buf+4, &h->num_r_elements, 2); if(little) swabip(buf+4, 2);
516  memcpy(buf+6, &h->num_angles, 2); if(little) swabip(buf+6, 2);
517  memcpy(buf+8, &h->corrections_applied, 2); if(little) swabip(buf+8, 2);
518  memcpy(buf+10, &h->num_z_elements, 2); if(little) swabip(buf+10, 2);
519  memcpy(buf+12, &h->ring_difference, 2); if(little) swabip(buf+12, 2);
520  memcpy(buf+14, &h->x_resolution, 4); if(little) swawbip(buf+14, 4);
521  memcpy(buf+18, &h->y_resolution, 4); if(little) swawbip(buf+18, 4);
522  memcpy(buf+22, &h->z_resolution, 4); if(little) swawbip(buf+22, 4);
523  memcpy(buf+26, &h->w_resolution, 4); if(little) swawbip(buf+26, 4);
524  memcpy(buf+30, h->fill_gate, 6*2); if(little) swabip(buf+30, 6*2);
525  memcpy(buf+42, &h->gate_duration, 4); if(little) swawbip(buf+42, 4);
526  memcpy(buf+46, &h->r_wave_offset, 4); if(little) swawbip(buf+46, 4);
527  memcpy(buf+50, &h->num_accepted_beats, 4); if(little) swawbip(buf+50, 4);
528  memcpy(buf+54, &h->scale_factor, 4); if(little) swawbip(buf+54, 4);
529  memcpy(buf+58, &h->scan_min, 2); if(little) swabip(buf+58, 2);
530  memcpy(buf+60, &h->scan_max, 2); if(little) swabip(buf+60, 2);
531  memcpy(buf+62, &h->prompts, 4); if(little) swawbip(buf+62, 4);
532  memcpy(buf+66, &h->delayed, 4); if(little) swawbip(buf+66, 4);
533  memcpy(buf+70, &h->multiples, 4); if(little) swawbip(buf+70, 4);
534  memcpy(buf+74, &h->net_trues, 4); if(little) swawbip(buf+74, 4);
535  memcpy(buf+78, h->cor_singles, 16*4); if(little) swawbip(buf+78, 16*4);
536  memcpy(buf+142, h->uncor_singles, 16*4); if(little) swawbip(buf+142, 16*4);
537  memcpy(buf+206, &h->tot_avg_cor, 4); if(little) swawbip(buf+206, 4);
538  memcpy(buf+210, &h->tot_avg_uncor, 4); if(little) swawbip(buf+210, 4);
539  memcpy(buf+214, &h->total_coin_rate, 4); if(little) swawbip(buf+214, 4);
540  memcpy(buf+218, &h->frame_start_time, 4); if(little) swawbip(buf+218, 4);
541  memcpy(buf+222, &h->frame_duration, 4); if(little) swawbip(buf+222, 4);
542  memcpy(buf+226, &h->deadtime_correction_factor, 4); if(little) swawbip(buf+226, 4);
543  memcpy(buf+230, h->physical_planes, 8*2); if(little) swabip(buf+230, 8*2);
544  memcpy(buf+246, h->fill_cti, 83*2); if(little) swabip(buf+246, 83*2);
545  memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
546 
547  /* Write header */
548  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
549  if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(4);
550  if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
551 
552  return(0);
553 }
554 /*****************************************************************************/
555 
556 /*****************************************************************************/
566 int ecat7Write2DNormheader(FILE *fp, int blk, ECAT7_2Dnormheader *h) {
567  unsigned char buf[MatBLKSIZE];
568  int little; /* 1 if current platform is little endian (i386), else 0 */
569 
570  if(ECAT7_TEST) printf("ecat7Write2DNormheader()\n");
571  if(fp==NULL || blk<2 || h==NULL) return(1);
572  little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
573  /* Clear buf */
574  memset(buf, 0, MatBLKSIZE);
576  else if(h->data_type==ECAT7_VAXI4) h->data_type=ECAT7_SUNI4;
578 
579  /* Copy the header fields and swap if necessary */
580  memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
581  memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
582  memcpy(buf+4, &h->num_r_elements, 2); if(little) swabip(buf+4, 2);
583  memcpy(buf+6, &h->num_angles, 2); if(little) swabip(buf+6, 2);
584  memcpy(buf+8, &h->num_z_elements, 2); if(little) swabip(buf+8, 2);
585  memcpy(buf+10, &h->ring_difference, 2); if(little) swabip(buf+10, 2);
586  memcpy(buf+12, &h->scale_factor, 4); if(little) swawbip(buf+12, 4);
587  memcpy(buf+16, &h->norm_min, 4); if(little) swawbip(buf+16, 4);
588  memcpy(buf+20, &h->norm_max, 4); if(little) swawbip(buf+20, 4);
589  memcpy(buf+24, &h->fov_source_width, 4); if(little) swawbip(buf+24, 4);
590  memcpy(buf+28, &h->norm_quality_factor, 4); if(little) swawbip(buf+28, 4);
591  memcpy(buf+32, &h->norm_quality_factor_code, 2); if(little) swabip(buf+32, 2);
592  memcpy(buf+34, &h->storage_order, 2); if(little) swabip(buf+34, 2);
593  memcpy(buf+36, &h->span, 2); if(little) swabip(buf+36, 2);
594  memcpy(buf+38, h->fill_cti, 64*2); if(little) swabip(buf+38, 64*2);
595  memcpy(buf+166, h->fill_cti, 123*2); if(little) swabip(buf+166, 123*2);
596  memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
597 
598  /* Write header */
599  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
600  if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(4);
601  if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
602 
603  return(0);
604 }
605 /*****************************************************************************/
606 
607 /*****************************************************************************/
616 FILE *ecat7Create(const char *fname, ECAT7_mainheader *h) {
617  FILE *fp;
618  char tmp[FILENAME_MAX];
619  int buf[MatBLKSIZE/4];
620 
621  if(ECAT7_TEST) printf("ecat7Create(%s, h)\n", fname);
622  /* Check the arguments */
623  if(fname==NULL || h==NULL) return(NULL);
624  /* Check if file exists; backup, if necessary */
625  if(access(fname, 0) != -1) {
626  strcpy(tmp, fname); strcat(tmp, BACKUP_EXTENSION);
627  if(access(tmp, 0) != -1) remove(tmp);
628  if(ECAT7_TEST) printf("Renaming %s -> %s\n", fname, tmp);
629  rename(fname, tmp);
630  }
631  /* Open file */
632  fp=fopen(fname, "wb+"); if(fp==NULL) return(fp);
633  /* Write main header */
634  if(ecat7WriteMainheader(fp, h)) return(NULL);
635  /* Construct an empty matrix list ; convert to little endian if necessary */
636  memset(buf, 0, MatBLKSIZE);
637  buf[0]=31; buf[1]=MatFirstDirBlk; if(little_endian()) swawbip(buf, MatBLKSIZE);
638  /* Write data buffer */
639  fseek(fp, (MatFirstDirBlk-1)*MatBLKSIZE, SEEK_SET);
640  if(ftell(fp)!=(MatFirstDirBlk-1)*MatBLKSIZE) return(NULL);
641  if(fwrite(buf, 4, MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(NULL);
642  /* OK, then return file pointer */
643  return(fp);
644 }
645 /*****************************************************************************/
646 
647 /*****************************************************************************/
657 int ecat7_is_scaling_needed(float amax, float *data, int nr) {
658  int i;
659  double d;
660 
661  if(nr<1 || data==NULL) return(0);
662  /* scaling is necessary if all values are between -1 - 1 */
663  if(amax<0.9999) return(1);
664  /* Lets check first if at least the max value is close to integers or not */
665  if(modf(amax, &d)>0.0001) return(1);
666  /* if it is, then check all pixels */
667  for(i=0; i<nr; i++) if(modf(*data++, &d)>0.0001) return(1);
668  return(0);
669 }
670 /*****************************************************************************/
671 
672 /*****************************************************************************/
682 int ecat7WriteImageMatrix(FILE *fp, int matrix_id, ECAT7_imageheader *h, float *fdata) {
683  int i, nxtblk, blkNr, data_size, pxlNr, ret;
684  float *fptr, fmin, fmax, g, f;
685  char *mdata, *mptr;
686  short int *sptr;
687 
688 
689  if(ECAT7_TEST) printf("ecat7WriteImageMatrix(fp, %d, h, data)\n", matrix_id);
690  if(fp==NULL || matrix_id<1 || h==NULL || fdata==NULL) {
691  sprintf(ecat7errmsg, "invalid function parameter.\n");
692  return(1);
693  }
694  if(h->data_type!=ECAT7_SUNI2) {
695  sprintf(ecat7errmsg, "invalid data_type.\n");
696  return(2);
697  }
698  /* nr of pixels */
699  pxlNr=h->x_dimension*h->y_dimension;
700  if(h->num_dimensions>2) pxlNr*=h->z_dimension;
701  if(pxlNr<1) {
702  sprintf(ecat7errmsg, "invalid matrix dimension.\n");
703  return(3);
704  }
705  /* How much memory is needed for ALL pixels */
706  data_size=pxlNr*ecat7pxlbytes(h->data_type);
707  /* block nr taken by all pixels */
708  blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
709  sprintf(ecat7errmsg, "invalid block number.\n");
710  return(4);
711  }
712  /* Allocate memory for matrix data */
713  mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
714  sprintf(ecat7errmsg, "out of memory.\n");
715  return(5);
716  }
717  /* Search for min and max for calculation of scale factor */
718  fptr=fdata; fmin=fmax=*fptr;
719  for(i=0; i<pxlNr; i++, fptr++) {
720  if(*fptr>fmax) fmax=*fptr; else if(*fptr<fmin) fmin=*fptr;
721  }
722  if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
723  if(g>0) f=32766./g; else f=1.0;
724  /* Check if pixels values can be left as such with scale_factor = 1 */
725  fptr=fdata;
726  if(f>=1.0 && ecat7_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
727  /* Scale matrix data to shorts */
728  h->scale_factor=1.0/f;
729  sptr=(short int*)mdata; fptr=fdata;
730  for(i=0; i<pxlNr; i++, sptr++, fptr++) *sptr=(short int)temp_roundf(f*(*fptr));
731  /* Set header short min & max */
732  h->image_min=(short int)temp_roundf(f*fmin);
733  h->image_max=(short int)temp_roundf(f*fmax);
734  /* Get block number for matrix header and data */
735  nxtblk=ecat7EnterMatrix(fp, matrix_id, blkNr); if(nxtblk<1) {
736  sprintf(ecat7errmsg, "cannot determine matrix block (%d).\n", -nxtblk);
737  free(mdata); return(8);
738  }
739  if(ECAT7_TEST>2) printf(" block=%d fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
740  /* Write header */
741  ret=ecat7WriteImageheader(fp, nxtblk, h); if(ret) {
742  sprintf(ecat7errmsg, "cannot write subheader (%d).\n", ret);
743  free(mdata); return(10);
744  }
745  /* Write matrix data */
746  mptr=mdata;
747  ret=ecat7WriteMatrixdata(fp, nxtblk+1, mptr, pxlNr, ecat7pxlbytes(h->data_type));
748  free(mdata);
749  if(ret) {
750  sprintf(ecat7errmsg, "cannot write matrix data (%d).\n", ret);
751  return(13);
752  }
753  return(0);
754 }
755 /*****************************************************************************/
756 
757 /*****************************************************************************/
767 int ecat7Write2DScanMatrix(FILE *fp, int matrix_id, ECAT7_2Dscanheader *h, float *fdata) {
768  int i, nxtblk, blkNr, data_size, pxlNr, ret;
769  float *fptr, fmin, fmax, g, f;
770  char *mdata, *mptr;
771  short int *sptr;
772 
773 
774  if(ECAT7_TEST) printf("ecat7Write2DScanMatrix(fp, %d, h, data)\n", matrix_id);
775  if(fp==NULL || matrix_id<1 || h==NULL || fdata==NULL) {
776  sprintf(ecat7errmsg, "invalid function parameter.\n");
777  return(1);
778  }
779  if(h->data_type!=ECAT7_SUNI2) {
780  sprintf(ecat7errmsg, "invalid data_type.\n");
781  return(2);
782  }
783  /* nr of pixels */
784  pxlNr=h->num_r_elements*h->num_angles;
785  if(h->num_dimensions>2) pxlNr*=h->num_z_elements;
786  if(pxlNr<1) {
787  sprintf(ecat7errmsg, "invalid matrix dimension.\n");
788  return(3);
789  }
790  /* How much memory is needed for ALL pixels */
791  data_size=pxlNr*ecat7pxlbytes(h->data_type);
792  /* block nr taken by all pixels */
793  blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
794  sprintf(ecat7errmsg, "invalid block number.\n");
795  return(4);
796  }
797  /* Allocate memory for matrix data */
798  mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
799  sprintf(ecat7errmsg, "out of memory.\n");
800  return(5);
801  }
802  /* Search for min and max for calculation of scale factor */
803  fptr=fdata; fmin=fmax=*fptr;
804  for(i=0; i<pxlNr; i++, fptr++) {
805  if(*fptr>fmax) fmax=*fptr; else if(*fptr<fmin) fmin=*fptr;
806  }
807  if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
808  if(g>0) f=32766./g; else f=1.0;
809  /* Check if pixels values can be left as such with scale_factor = 1 */
810  fptr=fdata;
811  if(f>=1.0 && ecat7_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
812  /* Scale matrix data to shorts */
813  h->scale_factor=1.0/f;
814  sptr=(short int*)mdata; fptr=fdata;
815  for(i=0; i<pxlNr; i++, sptr++, fptr++) *sptr=(short int)temp_roundf(f*(*fptr));
816  /* Set header short min & max */
817  h->scan_min=(short int)temp_roundf(f*fmin);
818  h->scan_max=(short int)temp_roundf(f*fmax);
819  /* Get block number for matrix header and data */
820  nxtblk=ecat7EnterMatrix(fp, matrix_id, blkNr); if(nxtblk<1) {
821  sprintf(ecat7errmsg, "cannot determine matrix block (%d).\n", -nxtblk);
822  free(mdata); return(8);
823  }
824  if(ECAT7_TEST>2) printf(" block=%d fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
825  /* Write header */
826  ret=ecat7Write2DScanheader(fp, nxtblk, h); if(ret) {
827  sprintf(ecat7errmsg, "cannot write subheader (%d).\n", ret);
828  free(mdata); return(10);
829  }
830  /* Write matrix data */
831  mptr=mdata;
832  ret=ecat7WriteMatrixdata(fp, nxtblk+1, mptr, pxlNr, ecat7pxlbytes(h->data_type));
833  free(mdata);
834  if(ret) {
835  sprintf(ecat7errmsg, "cannot write matrix data (%d).\n", ret);
836  return(13);
837  }
838  return(0);
839 }
840 /*****************************************************************************/
841 
842 /*****************************************************************************/
852 int ecat7WriteScanMatrix(FILE *fp, int matrix_id, ECAT7_scanheader *h, float *fdata) {
853  int i, nxtblk, blkNr, data_size, pxlNr, dimz, ret;
854  float *fptr, fmin, fmax, g, f;
855  char *mdata, *mptr;
856  short int *sptr;
857 
858 
859  if(ECAT7_TEST) printf("ecat7WriteScanMatrix(fp, %d, h, data)\n", matrix_id);
860  if(fp==NULL || matrix_id<1 || h==NULL || fdata==NULL) {
861  sprintf(ecat7errmsg, "invalid function parameter.\n");
862  return(1);
863  }
864  if(h->data_type!=ECAT7_SUNI2) {
865  sprintf(ecat7errmsg, "invalid data_type.\n");
866  return(2);
867  }
868  /* nr of pixels */
869  pxlNr=h->num_r_elements*h->num_angles;
870  for(i=dimz=0; i<64; i++) dimz+=h->num_z_elements[i]; pxlNr*=dimz;
871  if(pxlNr<1) {
872  sprintf(ecat7errmsg, "invalid matrix dimension.\n");
873  return(3);
874  }
875  /* How much memory is needed for ALL pixels */
876  data_size=pxlNr*ecat7pxlbytes(h->data_type);
877  /* block nr taken by all pixels */
878  blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
879  sprintf(ecat7errmsg, "invalid block number.\n");
880  return(4);
881  }
882  /* Allocate memory for matrix data */
883  mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
884  sprintf(ecat7errmsg, "out of memory.\n");
885  return(5);
886  }
887  /* Search for min and max for calculation of scale factor */
888  fptr=fdata; fmin=fmax=*fptr;
889  for(i=0; i<pxlNr; i++, fptr++) {
890  if(*fptr>fmax) fmax=*fptr; else if(*fptr<fmin) fmin=*fptr;
891  }
892  if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
893  if(g>0) f=32766./g; else f=1.0;
894  /* Check if pixels values can be left as such with scale_factor = 1 */
895  fptr=fdata;
896  if(f>=1.0 && ecat7_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
897  /* Scale matrix data to shorts */
898  h->scale_factor=1.0/f;
899  sptr=(short int*)mdata; fptr=fdata;
900  for(i=0; i<pxlNr; i++, sptr++, fptr++) *sptr=(short int)temp_roundf(f*(*fptr));
901  /* Set header short min & max */
902  h->scan_min=(short int)temp_roundf(f*fmin);
903  h->scan_max=(short int)temp_roundf(f*fmax);
904  /* Get block number for matrix header and data */
905  /* Note that one extra block (blkNr+1) is needed for 3D scan header */
906  nxtblk=ecat7EnterMatrix(fp, matrix_id, blkNr+1); if(nxtblk<1) {
907  sprintf(ecat7errmsg, "cannot determine matrix block (%d).\n", -nxtblk);
908  free(mdata); return(8);
909  }
910  if(ECAT7_TEST>2) printf(" block=%d fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
911  /* Write header */
912  ret=ecat7WriteScanheader(fp, nxtblk, h); if(ret) {
913  sprintf(ecat7errmsg, "cannot write subheader (%d).\n", ret);
914  free(mdata); return(10);
915  }
916  /* Write matrix data */
917  /* Note that 3D scan header takes TWO blocks */
918  mptr=mdata;
919  ret=ecat7WriteMatrixdata(fp, nxtblk+2, mptr, pxlNr, ecat7pxlbytes(h->data_type));
920  free(mdata);
921  if(ret) {
922  sprintf(ecat7errmsg, "cannot write matrix data (%d).\n", ret);
923  return(13);
924  }
925  return(0);
926 }
927 /*****************************************************************************/
928 
929 /*****************************************************************************/
939 int ecat7WritePolarmapMatrix(FILE *fp, int matrix_id, ECAT7_polmapheader *h, float *fdata) {
940  int i, nxtblk, blkNr, data_size, pxlNr, ret;
941  float *fptr, fmin, fmax, g, f;
942  char *mdata, *mptr;
943  short int *sptr;
944 
945 
946  if(ECAT7_TEST) printf("ecat7WritePolarmapMatrix(fp, %d, h, data)\n", matrix_id);
947  if(fp==NULL || matrix_id<1 || h==NULL || fdata==NULL) {
948  sprintf(ecat7errmsg, "invalid function parameter.\n");
949  return(1);
950  }
951  if(h->data_type!=ECAT7_SUNI2) {
952  sprintf(ecat7errmsg, "invalid data_type.\n");
953  return(2);
954  }
955  /* nr of pixels */
956  for(i=pxlNr=0; i<h->num_rings; i++) pxlNr+=h->sectors_per_ring[i];
957  if(pxlNr<1) {
958  sprintf(ecat7errmsg, "invalid matrix dimension.\n");
959  return(3);
960  }
961  /* How much memory is needed for ALL pixels */
962  data_size=pxlNr*ecat7pxlbytes(h->data_type);
963  /* block nr taken by all pixels */
964  blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
965  sprintf(ecat7errmsg, "invalid block number.\n");
966  return(4);
967  }
968  /* Allocate memory for matrix data */
969  mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
970  sprintf(ecat7errmsg, "out of memory.\n");
971  return(5);
972  }
973  /* Search for min and max for calculation of scale factor */
974  fptr=fdata; fmin=fmax=*fptr;
975  for(i=0; i<pxlNr; i++, fptr++) {
976  if(*fptr>fmax) fmax=*fptr; else if(*fptr<fmin) fmin=*fptr;
977  }
978  if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
979  if(g>0) f=32766./g; else f=1.0;
980  /* Check if pixels values can be left as such with scale_factor = 1 */
981  fptr=fdata;
982  if(f>=1.0 && ecat7_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
983  /* Scale matrix data to shorts */
984  h->scale_factor=1.0/f;
985  sptr=(short int*)mdata; fptr=fdata;
986  for(i=0; i<pxlNr; i++, sptr++, fptr++) *sptr=(short int)temp_roundf(f*(*fptr));
987  /* Set header short min & max */
988  h->image_min=(short int)temp_roundf(f*fmin);
989  h->image_max=(short int)temp_roundf(f*fmax);
990  /* Get block number for matrix header and data */
991  nxtblk=ecat7EnterMatrix(fp, matrix_id, blkNr); if(nxtblk<1) {
992  sprintf(ecat7errmsg, "cannot determine matrix block (%d).\n", -nxtblk);
993  free(mdata); return(8);
994  }
995  if(ECAT7_TEST>2) printf(" block=%d fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
996  /* Write header */
997  ret=ecat7WritePolmapheader(fp, nxtblk, h); if(ret) {
998  sprintf(ecat7errmsg, "cannot write subheader (%d).\n", ret);
999  free(mdata); return(10);
1000  }
1001  /* Write matrix data */
1002  mptr=mdata;
1003  ret=ecat7WriteMatrixdata(fp, nxtblk+1, mptr, pxlNr, ecat7pxlbytes(h->data_type));
1004  free(mdata);
1005  if(ret) {
1006  sprintf(ecat7errmsg, "cannot write matrix data (%d).\n", ret);
1007  return(13);
1008  }
1009  return(0);
1010 }
1011 /*****************************************************************************/
1012 
1013 /*****************************************************************************/
1027 int ecat7WriteMatrixdata(FILE *fp, int start_block, char *data, int pxl_nr, int pxl_size) {
1028  unsigned char buf[MatBLKSIZE];
1029  char *dptr;
1030  int i, blkNr, dataSize, byteNr, little;
1031 
1032  if(ECAT7_TEST) printf("ecat7WriteMatrixdata(fp, %d, data, %d, %d)\n",
1033  start_block, pxl_nr, pxl_size);
1034  if(fp==NULL || start_block<1 || data==NULL || pxl_nr<1 || pxl_size<1) return(1);
1035  little=little_endian(); memset(buf, 0, MatBLKSIZE);
1036  dataSize=pxl_nr*pxl_size;
1037  /* block nr taken by all pixels */
1038  blkNr=(dataSize+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) return(1);
1039  if(ECAT7_TEST>2) printf(" blkNr=%d\n", blkNr);
1040  /* Search the place for writing */
1041  fseek(fp, (start_block-1)*MatBLKSIZE, SEEK_SET);
1042  if(ftell(fp)!=(start_block-1)*MatBLKSIZE) return(2);
1043  /* Save blocks one at a time */
1044  for(i=0, dptr=data; i<blkNr && dataSize>0; i++) {
1045  byteNr=(dataSize<MatBLKSIZE)?dataSize:MatBLKSIZE;
1046  memcpy(buf, dptr, byteNr);
1047  /* Change matrix byte order in little endian platforms */
1048  if(little) {
1049  if(pxl_size==2) swabip(buf, byteNr);
1050  else if(pxl_size==4) swawbip(buf, byteNr);
1051  }
1052  /* Write block */
1053  if(fwrite(buf, 1, MatBLKSIZE, fp)!=MatBLKSIZE) return(3);
1054  /* Prepare for the next block */
1055  dptr+=byteNr; dataSize-=byteNr;
1056  } /* next block */
1057  return(0);
1058 }
1059 /*****************************************************************************/
1060 
1061 /*****************************************************************************/
1062 
short int uld
Definition: ecat7.h:551
float scale_factor
Definition: ecat7.h:438
float tot_avg_cor
Definition: ecat7.h:403
float z_resolution
Definition: ecat7.h:270
float z_pixel_size
Definition: ecat7.h:258
float uncor_singles[128]
Definition: ecat7.h:419
char study_type[12]
Definition: ecat7.h:154
short int calibration_units_label
Definition: ecat7.h:150
float well_counter_corr_factor
Definition: ecat7.h:219
float isotope_halflife
Definition: ecat7.h:121
short int num_z_elements[64]
Definition: ecat7.h:365
int ecat7Write2DScanMatrix(FILE *fp, int matrix_id, ECAT7_2Dscanheader *h, float *fdata)
Definition: ecat7w.c:767
float ring_dtcor1[32]
Definition: ecat7.h:561
float mt_3_1
Definition: ecat7.h:314
float x_resolution
Definition: ecat7.h:373
int patient_birth_date
Definition: ecat7.h:172
int ecat7WriteScanheader(FILE *fp, int blk, ECAT7_scanheader *h)
Definition: ecat7w.c:433
short int num_r_elements
Definition: ecat7.h:486
float recon_zoom
Definition: ecat7.h:246
short int num_angles
Definition: ecat7.h:462
short int num_angles
Definition: ecat7.h:426
float z_rotation_angle
Definition: ecat7.h:276
short int compression_code
Definition: ecat7.h:152
short int num_r_elements
Definition: ecat7.h:425
short int filter_code
Definition: ecat7.h:264
int ecat7WriteMatrixdata(FILE *fp, int start_block, char *data, int pxl_nr, int pxl_size)
Definition: ecat7w.c:1027
#define ECAT7_VAXI4
Definition: ecat7.h:60
short int corrections_applied
Definition: ecat7.h:363
float scale_factor
Definition: ecat7.h:465
int ecat7WriteNormheader(FILE *fp, int blk, ECAT7_normheader *h)
Definition: ecat7w.c:380
short int start_angle
Definition: ecat7.h:583
float y_resolution
Definition: ecat7.h:431
short int fill_cti[6]
Definition: ecat7.h:225
int frame_duration
Definition: ecat7.h:451
float branching_fraction
Definition: ecat7.h:213
short int span
Definition: ecat7.h:530
short int zfilter_code
Definition: ecat7.h:332
float x_resolution
Definition: ecat7.h:494
float filter_scatter_fraction
Definition: ecat7.h:296
float uncor_singles[16]
Definition: ecat7.h:446
short int recon_type
Definition: ecat7.h:344
int scan_start_time
Definition: ecat7.h:117
float ecat_calibration_factor
Definition: ecat7.h:146
float norm_min
Definition: ecat7.h:466
short int patient_orientation
Definition: ecat7.h:183
short int scatter_energy
Definition: ecat7.h:555
short int num_dimensions
Definition: ecat7.h:232
short int num_z_elements
Definition: ecat7.h:490
int num_accepted_beats
Definition: ecat7.h:387
int r_wave_offset
Definition: ecat7.h:284
int ecat7WritePolarmapMatrix(FILE *fp, int matrix_id, ECAT7_polmapheader *h, float *fdata)
Definition: ecat7w.c:939
float x_offset
Definition: ecat7.h:240
float tot_avg_uncor
Definition: ecat7.h:405
short int fill_cti[87]
Definition: ecat7.h:348
short int num_geo_corr_planes
Definition: ecat7.h:549
short int num_bed_pos
Definition: ecat7.h:193
short int data_type
Definition: ecat7.h:540
float mt_3_3
Definition: ecat7.h:318
float norm_max
Definition: ecat7.h:467
char operator_name[32]
Definition: ecat7.h:176
short int num_additional_atten_coeff
Definition: ecat7.h:522
float filter_resolution
Definition: ecat7.h:290
short int num_angles
Definition: ecat7.h:361
short int data_type
Definition: ecat7.h:355
short int span
Definition: ecat7.h:472
short int z_dimension
Definition: ecat7.h:238
int ecat7WritePolmapheader(FILE *fp, int blk, ECAT7_polmapheader *h)
Definition: ecat7w.c:321
short int lld
Definition: ecat7.h:553
float y_resolution
Definition: ecat7.h:268
short int num_angles
Definition: ecat7.h:488
short int z_elements[64]
Definition: ecat7.h:532
short int lwr_true_thres
Definition: ecat7.h:203
short int num_frames
Definition: ecat7.h:189
char original_file_name[32]
Definition: ecat7.h:107
short int num_dimensions
Definition: ecat7.h:460
short int data_type
Definition: ecat7.h:230
#define ECAT7_VAXR4
Definition: ecat7.h:61
short int rfilter_order
Definition: ecat7.h:326
float mt_3_4
Definition: ecat7.h:340
#define ECAT7_IEEER4
Definition: ecat7.h:62
short int file_type
Definition: ecat7.h:113
short int fill_cti[90]
Definition: ecat7.h:415
char polar_map_protocol[20]
Definition: ecat7.h:599
float x_resolution
Definition: ecat7.h:266
int ECAT7_TEST
Definition: ecat7.h:101
float fov_source_width
Definition: ecat7.h:468
short int num_dimensions
Definition: ecat7.h:482
float transaxial_fov
Definition: ecat7.h:139
float attenuation_coeff
Definition: ecat7.h:514
float patient_age
Definition: ecat7.h:164
float zfilter_cutoff
Definition: ecat7.h:328
short int rfilter_code
Definition: ecat7.h:324
float edge_finding_threshold
Definition: ecat7.h:526
short int fill_user[49]
Definition: ecat7.h:350
char patient_id[16]
Definition: ecat7.h:156
float tot_avg_uncor
Definition: ecat7.h:448
float mt_2_2
Definition: ecat7.h:310
short int num_dimensions
Definition: ecat7.h:357
short int fill_user[50]
Definition: ecat7.h:536
float ring_dtcor2[32]
Definition: ecat7.h:563
char serial_number[10]
Definition: ecat7.h:115
char isotope_name[8]
Definition: ecat7.h:119
short int num_gates
Definition: ecat7.h:191
float bed_elevation
Definition: ecat7.h:129
float v_resolution
Definition: ecat7.h:375
int frame_start_time
Definition: ecat7.h:262
short int crystals_per_ring
Definition: ecat7.h:547
char patient_name[32]
Definition: ecat7.h:158
float patient_height
Definition: ecat7.h:166
float scale_factor
Definition: ecat7.h:389
float distance_scanned
Definition: ecat7.h:137
short int x_dimension
Definition: ecat7.h:234
int num_accepted_beats
Definition: ecat7.h:437
float scale_factor
Definition: ecat7.h:589
float mt_1_1
Definition: ecat7.h:302
float y_offset
Definition: ecat7.h:242
short int polar_map_type
Definition: ecat7.h:578
float rfilter_cutoff
Definition: ecat7.h:320
short int num_transaxial_crystals
Definition: ecat7.h:544
short int storage_order
Definition: ecat7.h:471
short int lwr_sctr_thres
Definition: ecat7.h:201
short int angular_compression
Definition: ecat7.h:141
char annotation[40]
Definition: ecat7.h:300
short int processing_code
Definition: ecat7.h:593
float y_pixel_size
Definition: ecat7.h:256
short int ring_difference
Definition: ecat7.h:464
#define MatBLKSIZE
Definition: ecat63.h:27
short int scatter_type
Definition: ecat7.h:342
short int num_rings
Definition: ecat7.h:579
float pixel_size
Definition: ecat7.h:590
float deadtime_correction_factor
Definition: ecat7.h:452
char magic_number[14]
Definition: ecat7.h:105
float norm_quality_factor
Definition: ecat7.h:557
float tilt_angle
Definition: ecat7.h:512
float deadtime_correction_factor
Definition: ecat7.h:413
short int ring_difference
Definition: ecat7.h:492
short int calibration_units
Definition: ecat7.h:148
float z_resolution
Definition: ecat7.h:432
short int image_max
Definition: ecat7.h:588
char physician_name[32]
Definition: ecat7.h:174
float y_resolution
Definition: ecat7.h:496
float init_bed_position
Definition: ecat7.h:195
short int data_type
Definition: ecat7.h:459
float w_resolution
Definition: ecat7.h:500
int ecat7_is_scaling_needed(float amax, float *data, int nr)
Definition: ecat7w.c:657
short int septa_state
Definition: ecat7.h:223
float mt_2_3
Definition: ecat7.h:312
float x_pixel_size
Definition: ecat7.h:254
float mt_2_4
Definition: ecat7.h:338
#define ECAT7_SUNI4
Definition: ecat7.h:64
short int long_axis_left[3]
Definition: ecat7.h:584
short int position_data
Definition: ecat7.h:586
short int scan_min
Definition: ecat7.h:391
float mt_1_3
Definition: ecat7.h:306
short int sw_version
Definition: ecat7.h:109
short int coin_samp_mode
Definition: ecat7.h:143
int frame_duration
Definition: ecat7.h:260
short int ring_difference
Definition: ecat7.h:367
float zfilter_resolution
Definition: ecat7.h:330
float crystal_dtcor[8]
Definition: ecat7.h:565
int r_wave_offset
Definition: ecat7.h:385
short int num_planes
Definition: ecat7.h:187
float mt_3_2
Definition: ecat7.h:316
short int num_crystal_rings
Definition: ecat7.h:546
float cor_singles[16]
Definition: ecat7.h:445
short int physical_planes[8]
Definition: ecat7.h:453
short int zfilter_order
Definition: ecat7.h:334
char ecat7errmsg[128]
Definition: ecat7.h:99
float mt_2_1
Definition: ecat7.h:308
float filter_scatter_slope
Definition: ecat7.h:298
short int fill_gate[6]
Definition: ecat7.h:434
float rfilter_resolution
Definition: ecat7.h:322
char annotation[40]
Definition: ecat7.h:595
short int scan_max
Definition: ecat7.h:440
float x_radius
Definition: ecat7.h:508
short int data_type
Definition: ecat7.h:577
int frame_start_time
Definition: ecat7.h:592
short int upr_true_thres
Definition: ecat7.h:205
int ecat7WriteImageheader(FILE *fp, int blk, ECAT7_imageheader *h)
Definition: ecat7w.c:164
float patient_weight
Definition: ecat7.h:168
short int fill_user[50]
Definition: ecat7.h:475
float scale_factor
Definition: ecat7.h:502
char patient_dexterity
Definition: ecat7.h:162
int ecat7WriteAttenheader(FILE *fp, int blk, ECAT7_attenheader *h)
Definition: ecat7w.c:258
float mt_1_2
Definition: ecat7.h:304
int frame_start_time
Definition: ecat7.h:409
short int fill_cti[27]
Definition: ecat7.h:601
int ecat7pxlbytes(short int data_type)
Definition: ecat7r.c:1055
float z_resolution
Definition: ecat7.h:377
short int axial_compression
Definition: ecat7.h:371
short int acquisition_mode
Definition: ecat7.h:209
float intrinsic_tilt
Definition: ecat7.h:131
int dose_start_time
Definition: ecat7.h:215
#define ECAT7_VAXI2
Definition: ecat7.h:59
float plane_separation
Definition: ecat7.h:199
float y_radius
Definition: ecat7.h:510
short int span
Definition: ecat7.h:567
float bed_position[15]
Definition: ecat7.h:197
short int quant_units
Definition: ecat7.h:594
short int filter_order
Definition: ecat7.h:294
int frame_start_time
Definition: ecat7.h:450
short int storage_order
Definition: ecat7.h:369
char user_process_code[10]
Definition: ecat7.h:207
float z_offset
Definition: ecat7.h:244
float skull_thickness
Definition: ecat7.h:520
float y_offset
Definition: ecat7.h:506
short int num_dimensions
Definition: ecat7.h:424
short int fill_user[50]
Definition: ecat7.h:573
short int fill_cti[83]
Definition: ecat7.h:454
short int ring_angle[32]
Definition: ecat7.h:582
short int y_dimension
Definition: ecat7.h:236
short int num_z_elements
Definition: ecat7.h:463
#define ECAT7_SUNI2
Definition: ecat7.h:63
short int max_ring_diff
Definition: ecat7.h:569
short int transm_source_type
Definition: ecat7.h:135
int num_accepted_beats
Definition: ecat7.h:286
char database_name[30]
Definition: ecat7.h:600
short int scan_min
Definition: ecat7.h:439
char patient_sex
Definition: ecat7.h:160
float attenuation_max
Definition: ecat7.h:518
#define MatFirstDirBlk
Definition: ecat63.h:28
int ecat7WriteImageMatrix(FILE *fp, int matrix_id, ECAT7_imageheader *h, float *fdata)
Definition: ecat7w.c:682
float x_offset
Definition: ecat7.h:504
int ecat7WriteMainheader(FILE *fp, ECAT7_mainheader *h)
Definition: ecat7w.c:73
int num_accepted_beats
Definition: ecat7.h:598
FILE * ecat7Create(const char *fname, ECAT7_mainheader *h)
Definition: ecat7w.c:616
int ecat7WriteScanMatrix(FILE *fp, int matrix_id, ECAT7_scanheader *h, float *fdata)
Definition: ecat7w.c:852
int gate_duration
Definition: ecat7.h:282
float w_resolution
Definition: ecat7.h:433
float filter_ramp_slope
Definition: ecat7.h:292
int processing_code
Definition: ecat7.h:280
short int acquisition_type
Definition: ecat7.h:181
short int norm_quality_factor_code
Definition: ecat7.h:559
float decay_corr_fctr
Definition: ecat7.h:278
short int attenuation_type
Definition: ecat7.h:484
int frame_duration
Definition: ecat7.h:591
char data_units[32]
Definition: ecat7.h:221
short int system_type
Definition: ecat7.h:111
float gantry_rotation
Definition: ecat7.h:127
short int fill_user[50]
Definition: ecat7.h:417
int ecat7Write2DScanheader(FILE *fp, int blk, ECAT7_2Dscanheader *h)
Definition: ecat7w.c:499
short int storage_order
Definition: ecat7.h:528
char study_description[32]
Definition: ecat7.h:178
short int image_max
Definition: ecat7.h:252
float dosage
Definition: ecat7.h:217
short int axial_samp_mode
Definition: ecat7.h:145
int total_coin_rate
Definition: ecat7.h:407
float z_resolution
Definition: ecat7.h:498
short int num_z_elements
Definition: ecat7.h:428
int frame_duration
Definition: ecat7.h:411
short int fill_cti[86]
Definition: ecat7.h:534
float attenuation_min
Definition: ecat7.h:516
short int scan_max
Definition: ecat7.h:393
float filter_cutoff_frequency
Definition: ecat7.h:288
short int recon_views
Definition: ecat7.h:346
int total_coin_rate
Definition: ecat7.h:449
short int sectors_per_ring[32]
Definition: ecat7.h:580
short int image_min
Definition: ecat7.h:587
int ecat7EnterMatrix(FILE *fp, int matrix_id, int block_nr)
Definition: ecat7ml.c:184
short int long_axis_right[3]
Definition: ecat7.h:585
short int data_type
Definition: ecat7.h:480
int gate_duration
Definition: ecat7.h:383
short int norm_quality_factor_code
Definition: ecat7.h:470
short int wobble_speed
Definition: ecat7.h:133
short int fill_gate[6]
Definition: ecat7.h:381
short int fill_user[50]
Definition: ecat7.h:455
short int ring_difference
Definition: ecat7.h:429
char radiopharmaceutical[32]
Definition: ecat7.h:123
float gantry_tilt
Definition: ecat7.h:125
int ecat7Write2DNormheader(FILE *fp, int blk, ECAT7_2Dnormheader *h)
Definition: ecat7w.c:566
float x_resolution
Definition: ecat7.h:430
float mt_1_4
Definition: ecat7.h:336
short int data_type
Definition: ecat7.h:423
short int num_r_elements
Definition: ecat7.h:461
short int num_r_elements
Definition: ecat7.h:359
float num_r_elements
Definition: ecat7.h:272
float norm_quality_factor
Definition: ecat7.h:469
short int corrections_applied
Definition: ecat7.h:427
float scale_factor
Definition: ecat7.h:248
float num_angles
Definition: ecat7.h:274
float ring_position[32]
Definition: ecat7.h:581
short int num_r_elements
Definition: ecat7.h:542
float additional_atten_coeff[8]
Definition: ecat7.h:524
short int fill_cti[48]
Definition: ecat7.h:571
short int image_min
Definition: ecat7.h:250
short int fill_cti[123]
Definition: ecat7.h:474
#define BACKUP_EXTENSION
Definition: analyze.h:19
float tot_avg_cor
Definition: ecat7.h:447
float bin_size
Definition: ecat7.h:211
float w_resolution
Definition: ecat7.h:379
char facility_name[20]
Definition: ecat7.h:185