TPCCLIB
Loading...
Searching...
No Matches
ecat7w.c File Reference

Functions for writing ECAT 7.x format. More...

#include "libtpcimgio.h"

Go to the source code of this file.

Functions

int ecat7WriteMainheader (FILE *fp, ECAT7_mainheader *h)
int ecat7WriteImageheader (FILE *fp, int blk, ECAT7_imageheader *h)
int ecat7WriteAttenheader (FILE *fp, int blk, ECAT7_attenheader *h)
int ecat7WritePolmapheader (FILE *fp, int blk, ECAT7_polmapheader *h)
int ecat7WriteNormheader (FILE *fp, int blk, ECAT7_normheader *h)
int ecat7WriteScanheader (FILE *fp, int blk, ECAT7_scanheader *h)
int ecat7Write2DScanheader (FILE *fp, int blk, ECAT7_2Dscanheader *h)
int ecat7Write2DNormheader (FILE *fp, int blk, ECAT7_2Dnormheader *h)
FILE * ecat7Create (const char *fname, ECAT7_mainheader *h)
int ecat7_is_scaling_needed (float amax, float *data, long long nr)
int ecat7WriteImageMatrix (FILE *fp, int matrix_id, ECAT7_imageheader *h, float *fdata)
int ecat7Write2DScanMatrix (FILE *fp, int matrix_id, ECAT7_2Dscanheader *h, float *fdata)
int ecat7WriteScanMatrix (FILE *fp, int matrix_id, ECAT7_scanheader *h, float *fdata)
int ecat7WritePolarmapMatrix (FILE *fp, int matrix_id, ECAT7_polmapheader *h, float *fdata)
int ecat7WriteMatrixdata (FILE *fp, int start_block, char *data, long long pxl_nr, int pxl_size)

Detailed Description

Functions for writing ECAT 7.x format.

Author
Vesa Oikonen

Definition in file ecat7w.c.

Function Documentation

◆ ecat7_is_scaling_needed()

int ecat7_is_scaling_needed ( float amax,
float * data,
long long nr )

Check if pixel float values need to be scaled to be saved as short ints, or if they are already all very close to integers.

Returns
1, if scaling is necessary, and 0 if not.
Parameters
amaxAbsolute maximum value.
dataFloat array.
nrNumber of float values in float array.

Definition at line 604 of file ecat7w.c.

611 {
612 double d;
613
614 if(nr<1 || data==NULL) return(0);
615 /* scaling is necessary if all values are between -1 - 1 */
616 if(amax<0.9999) return(1);
617 /* Lets check first if at least the max value is close to integers or not */
618 if(modf(amax, &d)>0.0001) return(1);
619 /* if it is, then check all pixels */
620 for(long long i=0; i<nr; i++) if(modf(*data++, &d)>0.0001) return(1);
621 return(0);
622}

Referenced by ecat7Write2DScanMatrix(), ecat7WriteImageMatrix(), ecat7WritePolarmapMatrix(), and ecat7WriteScanMatrix().

◆ ecat7Create()

FILE * ecat7Create ( const char * fname,
ECAT7_mainheader * h )

Create a new ECAT 7.x file. If file exists, it is renamed as fname% if possible. Directory list is written in big endian byte order.

Parameters
fnamefilename
hEcat7 main header
Returns
file pointer or NULL in case of an error.

Definition at line 567 of file ecat7w.c.

