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

Reading and writing ECAT 7.x matrix list. More...

#include "libtpcimgio.h"

Go to the source code of this file.

Functions

void ecat7InitMatlist (ECAT7_MATRIXLIST *mlist)
void ecat7EmptyMatlist (ECAT7_MATRIXLIST *mlist)
int ecat7ReadMatlist (FILE *fp, ECAT7_MATRIXLIST *ml, int verbose)
void ecat7PrintMatlist (ECAT7_MATRIXLIST *ml)
int ecat7EnterMatrix (FILE *fp, int matrix_id, int block_nr)
int ecat7_val_to_id (int frame, int plane, int gate, int data, int bed)
void ecat7_id_to_val (int matrix_id, ECAT7_Matval *matval)
void ecat7SortMatlistByPlane (ECAT7_MATRIXLIST *ml)
void ecat7SortMatlistByFrame (ECAT7_MATRIXLIST *ml)
int ecat7CheckMatlist (ECAT7_MATRIXLIST *ml)
int ecat7DeleteLateFrames (ECAT7_MATRIXLIST *ml, int frame_nr)
int ecat7GetPlaneAndFrameNr (ECAT7_MATRIXLIST *mlist, ECAT7_mainheader *h, int *plane_nr, int *frame_nr)
int ecat7GetMatrixBlockSize (ECAT7_MATRIXLIST *mlist, int *blk_nr)
int ecat7GetNums (ECAT7_MATRIXLIST *ml, ECAT7_mainheader *mh, FILE *fp, short int *num_planes, short int *num_frames, short int *num_gates, short int *num_bed_pos)
int ecat7GatherMatlist (ECAT7_MATRIXLIST *ml, short int do_planes, short int do_frames, short int do_gates, short int do_beds)

Detailed Description

Reading and writing ECAT 7.x matrix list.

Author
Vesa Oikonen, Harri Merisaari

Definition in file ecat7ml.c.

Function Documentation

◆ ecat7_id_to_val()

void ecat7_id_to_val ( int matrix_id,
ECAT7_Matval * matval )

Conversion of matrix identifier to numerical values

Parameters
matrix_idmatrix identifier coding
matvalmatrix values structure

Definition at line 262 of file ecat7ml.c.

262 {
263 matval->frame = matrix_id & 0x1FF;
264 matval->plane = ((matrix_id >> 16) & 0xFF) + ((matrix_id >> 1) & 0x300);
265 matval->gate = (matrix_id >> 24) & 0x3F;
266 matval->data = ((matrix_id >> 30) & 0x3) + ((matrix_id >> 9) & 0x4);
267 matval->bed = (matrix_id >> 12) & 0xF;
268}

Referenced by ecat7DeleteLateFrames(), ecat7GatherMatlist(), ecat7GetNums(), ecat7GetPlaneAndFrameNr(), ecat7PrintMatlist(), ecat7PrintSubheader(), ecat7ReadHeaders(), ecat7SortMatlistByFrame(), ecat7SortMatlistByPlane(), ecat7WriteHeaders(), imgReadEcat7(), and imgReadEcat7Frame().

◆ ecat7_val_to_id()

int ecat7_val_to_id ( int frame,
int plane,
int gate,
int data,
int bed )

Returns the matrix identifier.

Parameters
frameframe number [0..65536]
planeplane number [0..65536]
gategate number [0..64]
datadata [0..1]
bedbed position [0..16]
Returns
matrix identifier coding

Definition at line 245 of file ecat7ml.c.

245 {
246 return(
247 ((bed & 0xF) << 12) | /* bed */
248 (frame & 0x1FF) | /* frame */
249 ((gate & 0x3F) << 24) | /* gate */
250 ((plane & 0xFF) << 16) | /* plane low */
251 ((plane & 0x300) << 1) | /* plane high */
252 ((data & 0x3) << 30) | /* data low */
253 ((data & 0x4) << 9) /* data high */
254 );
255}

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

◆ ecat7CheckMatlist()

int ecat7CheckMatlist ( ECAT7_MATRIXLIST * ml)

