TPCCLIB
Loading...
Searching...
No Matches
ecatmatrixlist.c
Go to the documentation of this file.
1
4/*****************************************************************************/
5#include "tpcclibConfig.h"
6/*****************************************************************************/
7#include <stdio.h>
8#include <stdlib.h>
9#include <math.h>
10#include <time.h>
11#include <string.h>
12/*****************************************************************************/
13#include "tpcextensions.h"
14#include "tpcift.h"
15/*****************************************************************************/
16#include "tpcecat.h"
17/*****************************************************************************/
18
19/*****************************************************************************/
26) {
27 if(ml==NULL) return;
28 ml->matdir=NULL;
29 ml->matrixSpace=ml->matrixNr=0;
30}
31/*****************************************************************************/
32
33/*****************************************************************************/
41) {
42 if(ml==NULL) return;
43 if(ml->matrixSpace>0) free((char*)(ml->matdir));
44 ml->matrixSpace=ml->matrixNr=0;
45}
46/*****************************************************************************/
47
48/*****************************************************************************/
54 int format,
56 unsigned int id,
58 ECAT_MATVAL *mv
59) {
60 if(mv==NULL) return;
61 mv->frame=mv->plane=mv->gate=mv->data=mv->bed=0;
62 if(format==7) {
63 mv->frame = id & 0x1FF;
64 mv->plane = ((id >> 16) & 0xFF) + ((id >> 1) & 0x300);
65 mv->gate = (id >> 24) & 0x3F;
66 mv->data = ((id >> 30) & 0x3) + ((id >> 9) & 0x4);
67 mv->bed = (id >> 12) & 0xF;
68 } else if(format==6) {
69 mv->frame = id&0xFFF;
70 mv->plane = (id>>16)&0xFF;
71 mv->gate = (id>>24)&0x3F;
72 mv->data = (id>>30)&0x3;
73 mv->bed = (id>>12)&0xF;
74 }
75 return;
76}
77/*****************************************************************************/
78
79/*****************************************************************************/
84unsigned int ecatMListMakeId(
86 int format,
88 unsigned int frame,
90 unsigned int plane,
92 unsigned int gate,
94 unsigned int data,
96 unsigned int bed
97) {
98 if(format==7) {
99 return(
100 (frame & 0x1FF) | /* frame */
101 ((plane & 0x300) << 1) | /* plane high */
102 ((data & 0x4) << 9) | /* data high */
103 ((bed & 0xF) << 12) | /* bed */
104 ((plane & 0xFF) << 16) | /* plane low */
105 ((gate & 0x3F) << 24) | /* gate */
106 ((data & 0x3) << 30) /* data low */
107 );
108 } else if(format==6) {
109 return(
110 (frame&0xFFF) |
111 ((bed&0xF)<<12) |
112 ((plane&0xFF)<<16) |
113 ((gate&0x3F)<<24) |
114 ((data&0x3)<<30)
115 );
116 }
117 return(0);
118}
119/*****************************************************************************/
124unsigned int ecatMValToId(
126 int format,
128 ECAT_MATVAL *mv
129) {
130 if(mv==NULL) return(0);
131 return(ecatMListMakeId(format, mv->frame, mv->plane, mv->gate, mv->data, mv->bed));
132}
133/*****************************************************************************/
134
135/*****************************************************************************/
142 int format,
144 FILE *fp,
147 ECAT_MATRIXLIST *ml,
149 TPCSTATUS *status
150) {
151 int verbose=0; if(status!=NULL) verbose=status->verbose;
152 if(verbose>0) {printf("%s(%d, ...)\n", __func__, format); fflush(stdout);}
153
154 if(fp==NULL || ml==NULL) {
155 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
156 return(TPCERROR_FAIL);
157 }
158
159 /* Is current platform little endian (1) or not (0) ? */
160 int little=endianLittle();
161 if(verbose>2) {
162 if(little) printf("little endian platform\n"); else printf("big endian platform\n");
163 }
164
165 /* Make sure that matrix list is empty */
166 ecatMListFree(ml);
167
168 /* Read the blocks belonging to the matrix list */
169 unsigned int blk=2; // Matrix list starts at block 2
170 unsigned int blkNext=0, blkPrev=0, nrFree=0, nrUsed=0;
171 unsigned int dirbuf[ECATBLKSIZE/4];
172 do {
173 /* Read the data block */
174 if(verbose>1) printf(" reading block %u\n", blk);
175 int ret=ecatReadBlock(NULL, fp, blk, (unsigned char*)dirbuf);
176 if(ret!=TPCERROR_OK) {
177 if(verbose>0) fprintf(stderr, "Error: cannot read block %u\n", blk);
178 ecatMListFree(ml);
179 statusSet(status, __func__, __FILE__, __LINE__, ret);
180 return(ret);
181 }
182 /* Byte order conversion for integers in little/big endian platforms */
183 if(little && format==7) swawbip(dirbuf, ECATBLKSIZE);
184 if(!little && format==6) swawbip(dirbuf, ECATBLKSIZE);
185 /* Read the "header" integers from the block */
186 nrFree = dirbuf[0];
187 blkNext = dirbuf[1];
188 blkPrev = dirbuf[2];
189 nrUsed = dirbuf[3];
190 if(verbose>2)
191 printf("nrFree=%u blkNext=%u blkPrev=%u nrUsed=%u\n", nrFree, blkNext, blkPrev, nrUsed);
192 /* Allocate (more) memory for the matrix list */
193 if(ml->matrixSpace==0) {
195 ml->matdir=(ECAT_MATDIR*)malloc(ml->matrixSpace*sizeof(ECAT_MATDIR));
196 } else if(ml->matrixSpace<(ml->matrixNr+ECATBLKSIZE/4)) {
198 ml->matdir=(ECAT_MATDIR*)realloc(ml->matdir, sizeof(ECAT_MATDIR)*ml->matrixSpace);
199 }
200 if(ml->matdir==NULL) {
201 ecatMListFree(ml);
202 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OUT_OF_MEMORY);
204 }
205 /* Add the content of this block to the matrix list */
206 for(unsigned int i=4; i<ECATBLKSIZE/4; i+=4) if(dirbuf[i]>0) {
207 ml->matdir[ml->matrixNr].id=dirbuf[i];
208 ml->matdir[ml->matrixNr].strtblk=dirbuf[i+1];
209 ml->matdir[ml->matrixNr].endblk=dirbuf[i+2];
210 ml->matdir[ml->matrixNr].status=dirbuf[i+3];
211 if(verbose>3) {
212 printf("matnum=%u strtblk=%u endblk=%u matstat=%u matrixNr=%u\n",
213 ml->matdir[ml->matrixNr].id, ml->matdir[ml->matrixNr].strtblk,
214 ml->matdir[ml->matrixNr].endblk, ml->matdir[ml->matrixNr].status,
215 ml->matrixNr);
216 }
217 /* verify that referred data block can be found in the file */
218 fpos_t current_fp; fgetpos(fp, &current_fp); // save current file position
219 int ret=fseeko(fp, (off_t)(ml->matdir[ml->matrixNr].endblk-1)*ECATBLKSIZE, SEEK_SET);
220 fsetpos(fp, &current_fp); // back to saved file position
221 if(ret==0) { // end block can be found
222 ml->matrixNr++; // save this matrix into the list
223 } else { // not found, file probably broken
224 if(verbose>0) {
225 printf("matnum %d points to data outside of file.\n", ml->matdir[ml->matrixNr].id);
226 fflush(stdout);
227 }
228 // matrixNr not incremented, thus this matrix is left out of the list
229 }
230 }
231 blk=blkNext;
232 } while(feof(fp)==0 && blk>2);
233
234 if(ml->matrixNr==0) {
235 ecatMListFree(ml);
236 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
237 return(TPCERROR_NO_DATA);
238 }
239 if(verbose>1) printf(" matrixNr := %u\n", ml->matrixNr);
240
241 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
242 return(TPCERROR_OK);
243}
244/*****************************************************************************/
245
246/*****************************************************************************/
252 int format,
254 ECAT_MATRIXLIST *ml,
256 FILE *fp
257) {
258 if(ml==NULL || fp==NULL) return;
259 ECAT_MATVAL mv;
260
261 fprintf(fp, "nr\tmatrix\tpl\tfr\tgate\tbed\tstartblk\tblknr\n");
262 for(unsigned int i=0; i<ml->matrixNr; i++) {
263 ecatMListReadId(format, ml->matdir[i].id, &mv);
264 fprintf(fp, "%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\n", i+1, ml->matdir[i].id,
265 mv.plane, mv.frame, mv.gate, mv.bed,
266 ml->matdir[i].strtblk, 1+ml->matdir[i].endblk-ml->matdir[i].strtblk);
267 }
268 return;
269}
270/*****************************************************************************/
271
272/*****************************************************************************/
int ecatReadBlock(const char *filename, FILE *fp, const unsigned int blocknumber, unsigned char *data)
Definition ecatio.c:23
void ecatMListPrint(int format, ECAT_MATRIXLIST *ml, FILE *fp)
void ecatMListFree(ECAT_MATRIXLIST *ml)
void ecatMListReadId(int format, unsigned int id, ECAT_MATVAL *mv)
int ecatMListRead(int format, FILE *fp, ECAT_MATRIXLIST *ml, TPCSTATUS *status)
void ecatMListInit(ECAT_MATRIXLIST *ml)
unsigned int ecatMValToId(int format, ECAT_MATVAL *mv)
unsigned int ecatMListMakeId(int format, unsigned int frame, unsigned int plane, unsigned int gate, unsigned int data, unsigned int bed)
int endianLittle()
Definition endian.c:53
void swawbip(void *buf, int size)
Definition endian.c:138
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
unsigned int endblk
Definition tpcecat.h:46
unsigned int id
Definition tpcecat.h:42
unsigned int strtblk
Definition tpcecat.h:44
int status
Definition tpcecat.h:48
ECAT_MATDIR * matdir
Definition tpcecat.h:58
unsigned int matrixNr
Definition tpcecat.h:54
unsigned int matrixSpace
Definition tpcecat.h:56
unsigned int gate
Definition tpcecat.h:68
unsigned int plane
Definition tpcecat.h:66
unsigned int frame
Definition tpcecat.h:64
unsigned int data
Definition tpcecat.h:70
unsigned int bed
Definition tpcecat.h:72
int verbose
Verbose level, used by statusPrint() etc.
Header file for libtpcecat.
#define ECATBLKSIZE
Definition tpcecat.h:37
Header file for library libtpcextensions.
@ TPCERROR_FAIL
General error.
@ TPCERROR_OUT_OF_MEMORY
Cannot allocate memory.
@ TPCERROR_OK
No error.
@ TPCERROR_NO_DATA
File contains no data.
Header file for library libtpcift.