567 {
568 FILE *fp;
569 char tmp[FILENAME_MAX];
570 int buf[MatBLKSIZE/4];
571
572 if(ECAT7_TEST) printf("ecat7Create(%s, h)\n", fname);
573 /* Check the arguments */
574 if(fname==NULL || h==NULL) return(NULL);
575 /* Check if file exists; backup, if necessary */
576 if(access(fname, 0) != -1) {
577 strcpy(tmp, fname); strcat(tmp, BACKUP_EXTENSION);
578 if(access(tmp, 0) != -1) remove(tmp);
579 if(ECAT7_TEST) printf("Renaming %s -> %s\n", fname, tmp);
580 rename(fname, tmp);
581 }
582 /* Open file */
583 fp=fopen(fname, "wb+"); if(fp==NULL) return(fp);
584 /* Write main header */
585 if(ecat7WriteMainheader(fp, h)) return(NULL);
586 /* Construct an empty matrix list ; convert to little endian if necessary */
587 memset(buf, 0, MatBLKSIZE);
588 buf[0]=31; buf[1]=MatFirstDirBlk; if(little_endian()) swawbip(buf, MatBLKSIZE);
589 /* Write data buffer */
590 fseek(fp, (MatFirstDirBlk-1)*MatBLKSIZE, SEEK_SET);
591 if(ftell(fp)!=(MatFirstDirBlk-1)*MatBLKSIZE) return(NULL);
592 if(fwrite(buf, 4, MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(NULL);
593 /* OK, then return file pointer */
594 return(fp);
595}
int ECAT7_TEST
Definition ecat7h.c:6
int ecat7WriteMainheader(FILE *fp, ECAT7_mainheader *h)
Definition ecat7w.c:16
#define BACKUP_EXTENSION
#define MatFirstDirBlk
#define MatBLKSIZE
void swawbip(void *buf, long long int size)
Definition swap.c:93
int little_endian()
Definition swap.c:14

Referenced by ecat7CopyFile(), imgWrite2DEcat7(), imgWriteEcat7(), imgWriteEcat7Frame(), and imgWritePolarmap().

◆ ecat7Write2DNormheader()

int ecat7Write2DNormheader ( FILE * fp,
int blk,
ECAT7_2Dnormheader * h )

Write ECAT 7.x 2D normalization header.

Parameters
fpfile pointer
blkheader block number, blk >= 2
hEcat7 2D normalization header
Returns
0 in case of success, 1 == invalid parameters, 4 == file pointer is at wrong position, 5 == writing of MatBLKSIZE bytes was not success

Definition at line 517 of file ecat7w.c.

517 {
518 unsigned char buf[MatBLKSIZE];
519 int little; /* 1 if current platform is little endian (i386), else 0 */
520
521 if(ECAT7_TEST) printf("ecat7Write2DNormheader()\n");
522 if(fp==NULL || blk<2 || h==NULL) return(1);
523 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
524 /* Clear buf */
525 memset(buf, 0, MatBLKSIZE);
529
530 /* Copy the header fields and swap if necessary */
531 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
532 memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
533 memcpy(buf+4, &h->num_r_elements, 2); if(little) swabip(buf+4, 2);
534 memcpy(buf+6, &h->num_angles, 2); if(little) swabip(buf+6, 2);
535 memcpy(buf+8, &h->num_z_elements, 2); if(little) swabip(buf+8, 2);
536 memcpy(buf+10, &h->ring_difference, 2); if(little) swabip(buf+10, 2);
537 memcpy(buf+12, &h->scale_factor, 4); if(little) swawbip(buf+12, 4);
538 memcpy(buf+16, &h->norm_min, 4); if(little) swawbip(buf+16, 4);
539 memcpy(buf+20, &h->norm_max, 4); if(little) swawbip(buf+20, 4);
540 memcpy(buf+24, &h->fov_source_width, 4); if(little) swawbip(buf+24, 4);
541 memcpy(buf+28, &h->norm_quality_factor, 4); if(little) swawbip(buf+28, 4);
542 memcpy(buf+32, &h->norm_quality_factor_code, 2); if(little) swabip(buf+32, 2);
543 memcpy(buf+34, &h->storage_order, 2); if(little) swabip(buf+34, 2);
544 memcpy(buf+36, &h->span, 2); if(little) swabip(buf+36, 2);
545 memcpy(buf+38, h->fill_cti, 64*2); if(little) swabip(buf+38, 64*2);
546 memcpy(buf+166, h->fill_cti, 123*2); if(little) swabip(buf+166, 123*2);
547 memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
548
549 /* Write header */
550 long long pos=(blk-1)*(long long)MatBLKSIZE;
551 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
552 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
553
554 return(0);
555}
#define ECAT7_IEEER4
#define ECAT7_VAXI4
#define ECAT7_SUNI4
#define ECAT7_VAXI2
#define ECAT7_VAXR4
#define ECAT7_SUNI2
void swabip(void *buf, long long int size)
Definition swap.c:72
short int num_dimensions
short int ring_difference
short int storage_order
short int num_z_elements
short int fill_user[50]
short int norm_quality_factor_code
short int num_r_elements
short int fill_cti[123]

◆ ecat7Write2DScanheader()

int ecat7Write2DScanheader ( FILE * fp,
int blk,
ECAT7_2Dscanheader * h )

Write ECAT 7.x 2D scan header

Parameters
fpoutput file pointer
blkheader block number, blk >= 2
hEcat7 2D scan header
Returns
0 in case of success, 1 == invalid parameters, 4 == file pointer is at wrong position, 5 == writing of MatBLKSIZE bytes was not success

Definition at line 450 of file ecat7w.c.

450 {
451 unsigned char buf[MatBLKSIZE];
452 int little; /* 1 if current platform is little endian (i386), else 0 */
453
454 if(ECAT7_TEST) printf("ecat7Write2DScanheader()\n");
455 if(fp==NULL || blk<2 || h==NULL) return(1);
456 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
457 /* Clear buf */
458 memset(buf, 0, MatBLKSIZE);
462
463 /* Copy the header fields and swap if necessary */
464 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
465 memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
466 memcpy(buf+4, &h->num_r_elements, 2); if(little) swabip(buf+4, 2);
467 memcpy(buf+6, &h->num_angles, 2); if(little) swabip(buf+6, 2);
468 memcpy(buf+8, &h->corrections_applied, 2); if(little) swabip(buf+8, 2);
469 memcpy(buf+10, &h->num_z_elements, 2); if(little) swabip(buf+10, 2);
470 memcpy(buf+12, &h->ring_difference, 2); if(little) swabip(buf+12, 2);
471 memcpy(buf+14, &h->x_resolution, 4); if(little) swawbip(buf+14, 4);
472 memcpy(buf+18, &h->y_resolution, 4); if(little) swawbip(buf+18, 4);
473 memcpy(buf+22, &h->z_resolution, 4); if(little) swawbip(buf+22, 4);
474 memcpy(buf+26, &h->w_resolution, 4); if(little) swawbip(buf+26, 4);
475 memcpy(buf+30, h->fill_gate, 6*2); if(little) swabip(buf+30, 6*2);
476 memcpy(buf+42, &h->gate_duration, 4); if(little) swawbip(buf+42, 4);
477 memcpy(buf+46, &h->r_wave_offset, 4); if(little) swawbip(buf+46, 4);
478 memcpy(buf+50, &h->num_accepted_beats, 4); if(little) swawbip(buf+50, 4);
479 memcpy(buf+54, &h->scale_factor, 4); if(little) swawbip(buf+54, 4);
480 memcpy(buf+58, &h->scan_min, 2); if(little) swabip(buf+58, 2);
481 memcpy(buf+60, &h->scan_max, 2); if(little) swabip(buf+60, 2);
482 memcpy(buf+62, &h->prompts, 4); if(little) swawbip(buf+62, 4);
483 memcpy(buf+66, &h->delayed, 4); if(little) swawbip(buf+66, 4);
484 memcpy(buf+70, &h->multiples, 4); if(little) swawbip(buf+70, 4);
485 memcpy(buf+74, &h->net_trues, 4); if(little) swawbip(buf+74, 4);
486 memcpy(buf+78, h->cor_singles, 16*4); if(little) swawbip(buf+78, 16*4);
487 memcpy(buf+142, h->uncor_singles, 16*4); if(little) swawbip(buf+142, 16*4);
488 memcpy(buf+206, &h->tot_avg_cor, 4); if(little) swawbip(buf+206, 4);
489 memcpy(buf+210, &h->tot_avg_uncor, 4); if(little) swawbip(buf+210, 4);
490 memcpy(buf+214, &h->total_coin_rate, 4); if(little) swawbip(buf+214, 4);
491 memcpy(buf+218, &h->frame_start_time, 4); if(little) swawbip(buf+218, 4);
492 memcpy(buf+222, &h->frame_duration, 4); if(little) swawbip(buf+222, 4);
493 memcpy(buf+226, &h->deadtime_correction_factor, 4); if(little) swawbip(buf+226, 4);
494 memcpy(buf+230, h->physical_planes, 8*2); if(little) swabip(buf+230, 8*2);
495 memcpy(buf+246, h->fill_cti, 83*2); if(little) swabip(buf+246, 83*2);
496 memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
497
498 /* Write header */
499 long long pos=(blk-1)*(long long)MatBLKSIZE;
500 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
501 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
502
503 return(0);
504}
short int corrections_applied
float deadtime_correction_factor
short int num_z_elements
short int num_r_elements
short int fill_user[50]
short int ring_difference
short int physical_planes[8]
short int fill_gate[6]
short int fill_cti[83]
float cor_singles[16]
float uncor_singles[16]
short int num_dimensions

Referenced by ecat7Write2DScanMatrix().

◆ ecat7Write2DScanMatrix()

int ecat7Write2DScanMatrix ( FILE * fp,
int matrix_id,
ECAT7_2Dscanheader * h,
float * fdata )

Write ECAT 7.x 2D sinogram matrix header and data

Parameters
fpoutput file pointer
matrix_idcoded matrix id
hEcat7 2D image scan header
fdatafloat data to be written
Returns
0 if ok.

Definition at line 719 of file ecat7w.c.

719 {
720 int ret;
721 long long i, data_size, nxtblk, blkNr, pxlNr;
722 float *fptr, fmin, fmax, g, f;
723 char *mdata, *mptr;
724 short int *sptr;
725
726
727 if(ECAT7_TEST) printf("ecat7Write2DScanMatrix(fp, %d, h, data)\n", matrix_id);
728 if(fp==NULL || matrix_id<1 || h==NULL || fdata==NULL) {
729 sprintf(ecat7errmsg, "invalid function parameter.\n");
730 return(1);
731 }
732 if(h->data_type!=ECAT7_SUNI2) {
733 sprintf(ecat7errmsg, "invalid data_type.\n");
734 return(2);
735 }
736 /* nr of pixels */
737 pxlNr=h->num_r_elements*h->num_angles;
738 if(h->num_dimensions>2) pxlNr*=h->num_z_elements;
739 if(pxlNr<1) {
740 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
741 return(3);
742 }
743 /* How much memory is needed for ALL pixels */
744 data_size=pxlNr*ecat7pxlbytes(h->data_type);
745 /* block nr taken by all pixels */
746 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
747 sprintf(ecat7errmsg, "invalid block number.\n");
748 return(4);
749 }
750 /* Allocate memory for matrix data */
751 mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
752 sprintf(ecat7errmsg, "out of memory.\n");
753 return(5);
754 }
755 /* Search for min and max for calculation of scale factor */
756 fMinMaxFin(fdata, pxlNr, &fmin, &fmax);
757 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
758 if(g>0) f=32766./g; else f=1.0;
759 /* Check if pixels values can be left as such with scale_factor = 1 */
760 fptr=fdata;
761 if(f>=1.0 && ecat7_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
762 /* Scale matrix data to shorts */
763 h->scale_factor=1.0/f;
764 sptr=(short int*)mdata; fptr=fdata;
765 for(i=0; i<pxlNr; i++, sptr++, fptr++) *sptr=(short int)temp_roundf(f*(*fptr));
766 /* Set header short min & max */
767 h->scan_min=(short int)temp_roundf(f*fmin);
768 h->scan_max=(short int)temp_roundf(f*fmax);
769 /* Get block number for matrix header and data */
770 nxtblk=ecat7EnterMatrix(fp, matrix_id, blkNr); if(nxtblk<1) {
771 sprintf(ecat7errmsg, "cannot determine matrix block (%lld).\n", -nxtblk);
772 free(mdata); return(8);
773 }
774 if(ECAT7_TEST>2) printf(" block=%lld fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
775 /* Write header */
776 ret=ecat7Write2DScanheader(fp, nxtblk, h); if(ret) {
777 sprintf(ecat7errmsg, "cannot write subheader (%d).\n", ret);
778 free(mdata); return(10);
779 }
780 /* Write matrix data */
781 mptr=mdata;
782 ret=ecat7WriteMatrixdata(fp, nxtblk+1, mptr, pxlNr, ecat7pxlbytes(h->data_type));
783 free(mdata);
784 if(ret) {
785 sprintf(ecat7errmsg, "cannot write matrix data (%d).\n", ret);
786 return(13);
787 }
788 return(0);
789}
char ecat7errmsg[128]
Definition ecat7h.c:7
int ecat7EnterMatrix(FILE *fp, int matrix_id, int block_nr)
Definition ecat7ml.c:147
int ecat7pxlbytes(short int data_type)
Definition ecat7r.c:1274
int ecat7_is_scaling_needed(float amax, float *data, long long nr)
Definition ecat7w.c:604
int ecat7WriteMatrixdata(FILE *fp, int start_block, char *data, long long pxl_nr, int pxl_size)
Definition ecat7w.c:974
int ecat7Write2DScanheader(FILE *fp, int blk, ECAT7_2Dscanheader *h)
Definition ecat7w.c:450
void fMinMaxFin(float *data, long long int n, float *fmin, float *fmax)
Definition imgminmax.c:649
int temp_roundf(float e)
Definition petc99.c:20

Referenced by imgWrite2DEcat7(), and imgWriteEcat7Frame().

◆ ecat7WriteAttenheader()

int ecat7WriteAttenheader ( FILE * fp,
int blk,
ECAT7_attenheader * h )

Write ECAT 7.x attenuation header

Parameters
fpoutput file pointer
blkheader block number, blk >= 2
hEcat7 attenuation header
Returns
0 in case of success, 1 == invalid parameters, 4 == file pointer is at wrong position, 5 == writing of MatBLKSIZE bytes was not success

Definition at line 208 of file ecat7w.c.

208 {
209 unsigned char buf[MatBLKSIZE];
210 int little; /* 1 if current platform is little endian (i386), else 0 */
211
212 if(ECAT7_TEST) printf("ecat7WriteAttenheader()\n");
213 if(fp==NULL || blk<2 || h==NULL) return(1);
214 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
215 /* Clear buf */
216 memset(buf, 0, MatBLKSIZE);
220
221 /* Copy the header fields and swap if necessary */
222 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
223 memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
224 memcpy(buf+4, &h->attenuation_type, 2); if(little) swabip(buf+4, 2);
225 memcpy(buf+6, &h->num_r_elements, 2); if(little) swabip(buf+6, 2);
226 memcpy(buf+8, &h->num_angles, 2); if(little) swabip(buf+8, 2);
227 memcpy(buf+10, &h->num_z_elements, 2); if(little) swabip(buf+10, 2);
228 memcpy(buf+12, &h->ring_difference, 2); if(little) swabip(buf+12, 2);
229 memcpy(buf+14, &h->x_resolution, 4); if(little) swawbip(buf+14, 4);
230 memcpy(buf+18, &h->y_resolution, 4); if(little) swawbip(buf+18, 4);
231 memcpy(buf+22, &h->z_resolution, 4); if(little) swawbip(buf+22, 4);
232 memcpy(buf+26, &h->w_resolution, 4); if(little) swawbip(buf+26, 4);
233 memcpy(buf+30, &h->scale_factor, 4); if(little) swawbip(buf+30, 4);
234 memcpy(buf+34, &h->x_offset, 4); if(little) swawbip(buf+34, 4);
235 memcpy(buf+38, &h->y_offset, 4); if(little) swawbip(buf+38, 4);
236 memcpy(buf+42, &h->x_radius, 4); if(little) swawbip(buf+42, 4);
237 memcpy(buf+46, &h->y_radius, 4); if(little) swawbip(buf+46, 4);
238 memcpy(buf+50, &h->tilt_angle, 4); if(little) swawbip(buf+50, 4);
239 memcpy(buf+54, &h->attenuation_coeff, 4); if(little) swawbip(buf+54, 4);
240 memcpy(buf+58, &h->attenuation_min, 4); if(little) swawbip(buf+58, 4);
241 memcpy(buf+62, &h->attenuation_max, 4); if(little) swawbip(buf+62, 4);
242 memcpy(buf+66, &h->skull_thickness, 4); if(little) swawbip(buf+66, 4);
243 memcpy(buf+70, &h->num_additional_atten_coeff, 2); if(little) swabip(buf+70, 2);
244 memcpy(buf+72, h->additional_atten_coeff, 8*4); if(little) swawbip(buf+72, 8*4);
245 memcpy(buf+104, &h->edge_finding_threshold, 4); if(little) swawbip(buf+104, 4);
246 memcpy(buf+108, &h->storage_order, 2); if(little) swabip(buf+108, 2);
247 memcpy(buf+110, &h->span, 2); if(little) swabip(buf+110, 2);
248 memcpy(buf+112, h->z_elements, 64*2); if(little) swabip(buf+112, 64*2);
249 memcpy(buf+240, h->fill_cti, 86*2); if(little) swabip(buf+240, 86*2);
250 memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
251
252 /* Write header */
253 long long pos=(blk-1)*(long long)MatBLKSIZE;
254 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
255 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
256
257 return(0);
258}
short int num_r_elements
short int z_elements[64]
short int attenuation_type
short int fill_cti[86]
short int num_additional_atten_coeff
short int num_dimensions
float edge_finding_threshold
short int num_z_elements
short int data_type
short int num_angles
short int fill_user[50]
short int storage_order
short int ring_difference
float additional_atten_coeff[8]

◆ ecat7WriteImageheader()

int ecat7WriteImageheader ( FILE * fp,
int blk,
ECAT7_imageheader * h )

Write ECAT 7.x image header. Changes data type to big endian.

Parameters
fpoutput file pointer
blkheader block number, blk >= 2
hEcat7 image header
Returns
0 in case of success, 1 == invalid parameters, 4 == file pointer is at wrong position, 5 == writing of MatBLKSIZE bytes was not success

Definition at line 113 of file ecat7w.c.

113 {
114 unsigned char buf[MatBLKSIZE];
115 int little; /* 1 if current platform is little endian (i386), else 0 */
116
117 if(ECAT7_TEST) printf("ecat7WriteImageheader(%d)\n", blk);
118 if(fp==NULL || blk<2 || h==NULL) return(1);
119 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
120 /* Clear buf */
121 memset(buf, 0, MatBLKSIZE);
125
126 /* Copy the header fields and swap if necessary */
127 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
128 memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
129 memcpy(buf+4, &h->x_dimension, 2); if(little) swabip(buf+4, 2);
130 memcpy(buf+6, &h->y_dimension, 2); if(little) swabip(buf+6, 2);
131 memcpy(buf+8, &h->z_dimension, 2); if(little) swabip(buf+8, 2);
132 memcpy(buf+10, &h->x_offset, 4); if(little) swawbip(buf+10, 4);
133 memcpy(buf+14, &h->y_offset, 4); if(little) swawbip(buf+14, 4);
134 memcpy(buf+18, &h->z_offset, 4); if(little) swawbip(buf+18, 4);
135 memcpy(buf+22, &h->recon_zoom, 4); if(little) swawbip(buf+22, 4);
136 memcpy(buf+26, &h->scale_factor, 4); if(little) swawbip(buf+26, 4);
137 memcpy(buf+30, &h->image_min, 2); if(little) swabip(buf+30, 2);
138 memcpy(buf+32, &h->image_max, 2); if(little) swabip(buf+32, 2);
139 memcpy(buf+34, &h->x_pixel_size, 4); if(little) swawbip(buf+34, 4);
140 memcpy(buf+38, &h->y_pixel_size, 4); if(little) swawbip(buf+38, 4);
141 memcpy(buf+42, &h->z_pixel_size, 4); if(little) swawbip(buf+42, 4);
142 memcpy(buf+46, &h->frame_duration, 4); if(little) swawbip(buf+46, 4);
143 memcpy(buf+50, &h->frame_start_time, 4); if(little) swawbip(buf+50, 4);
144 memcpy(buf+54, &h->filter_code, 2); if(little) swabip(buf+54, 2);
145 memcpy(buf+56, &h->x_resolution, 4); if(little) swawbip(buf+56, 4);
146 memcpy(buf+60, &h->y_resolution, 4); if(little) swawbip(buf+60, 4);
147 memcpy(buf+64, &h->z_resolution, 4); if(little) swawbip(buf+64, 4);
148 memcpy(buf+68, &h->num_r_elements, 4); if(little) swawbip(buf+68, 4);
149 memcpy(buf+72, &h->num_angles, 4); if(little) swawbip(buf+72, 4);
150 memcpy(buf+76, &h->z_rotation_angle, 4); if(little) swawbip(buf+76, 4);
151 memcpy(buf+80, &h->decay_corr_fctr, 4); if(little) swawbip(buf+80, 4);
152 memcpy(buf+84, &h->processing_code, 4); if(little) swawbip(buf+84, 4);
153 memcpy(buf+88, &h->gate_duration, 4); if(little) swawbip(buf+88, 4);
154 memcpy(buf+92, &h->r_wave_offset, 4); if(little) swawbip(buf+92, 4);
155 memcpy(buf+96, &h->num_accepted_beats, 4); if(little) swawbip(buf+96, 4);
156 memcpy(buf+100, &h->filter_cutoff_frequency, 4); if(little) swawbip(buf+100, 4);
157 memcpy(buf+104, &h->filter_resolution, 4); if(little) swawbip(buf+104, 4);
158 memcpy(buf+108, &h->filter_ramp_slope, 4); if(little) swawbip(buf+108, 4);
159 memcpy(buf+112, &h->filter_order, 2); if(little) swabip(buf+112, 2);
160 memcpy(buf+114, &h->filter_scatter_fraction, 4); if(little) swawbip(buf+114, 4);
161 memcpy(buf+118, &h->filter_scatter_slope, 4); if(little) swawbip(buf+118, 4);
162 memcpy(buf+122, &h->annotation, 40);
163 memcpy(buf+162, &h->mt_1_1, 4); if(little) swawbip(buf+162, 4);
164 memcpy(buf+166, &h->mt_1_2, 4); if(little) swawbip(buf+166, 4);
165 memcpy(buf+170, &h->mt_1_3, 4); if(little) swawbip(buf+170, 4);
166 memcpy(buf+174, &h->mt_2_1, 4); if(little) swawbip(buf+174, 4);
167 memcpy(buf+178, &h->mt_2_2, 4); if(little) swawbip(buf+178, 4);
168 memcpy(buf+182, &h->mt_2_3, 4); if(little) swawbip(buf+182, 4);
169 memcpy(buf+186, &h->mt_3_1, 4); if(little) swawbip(buf+186, 4);
170 memcpy(buf+190, &h->mt_3_2, 4); if(little) swawbip(buf+190, 4);
171 memcpy(buf+194, &h->mt_3_3, 4); if(little) swawbip(buf+194, 4);
172 memcpy(buf+198, &h->rfilter_cutoff, 4); if(little) swawbip(buf+198, 4);
173 memcpy(buf+202, &h->rfilter_resolution, 4); if(little) swawbip(buf+202, 4);
174 memcpy(buf+206, &h->rfilter_code, 2); if(little) swabip(buf+206, 2);
175 memcpy(buf+208, &h->rfilter_order, 2); if(little) swabip(buf+208, 2);
176 memcpy(buf+210, &h->zfilter_cutoff, 4); if(little) swawbip(buf+210, 4);
177 memcpy(buf+214, &h->zfilter_resolution, 4); if(little) swawbip(buf+214, 4);
178 memcpy(buf+218, &h->zfilter_code, 2); if(little) swabip(buf+218, 2);
179 memcpy(buf+220, &h->zfilter_order, 2); if(little) swabip(buf+220, 2);
180 memcpy(buf+222, &h->mt_1_4, 4); if(little) swawbip(buf+222, 4);
181 memcpy(buf+226, &h->mt_2_4, 4); if(little) swawbip(buf+226, 4);
182 memcpy(buf+230, &h->mt_3_4, 4); if(little) swawbip(buf+230, 4);
183 memcpy(buf+234, &h->scatter_type, 2); if(little) swabip(buf+234, 2);
184 memcpy(buf+236, &h->recon_type, 2); if(little) swabip(buf+236, 2);
185 memcpy(buf+238, &h->recon_views, 2); if(little) swabip(buf+238, 2);
186 memcpy(buf+240, &h->fill_cti, 87);
187 memcpy(buf+414, &h->fill_user, 48);
188
189 /* Write header */
190 long long pos=(blk-1)*(long long)MatBLKSIZE;
191 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
192 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
193
194 return(0);
195}
short int fill_cti[87]
float filter_scatter_fraction
short int filter_code
short int image_max
short int image_min
short int zfilter_order
short int fill_user[49]
short int rfilter_code
float filter_cutoff_frequency
short int zfilter_code
short int filter_order
short int y_dimension
short int z_dimension
short int recon_type
short int scatter_type
short int recon_views
short int num_dimensions
short int rfilter_order
short int x_dimension
short int data_type

Referenced by ecat7WriteImageMatrix(), and ecat7WriteSubheaderFromIFT().

◆ ecat7WriteImageMatrix()

int ecat7WriteImageMatrix ( FILE * fp,
int matrix_id,
ECAT7_imageheader * h,
float * fdata )

Write ECAT 7.x image or volume matrix header and data

Parameters
fpoutput file pointer
matrix_idcoded matrix id
hEcat7 image header
fdatafloat data to be written
Returns
0 if ok.

Definition at line 635 of file ecat7w.c.

635 {
636 int ret;
637 long long pxlNr, blkNr, nxtblk, data_size;
638 float *fptr, fmin, fmax, g, f;
639 char *mdata, *mptr;
640 short int *sptr;
641
642
643 if(ECAT7_TEST) printf("ecat7WriteImageMatrix(fp, %d, h, data)\n", matrix_id);
644 if(fp==NULL || matrix_id<1 || h==NULL || fdata==NULL) {
645 sprintf(ecat7errmsg, "invalid function parameter.\n");
646 return(1);
647 }
648 if(h->data_type!=ECAT7_SUNI2) {
649 sprintf(ecat7errmsg, "invalid data_type.\n");
650 return(2);
651 }
652 /* nr of pixels */
653 pxlNr=h->x_dimension*h->y_dimension;
654 if(h->num_dimensions>2) pxlNr*=h->z_dimension;
655 if(pxlNr<1) {
656 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
657 return(3);
658 }
659
660 /* How much memory is needed for ALL pixels */
661 data_size=pxlNr*ecat7pxlbytes(h->data_type);
662 /* block nr taken by all pixels */
663 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
664 sprintf(ecat7errmsg, "invalid block number.\n");
665 return(4);
666 }
667 /* Allocate memory for matrix data */
668 mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
669 sprintf(ecat7errmsg, "out of memory.\n");
670 return(5);
671 }
672 /* Search for min and max for calculation of scale factor */
673 fMinMaxFin(fdata, pxlNr, &fmin, &fmax);
674 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
675 if(g>0) f=32766./g; else f=1.0;
676 /* Check if pixels values can be left as such with scale_factor = 1 */
677 fptr=fdata;
678 if(f>=1.0 && ecat7_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
679 /* Scale matrix data to shorts */
680 h->scale_factor=1.0/f;
681 sptr=(short int*)mdata; fptr=fdata;
682 for(long long i=0; i<pxlNr; i++, sptr++, fptr++) *sptr=(short int)temp_roundf(f*(*fptr));
683 /* Set header short min & max */
684 h->image_min=(short int)temp_roundf(f*fmin);
685 h->image_max=(short int)temp_roundf(f*fmax);
686 /* Get block number for matrix header and data */
687 nxtblk=ecat7EnterMatrix(fp, matrix_id, blkNr); if(nxtblk<1) {
688 sprintf(ecat7errmsg, "cannot determine matrix block (%lld).\n", -nxtblk);
689 free(mdata); return(8);
690 }
691 if(ECAT7_TEST>2) printf(" block=%lld fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
692 /* Write header */
693 ret=ecat7WriteImageheader(fp, nxtblk, h); if(ret) {
694 sprintf(ecat7errmsg, "cannot write subheader (%d).\n", ret);
695 free(mdata); return(10);
696 }
697 /* Write matrix data */
698 mptr=mdata;
699 ret=ecat7WriteMatrixdata(fp, nxtblk+1, mptr, pxlNr, ecat7pxlbytes(h->data_type));
700 free(mdata);
701 if(ret) {
702 sprintf(ecat7errmsg, "cannot write matrix data (%d).\n", ret);
703 return(13);
704 }
705 return(0);
706}
int ecat7WriteImageheader(FILE *fp, int blk, ECAT7_imageheader *h)
Definition ecat7w.c:113

Referenced by imgWrite2DEcat7(), imgWriteEcat7(), and imgWriteEcat7Frame().

◆ ecat7WriteMainheader()

int ecat7WriteMainheader ( FILE * fp,
ECAT7_mainheader * h )

Write ECAT 7.x main header.

Writes header always in big endian byte order.

Returns
0 in case of success, 1 == invalid parameters, 4 == file pointer is at wrong position, 5 == writing of MatBLKSIZE bytes was not success
Parameters
fpoutput file pointer
hEcat7 main header

Definition at line 16 of file ecat7w.c.

21 {
22 unsigned char buf[MatBLKSIZE];
23 int little;
24
25 if(ECAT7_TEST) printf("ecat7WriteMainheader()\n");
26 /* Check arguments */
27 if(fp==NULL || h==NULL) return(1);
28 little=little_endian();
29 /* Clear buf */
30 memset(buf, 0, MatBLKSIZE);
31
32 /* Copy header contents into buffer and change byte order if necessary */
33 memcpy(buf+0, &h->magic_number, 14);
34 memcpy(buf+14, &h->original_file_name, 32);
35 memcpy(buf+46, &h->sw_version, 2); if(little) swabip(buf+46, 2);
36 memcpy(buf+48, &h->system_type, 2); if(little) swabip(buf+48, 2);
37 memcpy(buf+50, &h->file_type, 2); if(little) swabip(buf+50, 2);
38 memcpy(buf+52, &h->serial_number, 10);
39 //printf("ecat7WriteMainheader(): scan_start_time := %d\n", h->scan_start_time);
40 memcpy(buf+62, &h->scan_start_time, 4); if(little) swawbip(buf+62, 4);
41 memcpy(buf+66, &h->isotope_name, 8);
42 memcpy(buf+74, &h->isotope_halflife, 4); if(little) swawbip(buf+74, 4);
43 memcpy(buf+78, &h->radiopharmaceutical, 32);
44 memcpy(buf+110, &h->gantry_tilt, 4); if(little) swawbip(buf+110, 4);
45 memcpy(buf+114, &h->gantry_rotation, 4); if(little) swawbip(buf+114, 4);
46 memcpy(buf+118, &h->bed_elevation, 4); if(little) swawbip(buf+118, 4);
47 memcpy(buf+122, &h->intrinsic_tilt, 4); if(little) swawbip(buf+122, 4);
48 memcpy(buf+126, &h->wobble_speed, 2); if(little) swabip(buf+126, 2);
49 memcpy(buf+128, &h->transm_source_type, 2); if(little) swabip(buf+128, 2);
50 memcpy(buf+130, &h->distance_scanned, 4); if(little) swawbip(buf+130, 4);
51 memcpy(buf+134, &h->transaxial_fov, 4); if(little) swawbip(buf+134, 4);
52 memcpy(buf+138, &h->angular_compression, 2); if(little) swabip(buf+138, 2);
53 memcpy(buf+140, &h->coin_samp_mode, 2); if(little) swabip(buf+140, 2);
54 memcpy(buf+142, &h->axial_samp_mode, 2); if(little) swabip(buf+142, 2);
55 memcpy(buf+144, &h->ecat_calibration_factor, 4); if(little) swawbip(buf+144, 4);
56 memcpy(buf+148, &h->calibration_units, 2); if(little) swabip(buf+148, 2);
57 memcpy(buf+150, &h->calibration_units_label, 2); if(little) swabip(buf+150, 2);
58 memcpy(buf+152, &h->compression_code, 2); if(little) swabip(buf+152, 2);
59 memcpy(buf+154, &h->study_type, 12);
60 memcpy(buf+166, &h->patient_id, 16);
61 memcpy(buf+182, &h->patient_name, 32);
62 memcpy(buf+214, &h->patient_sex, 1);
63 memcpy(buf+215, &h->patient_dexterity, 1);
64 memcpy(buf+216, &h->patient_age, 4); if(little) swawbip(buf+216, 4);
65 memcpy(buf+220, &h->patient_height, 4); if(little) swawbip(buf+220, 4);
66 memcpy(buf+224, &h->patient_weight, 4); if(little) swawbip(buf+224, 4);
67 memcpy(buf+228, &h->patient_birth_date, 4); if(little) swawbip(buf+228, 4);
68 memcpy(buf+232, &h->physician_name, 32);
69 memcpy(buf+264, &h->operator_name, 32);
70 memcpy(buf+296, &h->study_description, 32);
71 memcpy(buf+328, &h->acquisition_type, 2); if(little) swabip(buf+328, 2);
72 memcpy(buf+330, &h->patient_orientation, 2); if(little) swabip(buf+330, 2);
73 memcpy(buf+332, &h->facility_name, 20);
74 memcpy(buf+352, &h->num_planes, 2); if(little) swabip(buf+352, 2);
75 memcpy(buf+354, &h->num_frames, 2); if(little) swabip(buf+354, 2);
76 memcpy(buf+356, &h->num_gates, 2); if(little) swabip(buf+356, 2);
77 memcpy(buf+358, &h->num_bed_pos, 2); if(little) swabip(buf+358, 2);
78 memcpy(buf+360, &h->init_bed_position, 4); if(little) swawbip(buf+360, 4);
79 memcpy(buf+364, h->bed_position, 15*4); if(little) swawbip(buf+364, 15*4);
80 memcpy(buf+424, &h->plane_separation, 4); if(little) swawbip(buf+424, 4);
81 memcpy(buf+428, &h->lwr_sctr_thres, 2); if(little) swabip(buf+428, 2);
82 memcpy(buf+430, &h->lwr_true_thres, 2); if(little) swabip(buf+430, 2);
83 memcpy(buf+432, &h->upr_true_thres, 2); if(little) swabip(buf+432, 2);
84 memcpy(buf+434, &h->user_process_code, 10);
85 memcpy(buf+444, &h->acquisition_mode, 2); if(little) swabip(buf+444, 2);
86 memcpy(buf+446, &h->bin_size, 4); if(little) swawbip(buf+446, 4);
87 memcpy(buf+450, &h->branching_fraction, 4); if(little) swawbip(buf+450, 4);
88 memcpy(buf+454, &h->dose_start_time, 4); if(little) swawbip(buf+454, 4);
89 memcpy(buf+458, &h->dosage, 4); if(little) swawbip(buf+458, 4);
90 memcpy(buf+462, &h->well_counter_corr_factor, 4); if(little) swawbip(buf+462, 4);
91 memcpy(buf+466, &h->data_units, 32);
92 memcpy(buf+498, &h->septa_state, 2); if(little) swabip(buf+498, 2);
93 memcpy(buf+500, &h->fill_cti, 12);
94
95 /* Write main header */
96 fseek(fp, 0*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=0*MatBLKSIZE) return(4);
97 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
98
99 return(0);
100}
short int file_type
short int compression_code
float bed_position[15]
short int system_type
char facility_name[20]
short int num_frames
char operator_name[32]
short int coin_samp_mode
char data_units[32]
char magic_number[14]
float well_counter_corr_factor
char study_type[12]
char user_process_code[10]
short int angular_compression
short int calibration_units
char patient_name[32]
short int fill_cti[6]
short int septa_state
short int num_gates
short int num_planes
short int lwr_true_thres
char physician_name[32]
short int wobble_speed
short int acquisition_mode
short int calibration_units_label
char serial_number[10]
short int num_bed_pos
float ecat_calibration_factor
short int sw_version
short int transm_source_type
short int acquisition_type
char study_description[32]
short int axial_samp_mode
char patient_id[16]
char radiopharmaceutical[32]
short int patient_orientation
short int upr_true_thres
short int lwr_sctr_thres
char original_file_name[32]

Referenced by ecat7Create(), ecat7WriteHeaders(), and imgWriteEcat7Frame().

◆ ecat7WriteMatrixdata()

int ecat7WriteMatrixdata ( FILE * fp,
int start_block,
char * data,
long long pxl_nr,
int pxl_size )

Write ECAT 7.x matrix data to a specified file position. Data does not need to be allocated for full blocks. Data must be represented in current machines byte order, and it is always saved in big endian byte order.

Parameters
fpPointer to an opened ECAT file
start_blockBlock number where matrix data is written
dataPointer to matrix data
pxl_nrNumber of pixels
pxl_sizeSize of data for one pixel in bytes
Returns
>0 in case of an error.

Definition at line 974 of file ecat7w.c.

974 {
975 unsigned char buf[MatBLKSIZE];
976 char *dptr;
977 int little;
978 long long i, dataSize, byteNr, blkNr;
979
980 if(ECAT7_TEST) printf("ecat7WriteMatrixdata(fp, %d, data, %lld, %d)\n",
981 start_block, pxl_nr, pxl_size);
982 if(fp==NULL || start_block<1 || data==NULL || pxl_nr<1 || pxl_size<1) return(1);
983 little=little_endian(); memset(buf, 0, MatBLKSIZE);
984 dataSize=pxl_nr*pxl_size;
985 /* block nr taken by all pixels */
986 blkNr=(dataSize+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) return(1);
987 if(ECAT7_TEST>2) printf(" blkNr=%lld\n", blkNr);
988 /* Search the place for writing */
989 long long pos=(start_block-1)*(long long)MatBLKSIZE;
990 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(2);
991 /* Save blocks one at a time */
992 for(i=0, dptr=data; i<blkNr && dataSize>0; i++) {
993 byteNr=(dataSize<MatBLKSIZE)?dataSize:MatBLKSIZE;
994 memcpy(buf, dptr, byteNr);
995 /* Change matrix byte order in little endian platforms */
996 if(little) {
997 if(pxl_size==2) swabip(buf, byteNr);
998 else if(pxl_size==4) swawbip(buf, byteNr);
999 }
1000 /* Write block */
1001 if(fwrite(buf, 1, MatBLKSIZE, fp)!=MatBLKSIZE) return(3);
1002 /* Prepare for the next block */
1003 dptr+=byteNr; dataSize-=byteNr;
1004 } /* next block */
1005 return(0);
1006}

Referenced by ecat7Write2DScanMatrix(), ecat7WriteImageMatrix(), ecat7WritePolarmapMatrix(), and ecat7WriteScanMatrix().

◆ ecat7WriteNormheader()

int ecat7WriteNormheader ( FILE * fp,
int blk,
ECAT7_normheader * h )

Write ECAT 7.x 3D normalization header

Parameters
fpoutput file pointer
blkheader block number, blk >= 2
hEcat7 normalization header
Returns
0 in case of success, 1 == invalid parameters, 4 == file pointer is at wrong position, 5 == writing of MatBLKSIZE bytes was not success

Definition at line 330 of file ecat7w.c.

330 {
331 unsigned char buf[MatBLKSIZE];
332 int little; /* 1 if current platform is little endian (i386), else 0 */
333
334 if(ECAT7_TEST) printf("ecat7WriteNormheader()\n");
335 if(fp==NULL || blk<2 || h==NULL) return(1);
336 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
337 /* Clear buf */
338 memset(buf, 0, MatBLKSIZE);
342
343 /* Copy the header fields and swap if necessary */
344 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
345 memcpy(buf+2, &h->num_r_elements, 2); if(little) swabip(buf+2, 2);
346 memcpy(buf+4, &h->num_transaxial_crystals, 2); if(little) swabip(buf+4, 2);
347 memcpy(buf+6, &h->num_crystal_rings, 2); if(little) swabip(buf+6, 2);
348 memcpy(buf+8, &h->crystals_per_ring, 2); if(little) swabip(buf+8, 2);
349 memcpy(buf+10, &h->num_geo_corr_planes, 2); if(little) swabip(buf+10, 2);
350 memcpy(buf+12, &h->uld, 2); if(little) swabip(buf+12, 2);
351 memcpy(buf+14, &h->lld, 2); if(little) swabip(buf+14, 2);
352 memcpy(buf+16, &h->scatter_energy, 2); if(little) swabip(buf+16, 2);
353 memcpy(buf+18, &h->norm_quality_factor, 4); if(little) swawbip(buf+18, 4);
354 memcpy(buf+22, &h->norm_quality_factor_code, 2); if(little) swabip(buf+22, 2);
355 memcpy(buf+24, h->ring_dtcor1, 32*4); if(little) swawbip(buf+24, 32*4);
356 memcpy(buf+152, h->ring_dtcor2, 32*4); if(little) swawbip(buf+152, 32*4);
357 memcpy(buf+280, h->crystal_dtcor, 8*4); if(little) swawbip(buf+280, 8*4);
358 memcpy(buf+312, &h->span, 2); if(little) swabip(buf+312, 2);
359 memcpy(buf+314, &h->max_ring_diff, 2); if(little) swabip(buf+314, 2);
360 memcpy(buf+316, h->fill_cti, 48*2); if(little) swabip(buf+316, 48*2);
361 memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
362
363 /* Write header */
364 long long pos=(blk-1)*(long long)MatBLKSIZE;
365 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
366 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
367
368 return(0);
369}
short int num_r_elements
short int data_type
short int num_transaxial_crystals
short int num_geo_corr_planes
short int fill_user[50]
short int crystals_per_ring
short int max_ring_diff
float norm_quality_factor
float ring_dtcor1[32]
short int num_crystal_rings
short int norm_quality_factor_code
float ring_dtcor2[32]
float crystal_dtcor[8]
short int scatter_energy
short int fill_cti[48]

◆ ecat7WritePolarmapMatrix()

int ecat7WritePolarmapMatrix ( FILE * fp,
int matrix_id,
ECAT7_polmapheader * h,
float * fdata )

Write ECAT 7.x polarmap matrix header and data

Parameters
fpoutput file pointer
matrix_idcoded matrix information
hEcat7 polar map header
fdatafloat data
Returns
0 if ok.

Definition at line 888 of file ecat7w.c.

888 {
889 int ret;
890 long long i, nxtblk, blkNr, data_size, pxlNr;
891 float *fptr, fmin, fmax, g, f;
892 char *mdata, *mptr;
893 short int *sptr;
894
895
896 if(ECAT7_TEST) printf("ecat7WritePolarmapMatrix(fp, %d, h, data)\n", matrix_id);
897 if(fp==NULL || matrix_id<1 || h==NULL || fdata==NULL) {
898 sprintf(ecat7errmsg, "invalid function parameter.\n");
899 return(1);
900 }
901 if(h->data_type!=ECAT7_SUNI2) {
902 sprintf(ecat7errmsg, "invalid data_type.\n");
903 return(2);
904 }
905 /* nr of pixels */
906 for(i=pxlNr=0; i<h->num_rings; i++) pxlNr+=h->sectors_per_ring[i];
907 if(pxlNr<1) {
908 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
909 return(3);
910 }
911 /* How much memory is needed for ALL pixels */
912 data_size=pxlNr*ecat7pxlbytes(h->data_type);
913 /* block nr taken by all pixels */
914 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
915 sprintf(ecat7errmsg, "invalid block number.\n");
916 return(4);
917 }
918 /* Allocate memory for matrix data */
919 mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
920 sprintf(ecat7errmsg, "out of memory.\n");
921 return(5);
922 }
923 /* Search for min and max for calculation of scale factor */
924 fMinMaxFin(fdata, pxlNr, &fmin, &fmax);
925 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
926 if(g>0) f=32766./g; else f=1.0;
927 /* Check if pixels values can be left as such with scale_factor = 1 */
928 fptr=fdata;
929 if(f>=1.0 && ecat7_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
930 /* Scale matrix data to shorts */
931 h->scale_factor=1.0/f;
932 sptr=(short int*)mdata; fptr=fdata;
933 for(i=0; i<pxlNr; i++, sptr++, fptr++) *sptr=(short int)temp_roundf(f*(*fptr));
934 /* Set header short min & max */
935 h->image_min=(short int)temp_roundf(f*fmin);
936 h->image_max=(short int)temp_roundf(f*fmax);
937 /* Get block number for matrix header and data */
938 nxtblk=ecat7EnterMatrix(fp, matrix_id, blkNr); if(nxtblk<1) {
939 sprintf(ecat7errmsg, "cannot determine matrix block (%lld).\n", -nxtblk);
940 free(mdata); return(8);
941 }
942 if(ECAT7_TEST>2) printf(" block=%lld fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
943 /* Write header */
944 ret=ecat7WritePolmapheader(fp, nxtblk, h); if(ret) {
945 sprintf(ecat7errmsg, "cannot write subheader (%d).\n", ret);
946 free(mdata); return(10);
947 }
948 /* Write matrix data */
949 mptr=mdata;
950 ret=ecat7WriteMatrixdata(fp, nxtblk+1, mptr, pxlNr, ecat7pxlbytes(h->data_type));
951 free(mdata);
952 if(ret) {
953 sprintf(ecat7errmsg, "cannot write matrix data (%d).\n", ret);
954 return(13);
955 }
956 return(0);
957}
int ecat7WritePolmapheader(FILE *fp, int blk, ECAT7_polmapheader *h)
Definition ecat7w.c:271
short int sectors_per_ring[32]

Referenced by imgWriteEcat7Frame(), and imgWritePolarmap().

◆ ecat7WritePolmapheader()

int ecat7WritePolmapheader ( FILE * fp,
int blk,
ECAT7_polmapheader * h )

Write ECAT 7.x polar map header

Parameters
fpoutput file pointer
blkheader block number, blk >= 2
hEcat7 polar map header
Returns
0 in case of success, 1 == invalid parameters, 4 == file pointer is at wrong position, 5 == writing of MatBLKSIZE bytes was not success

Definition at line 271 of file ecat7w.c.

271 {
272 unsigned char buf[MatBLKSIZE];
273 int little; /* 1 if current platform is little endian (i386), else 0 */
274
275 if(ECAT7_TEST) printf("ecat7WritePolmapheader()\n");
276 if(fp==NULL || blk<2 || h==NULL) return(1);
277 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
278 /* Clear buf */
279 memset(buf, 0, MatBLKSIZE);
283
284 /* Copy the header fields and swap if necessary */
285 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
286 memcpy(buf+2, &h->polar_map_type, 2); if(little) swabip(buf+2, 2);
287 memcpy(buf+4, &h->num_rings, 2); if(little) swabip(buf+4, 2);
288 memcpy(buf+6, h->sectors_per_ring, 32*2); if(little) swabip(buf+6, 32*2);
289 memcpy(buf+70, h->ring_position, 32*4); if(little) swawbip(buf+70, 32*4);
290 memcpy(buf+198, h->ring_angle, 32*2); if(little) swabip(buf+198, 32*2);
291 memcpy(buf+262, &h->start_angle, 2); if(little) swabip(buf+262, 2);
292 memcpy(buf+264, h->long_axis_left, 3*2); if(little) swabip(buf+264, 3*2);
293 memcpy(buf+270, h->long_axis_right, 3*2); if(little) swabip(buf+270, 3*2);
294 memcpy(buf+276, &h->position_data, 2); if(little) swabip(buf+276, 2);
295 memcpy(buf+278, &h->image_min, 2); if(little) swabip(buf+278, 2);
296 memcpy(buf+280, &h->image_max, 2); if(little) swabip(buf+280, 2);
297 memcpy(buf+282, &h->scale_factor, 4); if(little) swawbip(buf+282, 4);
298 memcpy(buf+286, &h->pixel_size, 4); if(little) swawbip(buf+286, 4);
299 memcpy(buf+290, &h->frame_duration, 4); if(little) swawbip(buf+290, 4);
300 memcpy(buf+294, &h->frame_start_time, 4); if(little) swawbip(buf+294, 4);
301 memcpy(buf+298, &h->processing_code, 2); if(little) swabip(buf+298, 2);
302 memcpy(buf+300, &h->quant_units, 2); if(little) swabip(buf+300, 2);
303 memcpy(buf+302, h->annotation, 40);
304 memcpy(buf+342, &h->gate_duration, 4); if(little) swawbip(buf+342, 4);
305 memcpy(buf+346, &h->r_wave_offset, 4); if(little) swawbip(buf+346, 4);
306 memcpy(buf+350, &h->num_accepted_beats, 4); if(little) swawbip(buf+350, 4);
307 memcpy(buf+354, h->polar_map_protocol, 20);
308 memcpy(buf+374, h->database_name, 30);
309 memcpy(buf+404, h->fill_cti, 27*2); if(little) swabip(buf+404, 27*2);
310
311 /* Write header */
312 long long pos=(blk-1)*(long long)MatBLKSIZE;
313 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
314 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
315
316 return(0);
317}
short int fill_cti[27]
short int ring_angle[32]
short int long_axis_left[3]
short int processing_code
char polar_map_protocol[20]
short int start_angle
short int polar_map_type
short int position_data
float ring_position[32]
short int quant_units
short int long_axis_right[3]

Referenced by ecat7WritePolarmapMatrix().

◆ ecat7WriteScanheader()

int ecat7WriteScanheader ( FILE * fp,
int blk,
ECAT7_scanheader * h )

Write ECAT 7.x 3D scan header (512 bytes) Changes data type to big endian.

Parameters
fppointer to output file
blkblock number, blk >= 2
hEcat7 scan header
Returns
0 in case of success, 1 == invalid parameters, 4 == file pointer is at wrong position, 5 == writing of MatBLKSIZE bytes was not success

Definition at line 383 of file ecat7w.c.

383 {
384 unsigned char buf[2*MatBLKSIZE];
385 int little; /* 1 if current platform is little endian (i386), else 0 */
386
387 if(ECAT7_TEST) printf("ecat7WriteScanheader()\n");
388 if(fp==NULL || blk<2 || h==NULL) return(1);
389 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
390 /* Clear buf */
391 memset(buf, 0, 2*MatBLKSIZE);
395
396 /* Copy the header fields and swap if necessary */
397 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
398 memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
399 memcpy(buf+4, &h->num_r_elements, 2); if(little) swabip(buf+4, 2);
400 memcpy(buf+6, &h->num_angles, 2); if(little) swabip(buf+6, 2);
401 memcpy(buf+8, &h->corrections_applied, 2); if(little) swabip(buf+8, 2);
402 memcpy(buf+10, h->num_z_elements, 64*2); if(little) swabip(buf+10, 64*2);
403 memcpy(buf+138, &h->ring_difference, 2); if(little) swabip(buf+138, 2);
404 memcpy(buf+140, &h->storage_order, 2); if(little) swabip(buf+140, 2);
405 memcpy(buf+142, &h->axial_compression, 2); if(little) swabip(buf+142, 2);
406 memcpy(buf+144, &h->x_resolution, 4); if(little) swawbip(buf+144, 4);
407 memcpy(buf+148, &h->v_resolution, 4); if(little) swawbip(buf+148, 4);
408 memcpy(buf+152, &h->z_resolution, 4); if(little) swawbip(buf+152, 4);
409 memcpy(buf+156, &h->w_resolution, 4); if(little) swawbip(buf+156, 4);
410 memcpy(buf+160, h->fill_gate, 6*2); if(little) swabip(buf+160, 6*2);
411 memcpy(buf+172, &h->gate_duration, 4); if(little) swawbip(buf+172, 4);
412 memcpy(buf+176, &h->r_wave_offset, 4); if(little) swawbip(buf+176, 4);
413 memcpy(buf+180, &h->num_accepted_beats, 4); if(little) swawbip(buf+180, 4);
414 memcpy(buf+184, &h->scale_factor, 4); if(little) swawbip(buf+184, 4);
415 memcpy(buf+188, &h->scan_min, 2); if(little) swabip(buf+188, 2);
416 memcpy(buf+190, &h->scan_max, 2); if(little) swabip(buf+190, 2);
417 memcpy(buf+192, &h->prompts, 4); if(little) swawbip(buf+192, 4);
418 memcpy(buf+196, &h->delayed, 4); if(little) swawbip(buf+196, 4);
419 memcpy(buf+200, &h->multiples, 4); if(little) swawbip(buf+200, 4);
420 memcpy(buf+204, &h->net_trues, 4); if(little) swawbip(buf+204, 4);
421 memcpy(buf+208, &h->tot_avg_cor, 4); if(little) swawbip(buf+208, 4);
422 memcpy(buf+212, &h->tot_avg_uncor, 4); if(little) swawbip(buf+212, 4);
423 memcpy(buf+216, &h->total_coin_rate, 4); if(little) swawbip(buf+216, 4);
424 memcpy(buf+220, &h->frame_start_time, 4); if(little) swawbip(buf+220, 4);
425 memcpy(buf+224, &h->frame_duration, 4); if(little) swawbip(buf+224, 4);
426 memcpy(buf+228, &h->deadtime_correction_factor, 4); if(little) swawbip(buf+228, 4);
427 memcpy(buf+232, h->fill_cti, 90*2); if(little) swabip(buf+232, 90*2);
428 memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
429 memcpy(buf+512, h->uncor_singles, 128*4); if(little) swawbip(buf+512, 128*4);
430
431 /* Write 3D scan header */
432 long long pos=(blk-1)*(long long)MatBLKSIZE;
433 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
434 if(fwrite(buf, 1, 2*MatBLKSIZE, fp) != 2*MatBLKSIZE) return(5);
435
436 return(0);
437}
short int scan_min
short int num_r_elements
short int num_angles
short int data_type
float deadtime_correction_factor
short int fill_cti[90]
short int num_dimensions
short int axial_compression
short int fill_gate[6]
short int storage_order
float uncor_singles[128]
short int scan_max
short int num_z_elements[64]
short int fill_user[50]
short int ring_difference
short int corrections_applied

Referenced by ecat7ReadSubheaderToIFT(), ecat7WriteScanMatrix(), and ecat7WriteSubheaderFromIFT().

◆ ecat7WriteScanMatrix()

int ecat7WriteScanMatrix ( FILE * fp,
int matrix_id,
ECAT7_scanheader * h,
float * fdata )

Write ECAT 7.x 3D sinogram matrix header and data

Parameters
fpoutput file pointer
matrix_idcoded matrix id
hEcat7 scan header
fdatafloat data
Returns
0 if ok.

Definition at line 802 of file ecat7w.c.

802 {
803 int ret;
804 long long i, nxtblk, blkNr, data_size, pxlNr, dimz;
805 float *fptr, fmin, fmax, g, f;
806 char *mdata, *mptr;
807 short int *sptr;
808
809
810 if(ECAT7_TEST) printf("ecat7WriteScanMatrix(fp, %d, h, data)\n", matrix_id);
811 if(fp==NULL || matrix_id<1 || h==NULL || fdata==NULL) {
812 sprintf(ecat7errmsg, "invalid function parameter.\n");
813 return(1);
814 }
815 if(h->data_type!=ECAT7_SUNI2) {
816 sprintf(ecat7errmsg, "invalid data_type.\n");
817 return(2);
818 }
819 /* nr of pixels */
820 pxlNr=h->num_r_elements*h->num_angles;
821 for(i=dimz=0; i<64; i++) dimz+=h->num_z_elements[i];
822 pxlNr*=dimz;
823 if(pxlNr<1) {
824 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
825 return(3);
826 }
827 /* How much memory is needed for ALL pixels */
828 data_size=pxlNr*ecat7pxlbytes(h->data_type);
829 /* block nr taken by all pixels */
830 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
831 sprintf(ecat7errmsg, "invalid block number.\n");
832 return(4);
833 }
834 /* Allocate memory for matrix data */
835 mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
836 sprintf(ecat7errmsg, "out of memory.\n");
837 return(5);
838 }
839 /* Search for min and max for calculation of scale factor */
840 fMinMaxFin(fdata, pxlNr, &fmin, &fmax);
841 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
842 if(g>0) f=32766./g; else f=1.0;
843 /* Check if pixels values can be left as such with scale_factor = 1 */
844 fptr=fdata;
845 if(f>=1.0 && ecat7_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
846 /* Scale matrix data to shorts */
847 h->scale_factor=1.0/f;
848 sptr=(short int*)mdata; fptr=fdata;
849 for(i=0; i<pxlNr; i++, sptr++, fptr++) *sptr=(short int)temp_roundf(f*(*fptr));
850 /* Set header short min & max */
851 h->scan_min=(short int)temp_roundf(f*fmin);
852 h->scan_max=(short int)temp_roundf(f*fmax);
853 /* Get block number for matrix header and data */
854 /* Note that one extra block (blkNr+1) is needed for 3D scan header */
855 nxtblk=ecat7EnterMatrix(fp, matrix_id, blkNr+1); if(nxtblk<1) {
856 sprintf(ecat7errmsg, "cannot determine matrix block (%lld).\n", -nxtblk);
857 free(mdata); return(8);
858 }
859 if(ECAT7_TEST>2) printf(" block=%lld fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
860 /* Write header */
861 ret=ecat7WriteScanheader(fp, nxtblk, h); if(ret) {
862 sprintf(ecat7errmsg, "cannot write subheader (%d).\n", ret);
863 free(mdata); return(10);
864 }
865 /* Write matrix data */
866 /* Note that 3D scan header takes TWO blocks */
867 mptr=mdata;
868 ret=ecat7WriteMatrixdata(fp, nxtblk+2, mptr, pxlNr, ecat7pxlbytes(h->data_type));
869 free(mdata);
870 if(ret) {
871 sprintf(ecat7errmsg, "cannot write matrix data (%d).\n", ret);
872 return(13);
873 }
874 return(0);
875}
int ecat7WriteScanheader(FILE *fp, int blk, ECAT7_scanheader *h)
Definition ecat7w.c:383

Referenced by imgWriteEcat7(), and imgWriteEcat7Frame().