Checks that all matrixlist entries have read/write status.

Parameters
mlchecked matrix list
Returns
0 if ok, or 1 if an entry is marked as deleted or unfinished

Definition at line 329 of file ecat7ml.c.

329 {
330 int i;
331
332 if(ml==NULL) return(1);
333 for(i=0; i<ml->matrixNr; i++) if(ml->matdir[i].status!=1) return(1);
334 return(0);
335}
ECAT7_MatDir * matdir

Referenced by ecat7ReadHeaders(), ecat7WriteHeaders(), ecatFixMatrixlist(), imgReadEcat7(), imgReadEcat7Frame(), and imgReadEcat7Header().

◆ ecat7DeleteLateFrames()

int ecat7DeleteLateFrames ( ECAT7_MATRIXLIST * ml,
int frame_nr )

Mark deleted the frames after the specified frame number.

Parameters
mltarget matrix list
frame_nrfirst index to be marked as deleted [1..number of frames]
Returns
Returns the number of deleted matrices.

Definition at line 346 of file ecat7ml.c.

346 {
347 int i, del_nr=0;
348 ECAT7_Matval matval;
349
350 for(i=0; i<ml->matrixNr; i++) {
351 ecat7_id_to_val(ml->matdir[i].id, &matval);
352 if(matval.frame>frame_nr) {del_nr++; ml->matdir[i].status=-1;}
353 }
354 return(del_nr);
355}
void ecat7_id_to_val(int matrix_id, ECAT7_Matval *matval)
Definition ecat7ml.c:262

◆ ecat7EmptyMatlist()

void ecat7EmptyMatlist ( ECAT7_MATRIXLIST * mlist)

Free memory allocated for ECAT matrix list.

Parameters
mlisttarget matrix list that has allocated memory

Definition at line 26 of file ecat7ml.c.

26 {
27 if(mlist->matrixSpace>0) free((char*)(mlist->matdir));
28 mlist->matrixSpace=mlist->matrixNr=0;
29}

Referenced by ecat7PrintSubheader(), ecat7ReadHeaders(), ecat7ReadMatlist(), ecat7WriteHeaders(), imgReadEcat7(), imgReadEcat7Frame(), and imgReadEcat7Header().

◆ ecat7EnterMatrix()

int ecat7EnterMatrix ( FILE * fp,
int matrix_id,
int block_nr )

Prepare matrix list for additional matrix data and return block number for matrix header. Directory records are written in big endian byte order. Set block_nr to the number of data blocks + (nr of header blocks - 1)

Parameters
fpfile pointer
matrix_idmatrix identifier coding
block_nrmatrix number [1..number of matrixes]
Returns
returns the block number for matrix header, -1 if invalid input, -2 if first directory block is not found, -3 if failed to read first block, -9 if other directory block is not found, -10 if failed to read other block, -11 if place for new directory block is not found, -12 if failed clear new block, -15 if place for new directory block is not found, -16 if failed to write into new block

Definition at line 147 of file ecat7ml.c.

