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