TPCCLIB
Loading...
Searching...
No Matches
ecat63ml.c
Go to the documentation of this file.
1
10/*****************************************************************************/
11#include "libtpcimgio.h"
12/*****************************************************************************/
13
14/*****************************************************************************/
21 mlist->matrixSpace=mlist->matrixNr=0; mlist->matdir=NULL;
22}
23/*****************************************************************************/
24
25/*****************************************************************************/
32 if(mlist->matrixSpace>0) free((char*)(mlist->matdir));
33 mlist->matrixSpace=mlist->matrixNr=0;
34}
35/*****************************************************************************/
36
37/*****************************************************************************/
48 FILE *fp,
50 MATRIXLIST *ml,
52 int verbose
53) {
54 int i, err=0, little;
55 int blk=MatFirstDirBlk, next_blk=0;
56 size_t sn;
57 unsigned int dirbuf[MatBLKSIZE/4];
58
59
60 if(verbose>0) {printf("ecat63ReadMatlist(fp, mlist)\n"); fflush(stdout);}
61 if(fp==NULL) return(1);
62 little=little_endian();
63 /* Make sure that matrix list is empty */
65 /* Seek the first list block */
66 fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
67 do {
68 /* Read the data block */
69 if(verbose>1) {printf(" reading dirblock %d\n", blk); fflush(stdout);}
70 sn=fread(dirbuf, sizeof(int), MatBLKSIZE/4, fp);
71 if(sn==0) { /* this never happens in valid ECAT file, but it does happen... */
72 if(verbose>0) {printf("sn=%d\n", (int)sn); fflush(stdout);}
73 //ml->matrixNr--;
74 break;
75 }
76 if(sn<MatBLKSIZE/4) { /* this would be a real error in file */
77 if(verbose>0) {printf("sn=%d\n", (int)sn); fflush(stdout);}
78 err=2; break;
79 }
80 /* Allocate (more) memory for one block */
81 if(ml->matrixSpace==0) {
83 ml->matdir=(MatDir*)malloc(ml->matrixSpace*sizeof(MatDir));
84 } else if(ml->matrixSpace<(ml->matrixNr+MatBLKSIZE/4)) {
86 ml->matdir=(MatDir*)realloc(ml->matdir, sizeof(MatDir)*ml->matrixSpace);
87 }
88 if(ml->matdir==NULL) return(4);
89 /* Byte order conversion for ints in big endian platforms */
90 if(!little) swawbip(dirbuf, MatBLKSIZE);
91 /* Read "header" integers */
92 /*nr_free = dirbuf[0];*/
93 next_blk = dirbuf[1];
94 /*prev_blk = dirbuf[2];*/
95 /*nr_used = dirbuf[3];*/
96 if(verbose>3) printf("next_blk=%d\n", next_blk);
97 fpos_t current_fp; fgetpos(fp, &current_fp); // save current file position
98 for(i=4; i<MatBLKSIZE/4; i+=4) if(dirbuf[i]>0) {
99 ml->matdir[ml->matrixNr].matnum=dirbuf[i];
100 ml->matdir[ml->matrixNr].strtblk=dirbuf[i+1];
101 ml->matdir[ml->matrixNr].endblk=dirbuf[i+2];
102 ml->matdir[ml->matrixNr].matstat=dirbuf[i+3];
103 if(verbose>4) printf("matnum=%d strtblk=%d endblk=%d matstat=%d matrixNr=%d\n",
104 ml->matdir[ml->matrixNr].matnum, ml->matdir[ml->matrixNr].strtblk,
105 ml->matdir[ml->matrixNr].endblk, ml->matdir[ml->matrixNr].matstat,
106 ml->matrixNr);
107 /* verify that these block can be found in the file */
108 int ret=fseek(fp, (ml->matdir[ml->matrixNr].endblk-1)*MatBLKSIZE, SEEK_SET);
109 fsetpos(fp, &current_fp); // back to saved file position
110 if(ret==0) { // end block can be found
111 ml->matrixNr++;
112 } else { // not found, file probably broken
113 if(verbose>0) {
114 printf("matnum %d points to data outside of file.\n", ml->matdir[ml->matrixNr].matnum);
115 fflush(stdout);
116 }
117 }
118 }
119 blk=next_blk;
120 /* Seek the next list block */
121 fseeko(fp, (blk-1)*MatBLKSIZE, SEEK_SET); if(ftello(fp)!=(blk-1)*MatBLKSIZE) err=1;
122 } while(err==0 && feof(fp)==0 && blk!=MatFirstDirBlk);
123 if(err) {ecat63EmptyMatlist(ml); return(5);}
124 return(0);
125}
126/*****************************************************************************/
127
128/*****************************************************************************/
132 MATRIXLIST *ml
133) {
134 int i;
135 Matval matval;
136
137 printf("nr\tmatrix\tpl\tfr\tgate\tbed\tstartblk\tblknr\n");
138 for(i=0; i<ml->matrixNr; i++) {
139 mat_numdoc(ml->matdir[i].matnum, &matval);
140 printf("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", i+1, ml->matdir[i].matnum,
141 matval.plane, matval.frame, matval.gate, matval.bed,
142 ml->matdir[i].strtblk, 1+ml->matdir[i].endblk-ml->matdir[i].strtblk);
143 }
144 return;
145}
146/*****************************************************************************/
147
148/*****************************************************************************/
160 FILE *fp, int matnum, int blkNr
161) {
162 unsigned int i=0, dirblk, little, busy=1, nxtblk=0, oldsize;
163 unsigned int dirbuf[MatBLKSIZE/4];
164
165 if(ECAT63_TEST) printf("ecat63Matenter(fp, %d, %d)\n", matnum, blkNr);
166 if(fp==NULL || matnum<1 || blkNr<1) return(0);
167 little=little_endian(); memset(dirbuf, 0, MatBLKSIZE);
168 /* Read first matrix list block */
169 dirblk=MatFirstDirBlk;
170 fseeko(fp, (dirblk-1)*MatBLKSIZE, SEEK_SET);
171 if(ftello(fp)!=(int)(dirblk-1)*MatBLKSIZE) return(0);
172 if(fread(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(0);
173 /* Byte order conversion for ints in big endian platforms */
174 if(!little) swawbip(dirbuf, MatBLKSIZE);
175
176 while(busy) {
177 nxtblk=dirblk+1;
178 for(i=4; i<MatBLKSIZE/4; i+=4) {
179 if(dirbuf[i]==0) { /* Check for end of matrix list */
180 busy=0; break;
181 } else if(dirbuf[i]==(unsigned int)matnum) { /* Check if this matrix already exists */
182 oldsize=dirbuf[i+2]-dirbuf[i+1]+1;
183 if(oldsize<(unsigned int)blkNr) { /* If old matrix is smaller */
184 dirbuf[i] = 0xFFFFFFFF;
185 if(!little) swawbip(dirbuf, MatBLKSIZE);
186 fseeko(fp, (dirblk-1)*MatBLKSIZE, SEEK_SET);
187 if(ftello(fp)!=(int)(dirblk-1)*MatBLKSIZE) return(0);
188 if(fwrite(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(0);
189 if(!little) swawbip(dirbuf, MatBLKSIZE);
190 nxtblk=dirbuf[i+2]+1;
191 } else { /* old matrix size is ok */
192 nxtblk=dirbuf[i+1]; dirbuf[0]++; dirbuf[3]--; busy=0;
193 break;
194 }
195 } else /* not this one */
196 nxtblk=dirbuf[i+2]+1;
197 }
198 if(!busy) break;
199 if(dirbuf[1]!=MatFirstDirBlk) {
200 dirblk=dirbuf[1];
201 fseeko(fp, (dirblk-1)*MatBLKSIZE, SEEK_SET);
202 if(ftello(fp)!=(int)(dirblk-1)*MatBLKSIZE) return(0);
203 if(fread(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(0);
204 if(!little) swawbip(dirbuf, MatBLKSIZE);
205 } else {
206 dirbuf[1]=nxtblk;
207 if(!little) swawbip(dirbuf, MatBLKSIZE);
208 fseeko(fp, (dirblk-1)*MatBLKSIZE, SEEK_SET);
209 if(ftello(fp)!=(int)(dirblk-1)*MatBLKSIZE) return(0);
210 if(fwrite(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(0);
211 dirbuf[0]=31; dirbuf[1]=MatFirstDirBlk; dirbuf[2]=dirblk;
212 dirbuf[3]=0; dirblk=nxtblk;
213 for(i=4; i<MatBLKSIZE/4; i++) dirbuf[i]=0;
214 }
215 }
216 dirbuf[i]=matnum;
217 dirbuf[i+1]=nxtblk;
218 dirbuf[i+2]=nxtblk+blkNr;
219 dirbuf[i+3]=1;
220 dirbuf[0]--;
221 dirbuf[3]++;
222 if(!little) swawbip(dirbuf, MatBLKSIZE);
223 fseeko(fp, (dirblk-1)*MatBLKSIZE, SEEK_SET);
224 if(ftello(fp)!=(int)(dirblk-1)*MatBLKSIZE) return(0);
225 if(fwrite(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(0);
226 if(ECAT63_TEST) printf("returning %d from ecat63Matenter()\n", nxtblk);
227 return(nxtblk);
228}
229/*****************************************************************************/
230
231/*****************************************************************************/
243 int frame, int plane, int gate, int data, int bed
244) {
245 return((frame&0xFFF)|((bed&0xF)<<12)|((plane&0xFF)<<16)|
246 ((gate&0x3F)<<24)|((data&0x3)<<30));
247}
255 int matnum, Matval *matval
256) {
257 matval->frame = matnum&0xFFF;
258 matval->plane = (matnum>>16)&0xFF;
259 matval->gate = (matnum>>24)&0x3F;
260 matval->data = (matnum>>30)&0x3;
261 matval->bed = (matnum>>12)&0xF;
262}
263/*****************************************************************************/
264
265/*****************************************************************************/
272 MATRIXLIST *ml
273) {
274 Matval mv1, mv2;
275 MatDir tmpMatdir;
276
277 for(int i=0; i<ml->matrixNr-1; i++) {
278 mat_numdoc(ml->matdir[i].matnum, &mv1);
279 for(int j=i+1; j<ml->matrixNr; j++) {
280 mat_numdoc(ml->matdir[j].matnum, &mv2);
281 if(mv2.plane<mv1.plane||(mv2.plane==mv1.plane&&mv2.frame<mv1.frame)) {
282 tmpMatdir=ml->matdir[i];
283 ml->matdir[i]=ml->matdir[j]; ml->matdir[j]=tmpMatdir;
284 mat_numdoc(ml->matdir[i].matnum, &mv1);
285 }
286 }
287 }
288}
289/*****************************************************************************/
290
291/*****************************************************************************/
298 MATRIXLIST *ml
299) {
300 Matval mv1, mv2;
301 MatDir tmpMatdir;
302
303 for(int i=0; i<ml->matrixNr-1; i++) {
304 mat_numdoc(ml->matdir[i].matnum, &mv1);
305 for(int j=i+1; j<ml->matrixNr; j++) {
306 mat_numdoc(ml->matdir[j].matnum, &mv2);
307 if(mv2.frame<mv1.frame||(mv2.frame==mv1.frame&&mv2.plane<mv1.plane)) {
308 tmpMatdir=ml->matdir[i];
309 ml->matdir[i]=ml->matdir[j]; ml->matdir[j]=tmpMatdir;
310 mat_numdoc(ml->matdir[i].matnum, &mv1);
311 }
312 }
313 }
314}
315/*****************************************************************************/
316
317/*****************************************************************************/
325 MATRIXLIST *ml
326) {
327 if(ml==NULL) return(1);
328 for(int i=0; i<ml->matrixNr; i++) if(ml->matdir[i].matstat!=1) return(1);
329 return(0);
330}
331/*****************************************************************************/
332
333/*****************************************************************************/
343 MATRIXLIST *ml, int frame_nr
344) {
345 int del_nr=0;
346 Matval matval;
347
348 for(int i=0; i<ml->matrixNr; i++) {
349 mat_numdoc(ml->matdir[i].matnum, &matval);
350 if(matval.frame>frame_nr) {del_nr++; ml->matdir[i].matstat=-1;}
351 }
352 return(del_nr);
353}
354/*****************************************************************************/
355
356/*****************************************************************************/
367 MATRIXLIST *mlist, int *blk_nr
368) {
369 int m, prev_blk, blk;
370
371 /* Check input */
372 if(mlist==NULL) return STATUS_FAULT;
373 if(blk_nr!=NULL) *blk_nr=0;
374
375 /* Calculate the size of first data matrix */
376 m=0; prev_blk=blk=mlist->matdir[m].endblk - mlist->matdir[m].strtblk;
377 for(m=1; m<mlist->matrixNr; m++) {
378 blk=mlist->matdir[m].endblk - mlist->matdir[m].strtblk;
379 if(blk!=prev_blk) return STATUS_VARMATSIZE;
380 else prev_blk=blk;
381 }
382 if(blk_nr!=NULL) *blk_nr=blk;
383 return STATUS_OK;
384}
385/*****************************************************************************/
386
387/*****************************************************************************/
401 MATRIXLIST *mlist, ECAT63_mainheader *h, int *plane_nr, int *frame_nr
402) {
403 Matval matval;
404 int m, plane, frame, prev_plane, prev_frame, fnr, pnr;
405
406 /* Check input */
407 if(mlist==NULL) return STATUS_FAULT;
408 if(plane_nr!=NULL) *plane_nr=0;
409 if(frame_nr!=NULL) *frame_nr=0;
410
411 /* Sort matrices by plane so that following computation works */
413
414 prev_plane=plane=-1; prev_frame=frame=-1;
415 fnr=pnr=0;
416 for(m=0; m<mlist->matrixNr; m++) if(mlist->matdir[m].matstat==1) {
417 mat_numdoc(mlist->matdir[m].matnum, &matval);
418 plane=matval.plane;
419 if(h->num_frames>=h->num_gates)
420 frame=matval.frame;
421 else
422 frame=matval.gate;
423 if(plane!=prev_plane) {
424 fnr=1; pnr++;
425 } else {
426 fnr++;
427 if(prev_frame>0 && frame!=prev_frame+1) return STATUS_MISSINGMATRIX;
428 }
429 prev_plane=plane; prev_frame=frame;
430 } /* next matrix */
431 if(fnr*pnr != mlist->matrixNr) return STATUS_MISSINGMATRIX;
432 if(plane_nr!=NULL) *plane_nr=pnr;
433 if(frame_nr!=NULL) *frame_nr=fnr;
434 return STATUS_OK;
435}
436/*****************************************************************************/
437
438/*****************************************************************************/
451 MATRIXLIST *ml, short int *num_planes, short int *num_frames,
452 short int *num_gates, short int *num_bed_pos
453) {
454 int i, nmax;
455 Matval* matval;
456
457 if(ml==NULL) return(1);
458 if(ml->matrixNr<1) return(2);
459
460 /* Allocate memory for matrix values */
461 matval = (Matval*)calloc(ml->matrixNr,sizeof(Matval));
462 if(matval == NULL) return(3);
463
464 /* And get the matrix values */
465 for(i=0; i<ml->matrixNr; i++) mat_numdoc(ml->matdir[i].matnum, matval+i);
466
467 /* Planes */
468 if(num_planes!=NULL) {
469 nmax=matval[0].plane;
470 for(i=1; i<ml->matrixNr; i++) if(matval[i].plane>nmax) nmax=matval[i].plane;
471 *num_planes=nmax;
472 }
473 /* Frames */
474 if(num_frames!=NULL) {
475 nmax=matval[0].frame;
476 for(i=1; i<ml->matrixNr; i++) if(matval[i].frame>nmax) nmax=matval[i].frame;
477 *num_frames=nmax;
478 }
479 /* Gates */
480 if(num_gates!=NULL) {
481 nmax=matval[0].gate;
482 for(i=1; i<ml->matrixNr; i++) if(matval[i].gate>nmax) nmax=matval[i].gate;
483 *num_gates=nmax;
484 }
485 /* Beds */
486 if(num_bed_pos!=NULL) {
487 nmax=matval[0].bed;
488 for(i=1; i<ml->matrixNr; i++) if(matval[i].bed>nmax) nmax=matval[i].bed;
489 *num_bed_pos=nmax;
490 }
491 free(matval);
492 return(0);
493}
494/*****************************************************************************/
495
496/*****************************************************************************/
511 MATRIXLIST *ml, short int do_planes, short int do_frames, short int do_gates,
512 short int do_beds
513) {
514 int i, ncurr, n;
515 Matval* matval;
516
517 if(ml==NULL) return(1);
518 if(ml->matrixNr<1) return(0);
519
520 /* Allocate memory for matrix values */
521 matval = (Matval*)calloc(ml->matrixNr,sizeof(Matval));
522 if(matval == NULL) return(3);
523
524 /* And get the matrix values */
525 for(i=0; i<ml->matrixNr; i++) mat_numdoc(ml->matdir[i].matnum, matval+i);
526
527 /* Planes */
528 if(do_planes!=0) {
529 ncurr=1;
530 while(ncurr <= ml->matrixNr) {
531 /* Find any matrix with this number? */
532 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].plane==ncurr) {n=1; break;}
533 /* If yes, then go on to the next matrix number */
534 if(n==1) {ncurr++; continue;}
535 /* If not, then subtract 1 from all matrix numbers that are larger */
536 for(i=0, n=0; i<ml->matrixNr; i++)
537 if(matval[i].plane>ncurr) {
538 matval[i].plane--; n++;
539 }
540 /* If no larger values were found any more, then quit */
541 if(n<1) break;
542 }
543 }
544
545 /* Frames */
546 if(do_frames!=0) {
547 ncurr=1;
548 while(ncurr <= ml->matrixNr) {
549 /* Find any matrix with this number? */
550 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].frame==ncurr) {n=1; break;}
551 /* If yes, then go on to the next matrix number */
552 if(n==1) {ncurr++; continue;}
553 /* If not, then subtract 1 from all matrix numbers that are larger */
554 for(i=0, n=0; i<ml->matrixNr; i++)
555 if(matval[i].frame>ncurr) {matval[i].frame--; n++;}
556 /* If no larger values were found any more, then quit */
557 if(n<1) break;
558 }
559 }
560
561 /* Gates */
562 if(do_gates!=0) {
563 ncurr=1;
564 while(ncurr <= ml->matrixNr) {
565 /* Find any matrix with this number? */
566 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].gate==ncurr) {n=1; break;}
567 /* If yes, then go on to the next matrix number */
568 if(n==1) {ncurr++; continue;}
569 /* If not, then subtract 1 from all matrix numbers that are larger */
570 for(i=0, n=0; i<ml->matrixNr; i++)
571 if(matval[i].gate>ncurr) {matval[i].gate--; n++;}
572 /* If no larger values were found any more, then quit */
573 if(n<1) break;
574 }
575 }
576
577 /* Beds */
578 if(do_beds!=0) {
579 ncurr=1;
580 while(ncurr <= ml->matrixNr) {
581 /* Find any matrix with this number? */
582 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].bed==ncurr) {n=1; break;}
583 /* If yes, then go on to the next matrix number */
584 if(n==1) {ncurr++; continue;}
585 /* If not, then subtract 1 from all matrix numbers that are larger */
586 for(i=0, n=0; i<ml->matrixNr; i++)
587 if(matval[i].bed>ncurr) {matval[i].bed--; n++;}
588 /* If no larger values were found any more, then quit */
589 if(n<1) break;
590 }
591 }
592
593 /* Write matrix values (possibly changed) into matrix list */
594 for(i=0; i<ml->matrixNr; i++) ml->matdir[i].matnum=mat_numcod(
595 matval[i].frame, matval[i].plane,
596 matval[i].gate, matval[i].data,
597 matval[i].bed);
598 free(matval);
599 return(0);
600}
601/*****************************************************************************/
602
603/*****************************************************************************/
int ECAT63_TEST
Definition ecat63h.c:6
int ecat63Matenter(FILE *fp, int matnum, int blkNr)
Definition ecat63ml.c:159
int ecat63ReadMatlist(FILE *fp, MATRIXLIST *ml, int verbose)
Definition ecat63ml.c:46
int ecat63GetPlaneAndFrameNr(MATRIXLIST *mlist, ECAT63_mainheader *h, int *plane_nr, int *frame_nr)
Definition ecat63ml.c:400
void ecat63InitMatlist(MATRIXLIST *mlist)
Definition ecat63ml.c:20
void ecat63EmptyMatlist(MATRIXLIST *mlist)
Definition ecat63ml.c:31
int ecat63GatherMatlist(MATRIXLIST *ml, short int do_planes, short int do_frames, short int do_gates, short int do_beds)
Definition ecat63ml.c:510
int mat_numcod(int frame, int plane, int gate, int data, int bed)
Definition ecat63ml.c:242
int ecat63GetNums(MATRIXLIST *ml, short int *num_planes, short int *num_frames, short int *num_gates, short int *num_bed_pos)
Definition ecat63ml.c:450
int ecat63GetMatrixBlockSize(MATRIXLIST *mlist, int *blk_nr)
Definition ecat63ml.c:366
int ecat63DeleteLateFrames(MATRIXLIST *ml, int frame_nr)
Definition ecat63ml.c:342
void ecat63SortMatlistByPlane(MATRIXLIST *ml)
Definition ecat63ml.c:271
void ecat63PrintMatlist(MATRIXLIST *ml)
Definition ecat63ml.c:130
int ecat63CheckMatlist(MATRIXLIST *ml)
Definition ecat63ml.c:324
void mat_numdoc(int matnum, Matval *matval)
Definition ecat63ml.c:254
void ecat63SortMatlistByFrame(MATRIXLIST *ml)
Definition ecat63ml.c:297
Header file for libtpcimgio.
#define MatFirstDirBlk
#define MatBLKSIZE
void swawbip(void *buf, long long int size)
Definition swap.c:93
int little_endian()
Definition swap.c:14
MatDir * matdir
int matstat
int endblk
int matnum
int strtblk
int frame
int plane