/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * filename: m-matrix.h * * * * UTIL C-source: Medical Image Conversion Utility * * * * purpose : m-matrix.c header file * * * * project : (X)MedCon by Erik Nolf * * * * Notes : Source code addapted from CTI PET Systems, Inc. * * Original code 2.2 10/19/93 Copyright 1989-1993 * * * * Changed code for swapping & the use of my data types * * with machine independency as purpose * * * * Added structs and prototypes for ECAT 7 reading support * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* $Id: m-matrix.h,v 1.19 2007/06/18 20:46:17 enlf Exp $ */ /* Copyright (C) 1997-2007 by Erik Nolf This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __M_MATRIX_H__ #define __M_MATRIX_H__ /**************************************************************************** D E F I N E S ****************************************************************************/ #define MDC_ECAT6_MAX_MATRICES 5000 #define MdcMatBLKSIZE 512 #define MdcMatFirstDirBlk 2 #define MdcMatrixBlocks(x) (((x+(MdcMatBLKSIZE-1))/MdcMatBLKSIZE)*MdcMatBLKSIZE); struct Mdc_MatDir { Int32 matnum; Int32 strtblk; Int32 endblk; Int32 matstat; }; typedef struct mdc_matdir { Int32 nmats; Int32 nmax; struct Mdc_MatDir *entry; } *Mdc_Mat_dir; struct Mdc_Matval { Int32 frame, plane, gate, data, bed; }; /* #define TotalCounts 0 #define UnknownCalib TotalCounts + 1 #define MDC_ECAT_COUNTS UnknownCalib + 1 #define MCi_ML MDC_ECAT_COUNTS + 1 #define LmrGlu MCi_ML + 1 #define LmrGlu_mMole LmrGlu + 1 #define LmrGlu_mGram LmrGlu_mMole + 1 #define NCi_ML LmrGlu_mGram + 1 #define WELL_COUNTS NCi_ML + 1 #define BECQUERELS WELL_COUNTS + 1 */ typedef struct mdc_mat_main_header { char original_file_name[20]; Int16 sw_version; Int16 data_type; Int16 system_type; Int16 file_type; char node_id[10]; Int16 scan_start_day, scan_start_month, scan_start_year, scan_start_hour, scan_start_minute, scan_start_second; char isotope_code[8]; float isotope_halflife; char radiopharmaceutical[32]; float gantry_tilt, gantry_rotation, bed_elevation; Int16 rot_source_speed, wobble_speed, transm_source_type; float axial_fov, transaxial_fov; Int16 transaxial_samp_mode, coin_samp_mode, axial_samp_mode; float calibration_factor; Int16 calibration_units, compression_code; char study_name[12], patient_id[16], patient_name[32], patient_sex, patient_age[10], patient_height[10], patient_weight[10], patient_dexterity, physician_name[32], operator_name[32], study_description[32]; Int16 acquisition_type, bed_type, septa_type; char facility_name[20]; Int16 num_planes, num_frames, num_gates, num_bed_pos; float init_bed_position, bed_offset[15], plane_separation; Int16 lwr_sctr_thres, lwr_true_thres, upr_true_thres; float collimator; char user_process_code[10]; Int16 acquisition_mode; } Mdc_Main_header; #define MH_64_SIZE 446 typedef struct mdc_mat_main_header7 { char magic_number[14]; char original_file_name[32]; Int16 sw_version; Int16 system_type; Int16 file_type; char serial_number[10]; Uint32 scan_start_time; char isotope_name[8]; float isotope_halflife; char radiopharmaceutical[32]; float gantry_tilt; float gantry_rotation; float bed_elevation; float intrinsic_tilt; Int16 wobble_speed; Int16 transm_source_type; float distance_scanned; float transaxial_fov; Int16 angular_compression; Int16 coin_samp_mode; Int16 axial_samp_mode; float ecat_calibration_factor; Int16 calibration_units; Int16 calibration_units_label; Int16 compression_code; char study_type[12]; char patient_id[16]; char patient_name[32]; char patient_sex[1]; char patient_dexterity[1]; float patient_age; float patient_height; float patient_weight; Uint32 patient_birth_date; char physician_name[32]; char operator_name[32]; char study_description[32]; Int16 acquisition_type; Int16 patient_orientation; char facility_name[20]; Int16 num_planes; Int16 num_frames; Int16 num_gates; Int16 num_bed_pos; float init_bed_position; float bed_position[15]; float plane_separation; Int16 lwr_sctr_thres; Int16 lwr_true_thres; Int16 upr_true_thres; char user_process_code[10]; Int16 acquisition_mode; float bin_size; float branching_fraction; Uint32 dose_start_time; float dosage; float well_counter_corr_factor; char data_units[32]; Int16 septa_state; Int16 fill_cti[6]; } Mdc_Main_header7; #define MH_72_SIZE 512 typedef struct mdc_mat_scan_subheader { Int16 data_type, dimension_1, dimension_2, smoothing, processing_code; float sample_distance, isotope_halflife; Int16 frame_duration_sec; Int32 gate_duration, r_wave_offset; float scale_factor; Int16 scan_min, scan_max; Int32 prompts, delayed, multiples, net_trues; float cor_singles[16], uncor_singles[16], tot_avg_cor, tot_avg_uncor; Int32 total_coin_rate, frame_start_time, frame_duration; float loss_correction_fctr; Int32 phy_planes[8]; } Mdc_Scan_subheader; #define SSH_64_SIZE 236 typedef struct mdc_mat_scan_subheader7 { Int16 data_type; Int16 num_dimensions; Int16 num_r_elements; Int16 num_angles; Int16 corrections_applied; Int16 num_z_elements; Int16 ring_difference; float x_resolution; float y_resolution; float z_resolution; float w_resolution; Int16 fill[6]; Uint32 gate_duration; Int32 r_wave_offset; Int32 num_accepted_beats; float scale_factor; Int16 scan_min; Int16 scan_max; Int32 prompts; Int32 delayed; Int32 multiples; Int32 net_trues; float cor_singles[16]; float uncor_singles[16]; float tot_avg_cor; float tot_avg_uncor; Int32 total_coin_rate; Uint32 frame_start_time; Uint32 frame_duration; float deadtime_correction_factor; Int16 phy_planes[8]; Int16 cti_fill[83]; Int16 user_fill[50]; } Mdc_Scan_subheader7; #define SSH_72_SIZE 234 typedef struct mdc_mat_image_subheader { Int16 data_type, num_dimensions, dimension_1, dimension_2; float x_origin, y_origin, recon_scale, /* Image ZOOM from reconstruction */ quant_scale; /* Scale Factor */ Int16 image_min, image_max; float pixel_size, slice_width; Int32 frame_duration, frame_start_time; Int16 slice_location, recon_start_hour, recon_start_minute, recon_start_sec; Int32 gate_duration; Int16 filter_code; Int32 scan_matrix_num, norm_matrix_num, atten_cor_matrix_num; float image_rotation, plane_eff_corr_fctr, decay_corr_fctr, loss_corr_fctr, intrinsic_tilt ; Int16 processing_code, quant_units, recon_start_day, recon_start_month, recon_start_year; float ecat_calibration_fctr, well_counter_cal_fctr, filter_params[6]; char annotation[40]; } Mdc_Image_subheader; #define ISH_64_SIZE 172 typedef struct mdc_mat_image_subheader7 { Int16 data_type; Int16 num_dimensions; Int16 x_dimension; Int16 y_dimension; Int16 z_dimension; float x_offset; float y_offset; float z_offset; float recon_zoom; float scale_factor; Int16 image_min; Int16 image_max; float x_pixel_size; float y_pixel_size; float z_pixel_size; Uint32 frame_duration; Uint32 frame_start_time; Int16 filter_code; float x_resolution; float y_resolution; float z_resolution; float num_r_elements; float num_angles; float z_rotation_angle; float decay_corr_fctr; Int32 processing_code; Uint32 gate_duration; Int32 r_wave_offset; Int32 num_accepted_beats; float filter_cutoff_frequency; float filter_resolution; float filter_ramp_slope; Int16 filter_order; float filter_scatter_fraction; float filter_scatter_slope; char annotation[40]; float mt_1_1; float mt_1_2; float mt_1_3; float mt_2_1; float mt_2_2; float mt_2_3; float mt_3_1; float mt_3_2; float mt_3_3; float rfilter_cutoff; float rfilter_resolution; Int16 rfilter_code; Int16 rfilter_order; float zfilter_cutoff; float zfilter_resolution; Int16 zfilter_code; Int16 zfilter_order; float mt_1_4; float mt_2_4; float mt_3_4; Int16 scatter_type; Int16 recon_type; Int16 recon_views; Int16 fill_cti[87]; Int16 fill_user[48]; } Mdc_Image_subheader7; #define ISH_72_SIZE 510 typedef struct mdc_mat_norm_subheader { Int16 data_type, dimension_1, dimension_2; float scale_factor; Int16 norm_hour, norm_minute, norm_second, norm_day, norm_month, norm_year; float fov_source_width; float ecat_calib_factor; } Mdc_Norm_subheader; #define NSH_64_SIZE 30 typedef struct mdc_mat_norm_subheader7 { Int16 data_type; Int16 num_dimensions; Int16 num_r_elements; Int16 num_angles; Int16 num_z_elements; Int16 ring_difference; float scale_factor; float norm_min; float norm_max; float fov_source_width; float norm_quality_factor; Int16 norm_quality_factor_code; Int16 storage_order; Int16 span; Int16 z_elements[64]; Int16 cti_fill[123]; Int16 user_fill[50]; } Mdc_Norm_subheader7; #define NSH_72_SIZE 166 typedef struct mdc_mat_attn_subheader { Int16 data_type, attenuation_type, dimension_1, dimension_2; float scale_factor, x_origin, y_origin, x_radius, y_radius, tilt_angle, attenuation_coeff, sample_distance; } Mdc_Attn_subheader; #define ASH_64_SIZE 40 typedef struct mdc_mat_attn_subheader7 { Int16 data_type; Int16 num_dimensions; Int16 attenuation_type; Int16 num_r_elements; Int16 num_angles; Int16 num_z_elements; Int16 ring_difference; float x_resolution; float y_resolution; float z_resolution; float w_resolution; float scale_factor; float x_offset; float y_offset; float x_radius; float y_radius; float tilt_angle; float attenuation_coeff; float attenuation_min; float attenuation_max; float skull_thickness; Int16 num_xtra_atten_coeff; float xtra_atten_coeff[8]; float edge_finding_threshold; Int16 storage_order; Int16 span; Int16 z_elements[64]; Int16 fill_unused[86]; Int16 fill_user[50]; } Mdc_Attn_subheader7; #define ASH_72_SIZE 512 typedef struct mdc_matdirnode { Int32 matnum; Int32 strtblk; Int32 endblk; Int32 matstat; struct mdc_matdirnode *next; } Mdc_MatDirNode; typedef struct mdc_matdirlist { Int32 nmats; Mdc_MatDirNode *first; Mdc_MatDirNode *last; } Mdc_MatDirList; typedef struct mdc_matrixdata { Int32 mat_type; Int32 matnum; Uint8 *shptr; Uint8 *data_ptr; Int32 nviews; Int32 nelements; Int32 nblks; Int32 data_type; } Mdc_MatrixData; typedef struct mdc_matrix_file { Mdc_Main_header *mhptr; Mdc_MatDirList *dirlist; FILE *fptr; Int32 mode; char *fname[80]; } Mdc_MatrixFile; typedef struct mdc_matdirblk { Int32 nfree, nextblk, prvblk, nused; struct Mdc_MatDir matdir[31]; } Mdc_MatDirBlk; #define BYTE_TYPE 1 #define VAX_I2 2 #define VAX_I4 3 #define VAX_R4 4 #define IEEE_R4 5 #define M68K_I2 6 #define M68K_I4 7 #define SUN_I2 M68K_I2 #define SUN_I4 M68K_I4 #define SUN_R4 IEEE_R4 #define RAW_DATA 1 #define IMAGE_DATA 2 #define ATTN_DATA 3 #define NORM_DATA 4 #define SUN_READ 1 #define SUN_WRITE 2 #define ACS_READ 3 #define ACS_WRITE 4 #define SUN_CREATE 5 #define ACQM_NORMAL 0 /* normal acquisition mode */ #define ACQM_RODTRN 1 /* rod transmission mode */ #define ACQM_RODTRN_KEEP 2 /* rod transmission mode keep all sinograms */ #define ACQM_DWIN_KEEP 3 /* dual window mode keep all sinograms */ #define ACQM_DWIN 4 /* dual window mode */ #define ACQM_SIMULT 5 /* simultaneous transmission/ emission mode */ /* eNlf: BEGIN - unnecessary, avoid conflicts! */ /* #define ERROR -1 */ /* #define OK 0 */ /* eNlf: END - unnecessary, avoid conflicts! */ /**************************************************************************** F U N C T I O N S ****************************************************************************/ Int32 MdcSWAW( Uint16 from[], Uint16 to[], Int32 length); Int32 MdcSWAB( Uint8 from[], Uint8 to[], Int32 length); FILE *mdc_mat_open(char *fname, char *fmode); void mdc_mat_close(FILE *fptr); Int32 mdc_mat_rblk(FILE *fptr, Int32 blkno, Uint8 *bufr, Int32 nblks); Int32 mdc_mat_list(FILE *fptr, struct Mdc_MatDir mlist[], Int32 lmax); Int32 mdc_mat_list7(FILE *fptr, struct Mdc_MatDir mlist[], Int32 lmax); Int32 mdc_mat_numcod(Int32 frame, Int32 plane, Int32 gate, Int32 data, Int32 bed); Int32 mdc_mat_numdoc( Int32 mdc_matnum, struct Mdc_Matval *matval); Int32 mdc_mat_lookup(FILE *fptr, Int32 matnum, struct Mdc_MatDir *entry); Int32 mdc_mat_lookup7(FILE *fptr, Int32 matnum, struct Mdc_MatDir *entry); Int32 mdc_mat_read_main_header(FILE *fptr, Mdc_Main_header *h); Int32 mdc_mat_read_main_header7(FILE *fptr, Mdc_Main_header7 *h); Int32 mdc_mat_read_matrix_data(FILE *fptr, Int32 blk, Int32 nblks, Int16 bufr[]); Int32 mdc_mat_read_mat_data(FILE *fptr, Int32 strtblk, Int32 nblks, Uint8 *dptr, Int32 dtype); Int32 mdc_mat_read_mat_data7(FILE *fptr, Int32 strtblk, Int32 nblks, Uint8 *dptr, Int32 dtype); Int32 mdc_mat_read_scan_subheader(FILE *fptr, Int32 blknum, Mdc_Scan_subheader *h); Int32 mdc_mat_read_scan_subheader7(FILE *fptr, Int32 blknum, Mdc_Scan_subheader7 *h); Int32 mdc_mat_read_image_subheader(FILE *fptr, Int32 blknum, Mdc_Image_subheader *h); Int32 mdc_mat_read_image_subheader7(FILE *fptr, Int32 blknum, Mdc_Image_subheader7 *h); float mdc_get_vax_float(Uint16 bufr[], Int32 off); Int32 mdc_get_vax_long(Uint16 bufr[], Int32 off); Mdc_Mat_dir mdc_mat_read_dir(FILE *fptr, Uint8 *selector); Int32 mdc_mat_wblk(FILE *fptr, Int32 blkno, Uint8 *bufr, Int32 nblks); FILE *mdc_mat_create(char *fname, Mdc_Main_header *mhead); Int32 mdc_mat_enter(FILE *fptr, Int32 matnum, Int32 nblks); Int32 mdc_mat_write_image(FILE *fptr, Int32 matnum, Mdc_Image_subheader *header, Uint16 *data, Int32 data_size); Int32 mdc_mat_write_scan(FILE *fptr, Int32 matnum, Mdc_Scan_subheader *header, Uint16 *data, Int32 data_size); Int32 mdc_mat_write_attn(FILE *fptr, Int32 matnum, Mdc_Attn_subheader *header, float *data, Int32 data_size); Int32 mdc_mat_write_norm(FILE *fptr, Int32 matnum, Mdc_Norm_subheader *header, float *data, Int32 data_size); Int32 mdc_mat_write_idata(FILE *fptr, Int32 blk, Uint8 *data, Int32 size); Int32 mdc_mat_write_fdata(FILE *fptr, Int32 blk, float *data, Int32 size); Int32 mdc_matrix_selector(Int32 matnum, Int32 ranges[2][5]); Int32 mdc_decode_selector(char *s1, Int32 ranges[2][5]); Int32 mdc_str_find(char *s1, char *s2); Int32 mdc_str_replace(char *s1, char *s2, char *s3, char *s4); Int32 mdc_string_replace(char *s1, char *s2, char *s3, char *s4); Int32 mdc_fix_selector(char *s1, char *s2); char* mdc_nex_word(char *s, char *w); Int32 mdc_hostftovaxf(float f_orig, Uint16 number[]); Int32 mdc_mat_write_main_header(FILE *fptr, Mdc_Main_header *header); Int32 mdc_mat_write_image_subheader(FILE *fptr, Int32 blknum, Mdc_Image_subheader *header); Int32 mdc_hostltovaxl(Int32 in, Uint16 out[2]); Int32 mdc_mat_write_scan_subheader(FILE *fptr, Int32 blknum, Mdc_Scan_subheader *header); Int32 mdc_mat_write_attn_subheader(FILE *fptr, Int32 blknum, Mdc_Attn_subheader *header); Int32 mdc_mat_write_norm_subheader(FILE *fptr, Int32 blknum, Mdc_Norm_subheader *header); Int32 mdc_mat_read_attn_subheader(FILE *fptr, Int32 blknum, Mdc_Attn_subheader *header); Int32 mdc_mat_read_attn_subheader7(FILE *fptr, Int32 blknum, Mdc_Attn_subheader7 *h); Int32 mdc_mat_read_norm_subheader(FILE *fptr, Int32 blknum, Mdc_Norm_subheader *header); Int32 mdc_mat_read_norm_subheader7(FILE *fptr, Int32 blknum, Mdc_Norm_subheader7 *header); Int32 mdc_write_matrix_data(FILE *fptr, Int32 strtblk, Int32 nblks, Uint8 *dptr, Int32 dtype); double mdc_mat_qs(double *X, double *Z, Int32 lod); double mdc_mat_max(double *X, Int32 lod); double mdc_mat_min(double *X, Int32 lod); Int32 mdc_mat_get_spec (char *file, Int32 *num_frames, Int32 *num_planes, Int32 *num_gates, Int32 *num_bed); void mdc_anatomical_sort (struct Mdc_MatDir matrix_list[], Int32 num_matrices, Mdc_Main_header *mhead, Int32 num_bed_pos); void mdc_matnum_sort(struct Mdc_MatDir mlist[], Int32 num_entry); void mdc_plane_sort (struct Mdc_MatDir matrix_list[], Int32 num_matrices); #endif