147 {
148 unsigned int i=0, dirblk, little, busy=1, nxtblk=0, oldsize;
149 /*unsigned*/ int dirbuf[MatBLKSIZE/4];
150
151 if(ECAT7_TEST) printf("ecat7EnterMatrix(fp, %d, %d)\n", matrix_id, block_nr);
152 /* Check the input */
153 if(fp==NULL || matrix_id<1 || block_nr<1) return(-1);
154 /* Is this a little endian machine? */
155 little=little_endian();
156 /* Read first directory record block */
157 dirblk=MatFirstDirBlk;
158 fseek(fp, (dirblk-1)*MatBLKSIZE, SEEK_SET);
159 if(ftell(fp)!=(int)(dirblk-1)*MatBLKSIZE) return(-2);
160 if(fread(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(-3);
161 /* Byte order conversion for ints in little endian platforms */
162 if(little) swawbip(dirbuf, MatBLKSIZE);
163 /* Read through the existing directory records */
164 while(busy) {
165 /* Go through the directory entries in this record */
166 for(i=4, nxtblk=dirblk+1; i<MatBLKSIZE/4; i+=4) {
167 oldsize=dirbuf[i+2]-dirbuf[i+1]+1;
168 if(dirbuf[i]==0) { /* Check for end of matrix list */
169 busy=0; break;
170 } else if(dirbuf[i]==matrix_id) { /* Maybe this matrix already exists? */
171 /* yes it does; is old data smaller? */
172 if(oldsize<(unsigned int)block_nr) {
173 /* it was smaller, so do not use it, but mark it deleted */
174 dirbuf[i] = 0xFFFFFFFF; dirbuf[i+3]=-1;
175 if(little) swawbip(dirbuf, MatBLKSIZE);
176 long long pos=(dirblk-1)*(long long)MatBLKSIZE;
177 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(-6);
178 if(fwrite(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(-7);
179 if(little) swawbip(dirbuf, MatBLKSIZE);
180 nxtblk=dirbuf[i+2]+1;
181 } else { /* old matrix size is ok */
182 nxtblk=dirbuf[i+1]; dirbuf[0]++; dirbuf[3]--; busy=0;
183 break;
184 }
185 } else { /* this is not the same matrix */
186 /* But is deleted and of same or smaller size? */
187 if(dirbuf[i+3]==-1 && (unsigned int)block_nr<=oldsize) {
188 /* yes it was, so lets recycle it */
189 dirbuf[i]=matrix_id;
190 nxtblk=dirbuf[i+1]; dirbuf[0]++; dirbuf[3]--; busy=0;
191 break;
192 }
193 /* nothing to be done with this entry */
194 nxtblk=dirbuf[i+2]+1;
195 }
196 } /* next entry in this record */
197 if(!busy) break; /* stop reading existing records */
198 /* Read the next directory record */
199 if(dirbuf[1]!=MatFirstDirBlk) {
200 /* There are more records left to read */
201 dirblk=dirbuf[1];
202 long long pos=(dirblk-1)*(long long)MatBLKSIZE;
203 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(-9);
204 if(fread(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(-10);
205 if(little) swawbip(dirbuf, MatBLKSIZE);
206 } else {
207 /* No more records to read, so lets write a new empty one */
208 dirbuf[1]=nxtblk; /* write a pointer to the new one */
209 if(little) swawbip(dirbuf, MatBLKSIZE);
210 long long pos=(dirblk-1)*(long long)MatBLKSIZE;
211 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(-11);
212 if(fwrite(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(-12);
213 /* and then initiate the contents of the next one, but do not write it */
214 dirbuf[0]=31; dirbuf[1]=MatFirstDirBlk; dirbuf[2]=dirblk;
215 dirbuf[3]=0; dirblk=nxtblk;
216 for(i=4; i<MatBLKSIZE/4; i++) dirbuf[i]=0;
217 }
218 } /* next directory record */
219 dirbuf[i]=matrix_id;
220 dirbuf[i+1]=nxtblk;
221 dirbuf[i+2]=nxtblk+block_nr;
222 dirbuf[i+3]=1; /* mark the entry as read/write */
223 dirbuf[0]--;
224 dirbuf[3]++;
225 if(little) swawbip(dirbuf, MatBLKSIZE);
226 long long pos=(dirblk-1)*(long long)MatBLKSIZE;
227 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(-15);
228 if(fwrite(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(-16);
229 if(ECAT7_TEST) printf("returning %d from ecat7EnterMatrix()\n", nxtblk);
230 return(nxtblk);
231}
int ECAT7_TEST
Definition ecat7h.c:6
#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(), ecat7Write2DScanMatrix(), ecat7WriteImageMatrix(), ecat7WritePolarmapMatrix(), and ecat7WriteScanMatrix().

◆ ecat7GatherMatlist()

int ecat7GatherMatlist ( ECAT7_MATRIXLIST * ml,
short int do_planes,
short int do_frames,
short int do_gates,
short int do_beds )

Matrix numbers in ECAT 7 matrix list are edited, when necessary, so that plane, frame, gate and/or bed numbers are continuous, starting from one (planes, frames and gates) or from zero (beds). List order is not changed.

Parameters
mlECAT 7 matrix list, where the matrix numbers will be edited
do_planesPlane numbers are gathered together (1) or not (0)
do_framesFrame numbers are gathered together (1) or not (0)
do_gatesGate numbers are gathered together (1) or not (0)
do_bedsBed numbers are gathered together (1) or not (0)
Returns
0 if successful, 1 if invalid input, 3 failed to allocate memory

Definition at line 535 of file ecat7ml.c.

536 {
537 int i, ncurr, n;
538 ECAT7_Matval* matval;
539
540 if(ml==NULL) return(1);
541 if(ml->matrixNr<1) return(0);
542
543 /* Allocate memory for matrix values */
544 matval = (ECAT7_Matval*)calloc(ml->matrixNr,sizeof(ECAT7_Matval));
545 if(matval == NULL) return(3);
546
547 /* And get the matrix values */
548 for(i=0; i<ml->matrixNr; i++) ecat7_id_to_val(ml->matdir[i].id, matval+i);
549
550 /* Planes */
551 if(do_planes!=0) {
552 ncurr=1;
553 while(ncurr <= ml->matrixNr) {
554 /* Find any matrix with this number? */
555 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].plane==ncurr) {n=1; break;}
556 /* If yes, then go on to the next matrix number */
557 if(n==1) {ncurr++; continue;}
558 /* If not, then subtract 1 from all matrix numbers that are larger */
559 for(i=0, n=0; i<ml->matrixNr; i++)
560 if(matval[i].plane>ncurr) {
561 /*printf(" plane %d -> plane %d\n", matval[i].plane, matval[i].plane-1);*/
562 matval[i].plane--; n++;
563 }
564 /* If no larger values were found any more, then quit */
565 if(n<1) break;
566 }
567 }
568
569 /* Frames */
570 if(do_frames!=0) {
571 ncurr=1;
572 while(ncurr <= ml->matrixNr) {
573 /* Find any matrix with this number? */
574 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].frame==ncurr) {n=1; break;}
575 /* If yes, then go on to the next matrix number */
576 if(n==1) {ncurr++; continue;}
577 /* If not, then subtract 1 from all matrix numbers that are larger */
578 for(i=0, n=0; i<ml->matrixNr; i++)
579 if(matval[i].frame>ncurr) {matval[i].frame--; n++;}
580 /* If no larger values were found any more, then quit */
581 if(n<1) break;
582 }
583 }
584
585 /* Gates */
586 if(do_gates!=0) {
587 ncurr=1;
588 while(ncurr <= ml->matrixNr) {
589 /* Find any matrix with this number? */
590 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].gate==ncurr) {n=1; break;}
591 /* If yes, then go on to the next matrix number */
592 if(n==1) {ncurr++; continue;}
593 /* If not, then subtract 1 from all matrix numbers that are larger */
594 for(i=0, n=0; i<ml->matrixNr; i++)
595 if(matval[i].gate>ncurr) {matval[i].gate--; n++;}
596 /* If no larger values were found any more, then quit */
597 if(n<1) break;
598 }
599 }
600
601 /* Beds */
602 if(do_beds!=0) {
603 ncurr=1;
604 while(ncurr <= ml->matrixNr) {
605 /* Find any matrix with this number? */
606 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].bed==ncurr) {n=1; break;}
607 /* If yes, then go on to the next matrix number */
608 if(n==1) {ncurr++; continue;}
609 /* If not, then subtract 1 from all matrix numbers that are larger */
610 for(i=0, n=0; i<ml->matrixNr; i++)
611 if(matval[i].bed>ncurr) {matval[i].bed--; n++;}
612 /* If no larger values were found any more, then quit */
613 if(n<1) break;
614 }
615 }
616
617 /* Write matrix values (possibly changed) into matrix list */
618 for(i=0; i<ml->matrixNr; i++) ml->matdir[i].id=ecat7_val_to_id(
619 matval[i].frame, matval[i].plane,
620 matval[i].gate, matval[i].data,
621 matval[i].bed);
622 free(matval);
623 return(0);
624}
int ecat7_val_to_id(int frame, int plane, int gate, int data, int bed)
Definition ecat7ml.c:245

Referenced by ecatFixMatrixlist(), imgReadEcat7Frame(), and imgReadEcat7Header().

◆ ecat7GetMatrixBlockSize()

int ecat7GetMatrixBlockSize ( ECAT7_MATRIXLIST * mlist,
int * blk_nr )

Calculate the size of one data matrix in ECAT7 file matrix list, and check that the size is same in all matrices.

Parameters
mlistEcat7 matrix list; note that this list is here sorted by planes
blk_nrnumber of blocks will be put here; NULL if not needed
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.

Definition at line 418 of file ecat7ml.c.

418 {
419 int m, prev_blk, blk;
420
421 /* Check input */
422 if(mlist==NULL) return STATUS_FAULT;
423 if(blk_nr!=NULL) *blk_nr=0;
424
425 /* Calculate the size of first data matrix */
426 m=0; prev_blk=blk=mlist->matdir[m].endblk - mlist->matdir[m].strtblk;
427 for(m=1; m<mlist->matrixNr; m++) {
428 blk=mlist->matdir[m].endblk - mlist->matdir[m].strtblk;
429 if(blk!=prev_blk) return STATUS_VARMATSIZE;
430 else prev_blk=blk;
431 }
432 if(blk_nr!=NULL) *blk_nr=blk;
433 return STATUS_OK;
434}

Referenced by imgReadEcat7Header().

◆ ecat7GetNums()

int ecat7GetNums ( ECAT7_MATRIXLIST * ml,
ECAT7_mainheader * mh,
FILE * fp,
short int * num_planes,
short int * num_frames,
short int * num_gates,
short int * num_bed_pos )

Read the maximum plane, frame, gate and bed number from matrixlist. In case of 3D formats, num_planes is checked from the first subheader.

Parameters
mlPointer to matrixlist
mhPointer to mainheader
fpFile pointer to ECAT7 file opened in binary mode
num_planesnum_planes will be put here; NULL if not needed to be read
num_framesnum_planes will be put here; NULL if not needed to be read
num_gatesnum_planes will be put here; NULL if not needed to be read
num_bed_posnum_planes will be put here; NULL if not needed to be read
Returns
0 if successful, 1 if invalid input, 2 if no matrixes, 3 failed to allocate memory, 5 if failed to read image/scan header information

Definition at line 452 of file ecat7ml.c.

453 {
454 int i, nmax, ret=0;
457 ECAT7_Matval* matval;
458
459 if(ml==NULL) return(1);
460 if(ml->matrixNr<1) return(2);
461
462 /* Allocate memory for matrix values */
463 matval = (ECAT7_Matval*)calloc(ml->matrixNr,sizeof(ECAT7_Matval));
464 if(matval == NULL) return(3);
465
466 /* And get the matrix values */
467 for(i=0; i<ml->matrixNr; i++) ecat7_id_to_val(ml->matdir[i].id, matval+i);
468
469 /* Planes */
470 if(num_planes!=NULL) {
471 nmax=matval[0].plane;
472 for(i=1; i<ml->matrixNr; i++) if(matval[i].plane>nmax) nmax=matval[i].plane;
473 *num_planes=nmax;
474 }
475 /* Frames */
476 if(num_frames!=NULL) {
477 nmax=matval[0].frame;
478 for(i=1; i<ml->matrixNr; i++) if(matval[i].frame>nmax) nmax=matval[i].frame;
479 *num_frames=nmax;
480 }
481 /* Gates */
482 if(num_gates!=NULL) {
483 nmax=matval[0].gate;
484 for(i=1; i<ml->matrixNr; i++) if(matval[i].gate>nmax) nmax=matval[i].gate;
485 *num_gates=nmax;
486 }
487 /* Beds */
488 if(num_bed_pos!=NULL) {
489 nmax=matval[0].bed;
490 for(i=1; i<ml->matrixNr; i++) if(matval[i].bed>nmax) nmax=matval[i].bed;
491 *num_bed_pos=nmax;
492 }
493
494 /* Check the num_planes from the first subheader in 3D formats */
495 if(num_planes!=NULL && *num_planes<=1) switch(mh->file_type) {
496 case ECAT7_VOLUME8:
497 case ECAT7_VOLUME16:
498 ret=ecat7ReadImageheader(fp, ml->matdir[0].strtblk, &ih);
499 if(ret!=0) {
500 free(matval);
501 return(5);
502 }
503 if(ih.num_dimensions>2 && ih.z_dimension>1) *num_planes=ih.z_dimension;
504 break;
505 case ECAT7_3DSCAN:
506 case ECAT7_3DSCAN8:
507 case ECAT7_3DSCANFIT:
508 ret=ecat7ReadScanheader(fp, ml->matdir[0].strtblk, &sh);
509 if(ret!=0) {
510 free(matval);
511 return(5);
512 }
513 for(i=0, *num_planes=0; i<64; i++) *num_planes+=sh.num_z_elements[i];
514 break;
515 }
516 free(matval);
517 return(0);
518}
int ecat7ReadScanheader(FILE *fp, int blk, ECAT7_scanheader *h)
Definition ecat7r.c:536
int ecat7ReadImageheader(FILE *fp, int blk, ECAT7_imageheader *h)
Definition ecat7r.c:162
#define ECAT7_VOLUME8
#define ECAT7_3DSCAN
#define ECAT7_3DSCAN8
#define ECAT7_3DSCANFIT
#define ECAT7_VOLUME16
short int z_dimension
short int num_dimensions
short int file_type
short int num_z_elements[64]

Referenced by ecatFixMatrixlist().

◆ ecat7GetPlaneAndFrameNr()

int ecat7GetPlaneAndFrameNr ( ECAT7_MATRIXLIST * mlist,
ECAT7_mainheader * h,
int * plane_nr,
int * frame_nr )

Calculate the number of planes and frames/gates from ECAT7 matrix list. Check that all planes have equal nr of frames/gates, that frames/gates are sequentally numbered.

Parameters
mlistEcat7 matrix list; note that this list is here sorted by planes
hEcat7 main header structure
plane_nrNumber of planes will be put here; NULL if not needed [1..number of planes, or NULL]
frame_nrNumber of frames/gates will be put here; NULL if not needed [1..number of frames, or NULL]
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error. Note that if this is 3D image volume or sinogram, then the returned plane_nr will be one, and the actual Z dim must be read from subheader.

Definition at line 372 of file ecat7ml.c.

372 {
373 ECAT7_Matval matval;
374 int m, plane, frame, prev_plane, prev_frame, fnr, pnr;
375
376 /* Check input */
377 if(mlist==NULL) return STATUS_FAULT;
378 if(plane_nr!=NULL) *plane_nr=0;
379 if(frame_nr!=NULL) *frame_nr=0;
380
381 /* Sort matrices by plane so that following computation works */
383
384 prev_plane=plane=-1; prev_frame=frame=-1;
385 fnr=pnr=0;
386 for(m=0; m<mlist->matrixNr; m++) {
387 ecat7_id_to_val(mlist->matdir[m].id, &matval);
388 plane=matval.plane;
389 if(h->num_frames>=h->num_gates)
390 frame=matval.frame;
391 else
392 frame=matval.gate;
393 if(plane!=prev_plane) {
394 fnr=1; pnr++;
395 } else {
396 fnr++;
397 if(prev_frame>0 && frame!=prev_frame+1) return STATUS_MISSINGMATRIX;
398 }
399 prev_plane=plane; prev_frame=frame;
400 } /* next matrix */
401 if(fnr*pnr != mlist->matrixNr) return STATUS_MISSINGMATRIX;
402 if(plane_nr!=NULL) *plane_nr=pnr;
403 if(frame_nr!=NULL) *frame_nr=fnr;
404 return STATUS_OK;
405}
void ecat7SortMatlistByPlane(ECAT7_MATRIXLIST *ml)
Definition ecat7ml.c:277
short int num_frames
short int num_gates

Referenced by imgReadEcat7Header().

◆ ecat7InitMatlist()

void ecat7InitMatlist ( ECAT7_MATRIXLIST * mlist)

Initiate ECAT matrix list. Call this once before first use.

Parameters
mlisttarget matrix list

Definition at line 15 of file ecat7ml.c.

15 {
16 mlist->matrixSpace=mlist->matrixNr=0; mlist->matdir=NULL;
17}

Referenced by ecat7PrintSubheader(), ecat7ReadHeaders(), ecat7WriteHeaders(), ecatFixMatrixlist(), imgReadEcat7(), imgReadEcat7Frame(), and imgReadEcat7Header().

◆ ecat7PrintMatlist()

void ecat7PrintMatlist ( ECAT7_MATRIXLIST * ml)

Print ECAT matrix list on stdout.

Parameters
mlmatrix list for Ecat7 file

Definition at line 112 of file ecat7ml.c.

112 {
113 int i;
114 ECAT7_Matval matval;
115
116 printf("nr matrix pl fr gate bed startblk blknr status\n");
117 for(i=0; i<ml->matrixNr; i++) {
118 ecat7_id_to_val(ml->matdir[i].id, &matval);
119 printf("%4d %8d %3d %3d %3d %3d %8d %5d ", i+1, ml->matdir[i].id,
120 matval.plane, matval.frame, matval.gate, matval.bed,
121 ml->matdir[i].strtblk, 1+ml->matdir[i].endblk-ml->matdir[i].strtblk);
122 if(ml->matdir[i].status==1) printf("read/write\n");
123 else if(ml->matdir[i].status==0) printf("not ready\n");
124 else if(ml->matdir[i].status==-1) printf("deleted\n");
125 else printf("%d\n", ml->matdir[i].status);
126 }
127 return;
128}

Referenced by ecat7PrintSubheader(), ecatFixMatrixlist(), and imgReadEcat7().

◆ ecat7ReadMatlist()

int ecat7ReadMatlist ( FILE * fp,
ECAT7_MATRIXLIST * ml,
int verbose )

Read ECAT matrix list.

Matrix list must be initiated (once) before calling this.

Returns
returns 0 if ok, 1 if invalid input, 2 if first matrix is not found, 3 if failed to read matrix, 4 if data allocation failed for matrix, 5 if other error occurred.
Parameters
fpFile pointer.
mlPointer to initiated matrix list.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 41 of file ecat7ml.c.

48 {
49 int err=0, little;
50 int blk=MatFirstDirBlk, next_blk=0, nr_free, prev_blk, nr_used;
51 size_t sn;
52 unsigned int dirbuf[MatBLKSIZE/4];
53
54
55 if(verbose>0) printf("ecat7ReadMatlist(fp, mlist)\n");
56 if(fp==NULL) return(1);
57 little=little_endian();
58 /* Make sure that matrix list is empty */
60 /* Seek the first list block */
61 fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
62 do {
63 /* Read the data block */
64 if(verbose>1) printf(" reading dirblock %d\n", blk);
65 sn=fread(dirbuf, sizeof(int), MatBLKSIZE/4, fp); if(sn<MatBLKSIZE/4) return(3);
66 /* Allocate (more) memory for one block */
67 if(ml->matrixSpace==0) {
69 ml->matdir=(ECAT7_MatDir*)malloc(ml->matrixSpace*sizeof(ECAT7_MatDir));
70 } else if(ml->matrixSpace<(ml->matrixNr+MatBLKSIZE/4)) {
72 ml->matdir=(ECAT7_MatDir*)realloc(ml->matdir, sizeof(ECAT7_MatDir)*ml->matrixSpace);
73 }
74 if(ml->matdir==NULL) return(4);
75 /* Byte order conversion for ints in little endian platforms */
76 if(little) swawbip(dirbuf, MatBLKSIZE);
77 /* Read "header" integers */
78 nr_free = dirbuf[0];
79 next_blk = dirbuf[1];
80 prev_blk = dirbuf[2];
81 nr_used = dirbuf[3];
82 if(verbose>2) printf("nr_free=%d next_blk=%d prev_blk=%d nr_used=%d\n", nr_free, next_blk, prev_blk, nr_used);
83 for(int i=4; i<MatBLKSIZE/4; i+=4) if(dirbuf[i]>0) {
84 ml->matdir[ml->matrixNr].id=dirbuf[i];
85 ml->matdir[ml->matrixNr].strtblk=dirbuf[i+1];
86 ml->matdir[ml->matrixNr].endblk=dirbuf[i+2];
87 ml->matdir[ml->matrixNr].status=dirbuf[i+3];
88 if(verbose>3) {
89 printf("matnum=%d strtblk=%d endblk=%d matstat=%d matrixNr=%d\n",
90 ml->matdir[ml->matrixNr].id, ml->matdir[ml->matrixNr].strtblk,
91 ml->matdir[ml->matrixNr].endblk, ml->matdir[ml->matrixNr].status,
92 ml->matrixNr);
93 }
94 ml->matrixNr++;
95 }
96 blk=next_blk;
97 /* Seek the next list block */
98 long long pos=(blk-1)*(long long)MatBLKSIZE;
99 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) err=1;
100 } while(err==0 && feof(fp)==0 && blk!=MatFirstDirBlk);
101 if(err) {ecat7EmptyMatlist(ml); return(5);}
102 return(0);
103}
void ecat7EmptyMatlist(ECAT7_MATRIXLIST *mlist)
Definition ecat7ml.c:26

Referenced by ecat7PrintSubheader(), ecat7ReadHeaders(), ecat7WriteHeaders(), ecatFixMatrixlist(), imgReadEcat7(), imgReadEcat7Frame(), and imgReadEcat7Header().

◆ ecat7SortMatlistByFrame()

void ecat7SortMatlistByFrame ( ECAT7_MATRIXLIST * ml)

Sort matrixlist by frame and plane. Bubble sorting algorithm.

Parameters
mltarget matrix list

Definition at line 303 of file ecat7ml.c.

303 {
304 int i, j;
305 ECAT7_Matval mv1, mv2;
306 ECAT7_MatDir tmpMatdir;
307
308 for(i=0; i<ml->matrixNr-1; i++) {
309 ecat7_id_to_val(ml->matdir[i].id, &mv1);
310 for(j=i+1; j<ml->matrixNr; j++) {
311 ecat7_id_to_val(ml->matdir[j].id, &mv2);
312 if(mv2.frame<mv1.frame||(mv2.frame==mv1.frame&&mv2.plane<mv1.plane)) {
313 tmpMatdir=ml->matdir[i];
314 ml->matdir[i]=ml->matdir[j]; ml->matdir[j]=tmpMatdir;
315 ecat7_id_to_val(ml->matdir[i].id, &mv1);
316 }
317 }
318 }
319}

Referenced by imgReadEcat7Frame().

◆ ecat7SortMatlistByPlane()

void ecat7SortMatlistByPlane ( ECAT7_MATRIXLIST * ml)

Sort matrixlist by plane and frame. Bubble sorting algorithm.

Parameters
mltarget matrix list

Definition at line 277 of file ecat7ml.c.

277 {
278 int i, j;
279 ECAT7_Matval mv1, mv2;
280 ECAT7_MatDir tmpMatdir;
281
282 for(i=0; i<ml->matrixNr-1; i++) {
283 ecat7_id_to_val(ml->matdir[i].id, &mv1);
284 for(j=i+1; j<ml->matrixNr; j++) {
285 ecat7_id_to_val(ml->matdir[j].id, &mv2);
286 if(mv2.plane<mv1.plane||(mv2.plane==mv1.plane&&mv2.frame<mv1.frame)) {
287 tmpMatdir=ml->matdir[i];
288 ml->matdir[i]=ml->matdir[j];
289 ml->matdir[j]=tmpMatdir;
290 ecat7_id_to_val(ml->matdir[i].id, &mv1);
291 }
292 }
293 }
294}

Referenced by ecat7GetPlaneAndFrameNr(), and imgReadEcat7().