1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * filename: m-matrix.h                                                    *
3  *                                                                         *
4  * UTIL C-source: Medical Image Conversion Utility                         *
5  *                                                                         *
6  * purpose      : m-matrix.c header file                                   *
7  *                                                                         *
8  * project      : (X)MedCon by Erik Nolf                                   *
9  *                                                                         *
10  * Notes        : Source code addapted from CTI PET Systems, Inc.          *
11  *                Original code 2.2 10/19/93  Copyright 1989-1993          *
12  *                                                                         *
13  *                Changed code for swapping & the use of my data types     *
14  *                with machine independency as purpose                     *
15  *                                                                         *
16  *                Added structs and prototypes for ECAT 7 reading support  *
17  *                                                                         *
18  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
19 /*
20  */
21 
22 /*
23    Copyright (C) 1997-2021 by Erik Nolf
24 
25    This program is free software; you can redistribute it and/or modify it
26    under the terms of the GNU General Public License as published by the
27    Free Software Foundation; either version 2, or (at your option) any later
28    version.
29 
30    This program is distributed in the hope that it will be useful, but
31    WITHOUT ANY WARRANTY; without even the implied warranty of
32    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
33    Public License for more details.
34 
35    You should have received a copy of the GNU General Public License along
36    with this program; if not, write to the Free Software Foundation, Inc.,
37    59 Place - Suite 330, Boston, MA 02111-1307, USA.  */
38 
39 #ifndef __M_MATRIX_H__
40 #define __M_MATRIX_H__
41 
42 /****************************************************************************
43   D E F I N E S
44  ****************************************************************************/
45 
46 #define MDC_ECAT6_MAX_MATRICES 5000
47 
48 #define MdcMatBLKSIZE     512
49 #define MdcMatFirstDirBlk 2
50 
51 #define MdcMatrixBlocks(x)   (((x+(MdcMatBLKSIZE-1))/MdcMatBLKSIZE)*MdcMatBLKSIZE);
52 
53 struct Mdc_MatDir {
54   Int32 matnum;
55   Int32 strtblk;
56   Int32 endblk;
57   Int32 matstat;
58 };
59 
60 typedef struct mdc_matdir {
61   Int32 nmats;
62   Int32 nmax;
63   struct Mdc_MatDir *entry;
64 } *Mdc_Mat_dir;
65 
66 struct Mdc_Matval {
67   Int32 frame, plane, gate, data, bed;
68 };
69 
70 /*
71 #define TotalCounts      0
72 #define UnknownCalib     TotalCounts + 1
73 #define MDC_ECAT_COUNTS  UnknownCalib + 1
74 #define MCi_ML           MDC_ECAT_COUNTS + 1
75 #define LmrGlu           MCi_ML + 1
76 #define LmrGlu_mMole     LmrGlu + 1
77 #define LmrGlu_mGram     LmrGlu_mMole + 1
78 #define NCi_ML           LmrGlu_mGram + 1
79 #define WELL_COUNTS      NCi_ML + 1
80 #define BECQUERELS       WELL_COUNTS + 1
81  */
82 
83 typedef struct mdc_mat_main_header {
84   char original_file_name[20];
85   Int16 sw_version;
86   Int16 data_type;
87   Int16 system_type;
88   Int16 file_type;
89   char node_id[10];
90   Int16 scan_start_day,
91         scan_start_month,
92         scan_start_year,
93         scan_start_hour,
94         scan_start_minute,
95         scan_start_second;
96   char isotope_code[8];
97   float isotope_halflife;
98   char radiopharmaceutical[32];
99   float gantry_tilt,
100         gantry_rotation,
101         bed_elevation;
102   Int16 rot_source_speed,
103         wobble_speed,
104         transm_source_type;
105   float axial_fov,
106         transaxial_fov;
107   Int16 transaxial_samp_mode,
108         coin_samp_mode,
109         axial_samp_mode;
110   float calibration_factor;
111   Int16 calibration_units,
112         compression_code;
113   char study_name[12],
114        patient_id[16],
115        patient_name[32],
116        patient_sex,
117        patient_age[10],
118        patient_height[10],
119        patient_weight[10],
120        patient_dexterity,
121        physician_name[32],
122        operator_name[32],
123        study_description[32];
124   Int16 acquisition_type,
125         bed_type,
126         septa_type;
127   char facility_name[20];
128   Int16 num_planes,
129         num_frames,
130         num_gates,
131         num_bed_pos;
132   float init_bed_position,
133         bed_offset[15],
134         plane_separation;
135   Int16 lwr_sctr_thres,
136         lwr_true_thres,
137         upr_true_thres;
138   float collimator;
139   char user_process_code[10];
140   Int16 acquisition_mode;
141 
142 } Mdc_Main_header;
143 
144 #define MH_64_SIZE 446
145 
146 typedef struct mdc_mat_main_header7 {
147 
148   char magic_number[14];
149   char original_file_name[32];
150   Int16 sw_version;
151   Int16 system_type;
152   Int16 file_type;
153   char serial_number[10];
154   Int32 scan_start_time;
155   char isotope_name[8];
156   float isotope_halflife;
157   char radiopharmaceutical[32];
158   float gantry_tilt;
159   float gantry_rotation;
160   float bed_elevation;
161   float intrinsic_tilt;
162   Int16 wobble_speed;
163   Int16 transm_source_type;
164   float distance_scanned;
165   float transaxial_fov;
166   Int16 angular_compression;
167   Int16 coin_samp_mode;
168   Int16 axial_samp_mode;
169   float ecat_calibration_factor;
170   Int16 calibration_units;
171   Int16 calibration_units_label;
172   Int16 compression_code;
173   char study_type[12];
174   char patient_id[16];
175   char patient_name[32];
176   char patient_sex[1];
177   char patient_dexterity[1];
178   float patient_age;
179   float patient_height;
180   float patient_weight;
181   Int32 patient_birth_date;
182   char physician_name[32];
183   char operator_name[32];
184   char study_description[32];
185   Int16 acquisition_type;
186   Int16 patient_orientation;
187   char facility_name[20];
188   Int16 num_planes;
189   Int16 num_frames;
190   Int16 num_gates;
191   Int16 num_bed_pos;
192   float init_bed_position;
193   float bed_position[15];
194   float plane_separation;
195   Int16 lwr_sctr_thres;
196   Int16 lwr_true_thres;
197   Int16 upr_true_thres;
198   char user_process_code[10];
199   Int16 acquisition_mode;
200   float bin_size;
201   float branching_fraction;
202   Uint32 dose_start_time;
203   float dosage;
204   float well_counter_corr_factor;
205   char data_units[32];
206   Int16 septa_state;
207   Int16 fill_cti[6];
208 
209 } Mdc_Main_header7;
210 
211 #define MH_72_SIZE       512
212 
213 typedef struct mdc_mat_scan_subheader {
214   Int16 data_type,
215         dimension_1,
216         dimension_2,
217         smoothing,
218         processing_code;
219   float sample_distance,
220         isotope_halflife;
221   Int16 frame_duration_sec;
222   Int32 gate_duration,
223         r_wave_offset;
224   float scale_factor;
225   Int16 scan_min,
226         scan_max;
227   Int32 prompts,
228         delayed,
229         multiples,
230         net_trues;
231   float cor_singles[16],
232         uncor_singles[16],
233         tot_avg_cor,
234         tot_avg_uncor;
235   Int32 total_coin_rate,
236         frame_start_time,
237         frame_duration;
238   float loss_correction_fctr;
239   Int32 phy_planes[8];
240 
241 } Mdc_Scan_subheader;
242 
243 #define SSH_64_SIZE 236
244 
245 typedef struct mdc_mat_scan_subheader7 {
246 
247   Int16 data_type;
248   Int16 num_dimensions;
249   Int16 num_r_elements;
250   Int16 num_angles;
251   Int16 corrections_applied;
252   Int16 num_z_elements;
253   Int16 ring_difference;
254   float x_resolution;
255   float y_resolution;
256   float z_resolution;
257   float w_resolution;
258   Int16 fill[6];
259   Uint32 gate_duration;
260   Int32 r_wave_offset;
261   Int32 num_accepted_beats;
262   float scale_factor;
263   Int16 scan_min;
264   Int16 scan_max;
265   Int32 prompts;
266   Int32 delayed;
267   Int32 multiples;
268   Int32 net_trues;
269   float cor_singles[16];
270   float uncor_singles[16];
271   float tot_avg_cor;
272   float tot_avg_uncor;
273   Int32 total_coin_rate;
274   Uint32 frame_start_time;
275   Uint32 frame_duration;
276   float deadtime_correction_factor;
277   Int16 phy_planes[8];
278   Int16 cti_fill[83];
279   Int16 user_fill[50];
280 
281 } Mdc_Scan_subheader7;
282 
283 #define SSH_72_SIZE   234
284 
285 typedef struct mdc_mat_image_subheader {
286   Int16 data_type,
287         num_dimensions,
288         dimension_1,
289         dimension_2;
290   float x_origin,
291         y_origin,
292         recon_scale,  /* Image ZOOM from reconstruction */
293         quant_scale;  /* Scale Factor */
294   Int16 image_min,
295         image_max;
296   float pixel_size,
297         slice_width;
298   Int32 frame_duration,
299         frame_start_time;
300   Int16 slice_location,
301         recon_start_hour,
302         recon_start_minute,
303         recon_start_sec;
304   Int32 gate_duration;
305   Int16 filter_code;
306   Int32 scan_matrix_num,
307         norm_matrix_num,
308         atten_cor_matrix_num;
309   float image_rotation,
310         plane_eff_corr_fctr,
311         decay_corr_fctr,
312         loss_corr_fctr,
313         intrinsic_tilt ;
314   Int16 processing_code,
315         quant_units,
316         recon_start_day,
317         recon_start_month,
318         recon_start_year;
319   float ecat_calibration_fctr,
320         well_counter_cal_fctr,
321         filter_params[6];
322   char annotation[40];
323 
324 } Mdc_Image_subheader;
325 
326 #define ISH_64_SIZE 172
327 
328 typedef struct mdc_mat_image_subheader7 {
329 
330   Int16 data_type;
331   Int16 num_dimensions;
332   Int16 x_dimension;
333   Int16 y_dimension;
334   Int16 z_dimension;
335   float x_offset;
336   float y_offset;
337   float z_offset;
338   float recon_zoom;
339   float scale_factor;
340   Int16 image_min;
341   Int16 image_max;
342   float x_pixel_size;
343   float y_pixel_size;
344   float z_pixel_size;
345   Uint32 frame_duration;
346   Uint32 frame_start_time;
347   Int16 filter_code;
348   float x_resolution;
349   float y_resolution;
350   float z_resolution;
351   float num_r_elements;
352   float num_angles;
353   float z_rotation_angle;
354   float decay_corr_fctr;
355   Int32 processing_code;
356   Uint32 gate_duration;
357   Int32 r_wave_offset;
358   Int32 num_accepted_beats;
359   float filter_cutoff_frequency;
360   float filter_resolution;
361   float filter_ramp_slope;
362   Int16 filter_order;
363   float filter_scatter_fraction;
364   float filter_scatter_slope;
365   char annotation[40];
366   float mt_1_1;
367   float mt_1_2;
368   float mt_1_3;
369   float mt_2_1;
370   float mt_2_2;
371   float mt_2_3;
372   float mt_3_1;
373   float mt_3_2;
374   float mt_3_3;
375   float rfilter_cutoff;
376   float rfilter_resolution;
377   Int16 rfilter_code;
378   Int16 rfilter_order;
379   float zfilter_cutoff;
380   float zfilter_resolution;
381   Int16 zfilter_code;
382   Int16 zfilter_order;
383   float mt_1_4;
384   float mt_2_4;
385   float mt_3_4;
386   Int16 scatter_type;
387   Int16 recon_type;
388   Int16 recon_views;
389   Int16 fill_cti[87];
390   Int16 fill_user[48];
391 
392 } Mdc_Image_subheader7;
393 
394 #define ISH_72_SIZE  510
395 
396 typedef struct mdc_mat_norm_subheader {
397   Int16 data_type,
398         dimension_1,
399         dimension_2;
400   float scale_factor;
401   Int16 norm_hour,
402         norm_minute,
403         norm_second,
404         norm_day,
405         norm_month,
406         norm_year;
407   float fov_source_width;
408   float ecat_calib_factor;
409 
410 } Mdc_Norm_subheader;
411 
412 #define NSH_64_SIZE 30
413 
414 typedef struct mdc_mat_norm_subheader7 {
415 
416   Int16 data_type;
417   Int16 num_dimensions;
418   Int16 num_r_elements;
419   Int16 num_angles;
420   Int16 num_z_elements;
421   Int16 ring_difference;
422   float scale_factor;
423   float norm_min;
424   float norm_max;
425   float fov_source_width;
426   float norm_quality_factor;
427   Int16 norm_quality_factor_code;
428   Int16 storage_order;
429   Int16 span;
430   Int16 z_elements[64];
431   Int16 cti_fill[123];
432   Int16 user_fill[50];
433 
434 } Mdc_Norm_subheader7;
435 
436 #define NSH_72_SIZE   166
437 
438 typedef struct mdc_mat_attn_subheader {
439   Int16 data_type,
440         attenuation_type,
441         dimension_1,
442         dimension_2;
443   float scale_factor,
444         x_origin,
445         y_origin,
446         x_radius,
447         y_radius,
448         tilt_angle,
449         attenuation_coeff,
450         sample_distance;
451 
452 } Mdc_Attn_subheader;
453 
454 #define ASH_64_SIZE 40
455 
456 typedef struct mdc_mat_attn_subheader7 {
457 
458   Int16 data_type;
459   Int16 num_dimensions;
460   Int16 attenuation_type;
461   Int16 num_r_elements;
462   Int16 num_angles;
463   Int16 num_z_elements;
464   Int16 ring_difference;
465   float x_resolution;
466   float y_resolution;
467   float z_resolution;
468   float w_resolution;
469   float scale_factor;
470   float x_offset;
471   float y_offset;
472   float x_radius;
473   float y_radius;
474   float tilt_angle;
475   float attenuation_coeff;
476   float attenuation_min;
477   float attenuation_max;
478   float skull_thickness;
479   Int16 num_xtra_atten_coeff;
480   float xtra_atten_coeff[8];
481   float edge_finding_threshold;
482   Int16 storage_order;
483   Int16 span;
484   Int16 z_elements[64];
485   Int16 fill_unused[86];
486   Int16 fill_user[50];
487 
488 } Mdc_Attn_subheader7;
489 
490 #define ASH_72_SIZE   512
491 
492 typedef struct mdc_matdirnode {
493   Int32 matnum;
494   Int32 strtblk;
495   Int32 endblk;
496   Int32 matstat;
497   struct mdc_matdirnode *next;
498 } Mdc_MatDirNode;
499 
500 typedef struct mdc_matdirlist {
501   Int32 nmats;
502   Mdc_MatDirNode *first;
503   Mdc_MatDirNode *last;
504 } Mdc_MatDirList;
505 
506 typedef struct mdc_matrixdata {
507   Int32 mat_type;
508   Int32 matnum;
509   Uint8 *shptr;
510   Uint8 *data_ptr;
511   Int32 nviews;
512   Int32 nelements;
513   Int32 nblks;
514   Int32 data_type;
515 } Mdc_MatrixData;
516 
517 typedef struct mdc_matrix_file {
518   Mdc_Main_header *mhptr;
519   Mdc_MatDirList  *dirlist;
520   FILE        *fptr;
521   Int32       mode;
522   char        *fname[80];
523 } Mdc_MatrixFile;
524 
525 typedef struct mdc_matdirblk {
526   Int32 nfree, nextblk, prvblk, nused;
527   struct Mdc_MatDir matdir[31];
528 } Mdc_MatDirBlk;
529 
530 #define BYTE_TYPE       1
531 #define VAX_I2          2
532 #define VAX_I4          3
533 #define VAX_R4          4
534 #define IEEE_R4         5
535 #define M68K_I2         6
536 #define M68K_I4         7
537 #define SUN_I2  M68K_I2
538 #define SUN_I4  M68K_I4
539 #define SUN_R4  IEEE_R4
540 
541 #define RAW_DATA        1
542 #define IMAGE_DATA      2
543 #define ATTN_DATA       3
544 #define NORM_DATA       4
545 #define SUN_READ        1
546 #define SUN_WRITE       2
547 #define ACS_READ        3
548 #define ACS_WRITE       4
549 #define SUN_CREATE      5
550 
551 #define ACQM_NORMAL      0  /* normal acquisition mode */
552 #define ACQM_RODTRN      1  /* rod transmission mode */
553 #define ACQM_RODTRN_KEEP 2  /* rod transmission mode keep all sinograms */
554 #define ACQM_DWIN_KEEP   3  /* dual window mode keep all sinograms */
555 #define ACQM_DWIN        4  /* dual window mode */
556 #define ACQM_SIMULT      5  /* simultaneous transmission/ emission mode */
557 
558 /* eNlf: BEGIN - unnecessary, avoid conflicts! */
559 /* #define ERROR   -1                          */
560 /* #define OK 0                                */
561 /* eNlf: END   - unnecessary, avoid conflicts! */
562 
563 /****************************************************************************
564   F U N C T I O N S
565  ****************************************************************************/
566 Int32 MdcSWAW( Uint16 from[], Uint16 to[], Int32 length);
567 Int32 MdcSWAB( Uint8  from[], Uint8  to[], Int32 length);
568 FILE *mdc_mat_open(char *fname, char *fmode);
569 void mdc_mat_close(FILE *fptr);
570 Int32 mdc_mat_rblk(FILE *fptr, Int32 blkno, Uint8 *bufr, Int32 nblks);
571 Int32 mdc_mat_list(FILE *fptr, struct Mdc_MatDir mlist[], Int32 lmax);
572 Int32 mdc_mat_list7(FILE *fptr, struct Mdc_MatDir mlist[], Int32 lmax);
573 Int32 mdc_mat_numcod(Int32 frame, Int32 plane, Int32 gate, Int32 data, Int32 bed);
574 Int32 mdc_mat_numdoc( Int32 mdc_matnum, struct Mdc_Matval *matval);
575 Int32 mdc_mat_lookup(FILE *fptr, Int32 matnum, struct Mdc_MatDir *entry);
576 Int32 mdc_mat_lookup7(FILE *fptr, Int32 matnum, struct Mdc_MatDir *entry);
577 Int32 mdc_mat_read_main_header(FILE *fptr, Mdc_Main_header *h);
578 Int32 mdc_mat_read_main_header7(FILE *fptr, Mdc_Main_header7 *h);
579 Int32 mdc_mat_read_matrix_data(FILE *fptr, Int32 blk, Int32 nblks, Int16 bufr[]);
580 Int32 mdc_mat_read_mat_data(FILE *fptr, Int32 strtblk, Int32 nblks, Uint8 *dptr, Int32 dtype);
581 Int32 mdc_mat_read_mat_data7(FILE *fptr, Int32 strtblk, Int32 nblks, Uint8 *dptr, Int32 dtype);
582 Int32 mdc_mat_read_scan_subheader(FILE *fptr, Int32 blknum, Mdc_Scan_subheader *h);
583 Int32 mdc_mat_read_scan_subheader7(FILE *fptr, Int32 blknum, Mdc_Scan_subheader7 *h);
584 Int32 mdc_mat_read_image_subheader(FILE *fptr, Int32 blknum, Mdc_Image_subheader *h);
585 Int32 mdc_mat_read_image_subheader7(FILE *fptr, Int32 blknum, Mdc_Image_subheader7 *h);
586 float mdc_get_vax_float(Uint16 bufr[], Int32 off);
587 Int32 mdc_get_vax_long(Uint16 bufr[], Int32 off);
588 Mdc_Mat_dir mdc_mat_read_dir(FILE *fptr, Uint8 *selector);
589 Int32 mdc_mat_wblk(FILE *fptr, Int32 blkno, Uint8 *bufr, Int32 nblks);
590 FILE *mdc_mat_create(char *fname, Mdc_Main_header *mhead);
591 Int32 mdc_mat_enter(FILE *fptr, Int32 matnum, Int32 nblks);
592 Int32 mdc_mat_write_image(FILE *fptr, Int32 matnum, Mdc_Image_subheader *header, Uint16 *data, Int32 data_size);
593 Int32 mdc_mat_write_scan(FILE *fptr, Int32 matnum, Mdc_Scan_subheader *header, Uint16 *data, Int32 data_size);
594 Int32 mdc_mat_write_attn(FILE *fptr, Int32 matnum, Mdc_Attn_subheader *header, float *data, Int32 data_size);
595 Int32 mdc_mat_write_norm(FILE *fptr, Int32 matnum, Mdc_Norm_subheader *header, float *data, Int32 data_size);
596 Int32 mdc_mat_write_idata(FILE *fptr, Int32 blk, Uint8 *data, Int32 size);
597 Int32 mdc_mat_write_fdata(FILE *fptr, Int32 blk, float *data, Int32 size);
598 Int32 mdc_matrix_selector(Int32 matnum, Int32 ranges[2][5]);
599 Int32 mdc_decode_selector(char *s1, Int32 ranges[2][5]);
600 Int32 mdc_str_find(char *s1, char *s2);
601 Int32 mdc_str_replace(char *s1, char *s2, char *s3, char *s4);
602 Int32 mdc_string_replace(char *s1, char *s2, char *s3, char *s4);
603 Int32 mdc_fix_selector(char *s1, char *s2);
604 char* mdc_nex_word(char *s, char *w);
605 Int32 mdc_hostftovaxf(float f_orig, Uint16 number[]);
606 Int32 mdc_mat_write_main_header(FILE *fptr, Mdc_Main_header *header);
607 Int32 mdc_mat_write_image_subheader(FILE *fptr, Int32 blknum, Mdc_Image_subheader *header);
608 Int32 mdc_hostltovaxl(Int32 in, Uint16 out[2]);
609 Int32 mdc_mat_write_scan_subheader(FILE *fptr, Int32 blknum, Mdc_Scan_subheader *header);
610 Int32 mdc_mat_write_attn_subheader(FILE *fptr, Int32 blknum, Mdc_Attn_subheader *header);
611 Int32 mdc_mat_write_norm_subheader(FILE *fptr, Int32 blknum, Mdc_Norm_subheader *header);
612 Int32 mdc_mat_read_attn_subheader(FILE *fptr, Int32 blknum, Mdc_Attn_subheader *header);
613 Int32 mdc_mat_read_attn_subheader7(FILE *fptr, Int32 blknum, Mdc_Attn_subheader7 *h);
614 Int32 mdc_mat_read_norm_subheader(FILE *fptr, Int32 blknum, Mdc_Norm_subheader *header);
615 Int32 mdc_mat_read_norm_subheader7(FILE *fptr, Int32 blknum, Mdc_Norm_subheader7 *header);
616 Int32 mdc_write_matrix_data(FILE *fptr, Int32 strtblk, Int32 nblks, Uint8 *dptr, Int32 dtype);
617 double  mdc_mat_qs(double *X, double *Z, Int32 lod);
618 double  mdc_mat_max(double *X, Int32 lod);
619 double  mdc_mat_min(double *X, Int32 lod);
620 Int32 mdc_mat_get_spec (char *file, Int32 *num_frames, Int32 *num_planes, Int32 *num_gates, Int32 *num_bed);
621 void mdc_anatomical_sort (struct Mdc_MatDir matrix_list[], Int32 num_matrices, Mdc_Main_header *mhead, Int32 num_bed_pos);
622 void mdc_matnum_sort(struct Mdc_MatDir mlist[], Int32 num_entry);
623 void mdc_plane_sort (struct Mdc_MatDir matrix_list[], Int32 num_matrices);
624 
625 #endif
626 
627