]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RAW/AliRawReaderDateV3.cxx
Fixing bugs in FMD reconstruction. Everything should work now
[u/mrichter/AliRoot.git] / RAW / AliRawReaderDateV3.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 ///
20 /// This is a class for reading raw data from a date file or event (version 3).
21 ///
22 /// The AliRawReaderDateV3 is constructed either with a pointer to a
23 /// date event or with a file name and an event number.
24 ///
25 ///////////////////////////////////////////////////////////////////////////////
26
27 #include "AliRawReaderDateV3.h"
28
29 struct eventHeaderStruct { 
30   Int_t  size;          /* size of event in Bytes  */
31   UInt_t magic;         /* magic number used for consistency check */
32   UInt_t type;          /* event type */
33   UInt_t headLen;       /* size of header in bytes */
34   UInt_t runNb;         /* run number */
35   UInt_t burstNb;       /* burst number */
36   UInt_t nbInRun;       /* event number in run */
37   UInt_t nbInBurst;     /* event number in burst */
38   UInt_t triggerNb;     /* trigger number for this detector */
39   UInt_t fileSeqNb;     /* file sequence number for multifiles run */
40   UInt_t detectorId[3]; /* detector identification */
41   UInt_t time;          /* time in seconds since 0.00 GMT 1.1.1970 */
42   UInt_t usec;          /* microseconds */
43   UInt_t errorCode;
44   UInt_t deadTime;
45   UInt_t deadTimeusec;
46   UInt_t typeAttribute[2]; /* event type id mask */
47 };
48
49 #define EVENT_MAGIC_NUMBER         ((UInt_t)0xDA1E5AFE)
50
51
52 ClassImp(AliRawReaderDateV3)
53
54
55 AliRawReaderDateV3::AliRawReaderDateV3(void* event) :
56   fFile(NULL),
57   fEvent(NULL),
58   fSubEvent(NULL),
59   fPosition(NULL),
60   fEnd(NULL)
61 {
62 // create an object to read digits from the given date event
63
64   fEvent = (eventHeaderStruct*) event;
65 }
66
67 AliRawReaderDateV3::AliRawReaderDateV3(const char* fileName, 
68                                        Int_t eventNumber) :
69   fFile(NULL),
70   fEvent(NULL),
71   fSubEvent(NULL),
72   fPosition(NULL),
73   fEnd(NULL)
74 {
75 // create an object to read digits from the given date event
76
77   fFile = fopen(fileName, "rb");
78   if (!fFile) {
79     Error("AliRawReaderDateV3", "could not open file %s", fileName);
80     fIsValid = kFALSE;
81     return;
82   }
83   if (eventNumber < 0) return;
84
85   eventHeaderStruct header;
86   UInt_t headerSize = sizeof(eventHeaderStruct);
87   while (fread(&header, 1, headerSize, fFile) == headerSize) {
88     if (eventNumber == 0) {
89       UChar_t* buffer = new UChar_t[header.size];
90       fseek(fFile, -(long)headerSize, SEEK_CUR);
91       if (Int_t(fread(buffer, 1, header.size, fFile)) != header.size) break;
92       fEvent = (eventHeaderStruct*) buffer;
93       break;
94     }
95     fseek(fFile, header.size-headerSize, SEEK_CUR);
96     eventNumber--;
97   }
98 }
99
100 AliRawReaderDateV3::AliRawReaderDateV3(const AliRawReaderDateV3& rawReader) :
101   AliRawReader(rawReader),
102   fFile(rawReader.fFile),
103   fEvent(rawReader.fEvent),
104   fSubEvent(rawReader.fSubEvent),
105   fPosition(rawReader.fPosition),
106   fEnd(rawReader.fEnd)
107
108 {
109 // copy constructor
110
111   Fatal("AliRawReaderDateV3", "copy constructor not implemented");
112 }
113
114 AliRawReaderDateV3& AliRawReaderDateV3::operator = (const AliRawReaderDateV3& 
115                                                 /*rawReader*/)
116 {
117 // assignment operator
118
119   Fatal("operator =", "assignment operator not implemented");
120   return *this;
121 }
122
123 AliRawReaderDateV3::~AliRawReaderDateV3()
124 {
125 // destructor
126
127   if (fFile) {
128     delete[] fEvent;
129     fclose(fFile);
130   }
131 }
132
133
134 UInt_t AliRawReaderDateV3::GetType() const
135 {
136 // get the type from the event header
137
138   if (!fEvent) return 0;
139   return fEvent->type;
140 }
141
142 UInt_t AliRawReaderDateV3::GetRunNumber() const
143 {
144 // get the run number from the event header
145
146   if (!fEvent) return 0;
147   return fEvent->runNb;
148 }
149
150 const UInt_t* AliRawReaderDateV3::GetEventId() const
151 {
152 // get the event id from the event header
153
154   if (!fEvent) return NULL;
155   return &(fEvent->nbInRun);
156 }
157
158 const UInt_t* AliRawReaderDateV3::GetTriggerPattern() const
159 {
160 // get the trigger pattern from the event header
161
162   return NULL;
163 }
164
165 const UInt_t* AliRawReaderDateV3::GetDetectorPattern() const
166 {
167 // get the detector pattern from the event header
168
169   if (!fEvent) return NULL;
170   return fEvent->detectorId;
171 }
172
173 const UInt_t* AliRawReaderDateV3::GetAttributes() const
174 {
175 // get the type attributes from the event header
176
177   if (!fEvent) return NULL;
178   return fEvent->typeAttribute;
179 }
180
181 const UInt_t* AliRawReaderDateV3::GetSubEventAttributes() const
182 {
183 // get the type attributes from the sub event header
184
185   if (!fSubEvent) return NULL;
186   return fSubEvent->typeAttribute;
187 }
188
189 UInt_t AliRawReaderDateV3::GetLDCId() const
190 {
191 // get the LDC Id from the event header
192
193   return UInt_t(-1);
194 }
195
196 UInt_t AliRawReaderDateV3::GetGDCId() const
197 {
198 // get the GDC Id from the event header
199
200   return UInt_t(-1);
201 }
202
203 UInt_t AliRawReaderDateV3::GetTimestamp() const
204 {
205 // get the timestamp from the event header
206
207   if (!fEvent) return 0;
208   return fEvent->time;
209 }
210
211 Int_t AliRawReaderDateV3::GetEquipmentSize() const
212 {
213 // get the size of the equipment
214
215   if (!fSubEvent) return 0;
216   return fSubEvent->size;
217 }
218
219 Int_t AliRawReaderDateV3::GetEquipmentType() const
220 {
221 // get the type from the equipment header
222
223   return 0;
224 }
225
226 Int_t AliRawReaderDateV3::GetEquipmentId() const
227 {
228 // get the ID from the equipment header
229
230   return 0;
231 }
232
233 const UInt_t* AliRawReaderDateV3::GetEquipmentAttributes() const
234 {
235 // get the attributes from the equipment header
236
237   return 0;
238 }
239
240 Int_t AliRawReaderDateV3::GetEquipmentElementSize() const
241 {
242 // get the basic element size from the equipment header
243
244   return 0;
245 }
246
247 Int_t AliRawReaderDateV3::GetEquipmentHeaderSize() const
248 {
249 // get the size of the equipment header
250
251   return 0;
252 }
253
254 Bool_t AliRawReaderDateV3::ReadHeader()
255 {
256 // read a data header at the current position
257 // returns kFALSE if the data header could not be read
258
259   fErrorCode = 0;
260
261   fHeader = NULL;
262   if (!fEvent) return kFALSE;
263   // check whether there are sub events
264   if (fEvent->size <= Int_t(fEvent->headLen)) return kFALSE;
265
266   do {
267     // skip payload (if event was not selected)
268     if (fCount > 0) fPosition += fCount;
269
270     // check for end of event data
271     if (fPosition >= ((UChar_t*)fEvent)+fEvent->size) return kFALSE;
272     if ((fEvent->detectorId[2] & 0x8000) != 0x8000) {
273       fSubEvent = fEvent;   // no super event
274     } else if (fSubEvent) {
275       fSubEvent = (eventHeaderStruct*) (((UChar_t*)fSubEvent) + 
276                                         fSubEvent->size);
277     } else {
278       fSubEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) + 
279                                         fEvent->headLen);
280     }
281
282     // check the magic word of the sub event
283     if (fSubEvent->magic != EVENT_MAGIC_NUMBER) {
284       Error("ReadHeader", "wrong magic number in sub event!\n"
285             " run: %d  event: %d\n", 
286             fSubEvent->runNb, fSubEvent->nbInRun);
287       fErrorCode = kErrMagic;
288       return kFALSE;
289     }
290
291     // continue if no data in the subevent
292     if (fSubEvent->size == Int_t(fSubEvent->headLen)) {
293       fPosition = fEnd = ((UChar_t*)fSubEvent) + fSubEvent->size;
294       fCount = 0;
295       continue;
296     }
297
298     fCount = 0;
299     fPosition = ((UChar_t*)fSubEvent) + sizeof(eventHeaderStruct);
300     fEnd = ((UChar_t*)fSubEvent) + fSubEvent->size;
301
302     // continue with the next sub event if no data left in the payload
303     if (fPosition >= fEnd) continue;
304
305     if (fRequireHeader) {
306       // check that there are enough bytes left for the data header
307       if (fPosition + sizeof(AliRawDataHeader) > fEnd) {
308         Error("ReadHeader", "could not read data header data!");
309         Warning("ReadHeader", "skipping %d bytes\n"
310                 " run: %d  event: %d\n", 
311                 fEnd - fPosition, fSubEvent->runNb, fSubEvent->nbInRun);
312         fCount = 0;
313         fPosition = fEnd;
314         fErrorCode = kErrNoDataHeader;
315         continue;
316       }
317
318       // "read" the data header
319       fHeader = (AliRawDataHeader*) fPosition;
320       if ((fPosition + fHeader->fSize) != fEnd) {
321         if (fHeader->fSize != 0xFFFFFFFF)
322           Warning("ReadHeader",
323                   "raw data size found in the header is wrong (%d != %d)! Using the equipment size instead !",
324                   fHeader->fSize, fEnd - fPosition);
325         fHeader->fSize = fEnd - fPosition;
326       }
327       fPosition += sizeof(AliRawDataHeader);
328     }
329
330     if (fHeader && (fHeader->fSize != 0xFFFFFFFF)) {
331       fCount = fHeader->fSize - sizeof(AliRawDataHeader);
332
333       // check consistency of data size in the header and in the sub event
334       if (fPosition + fCount > fEnd) {
335         Error("ReadHeader", "size in data header exceeds event size!");
336         Warning("ReadHeader", "skipping %d bytes\n"
337                 " run: %d  event: %d\n", 
338                 fEnd - fPosition, fSubEvent->runNb, fSubEvent->nbInRun);
339         fCount = 0;
340         fPosition = fEnd;
341         fErrorCode = kErrSize;
342         continue;
343       }
344
345     } else {
346       fCount = fEnd - fPosition;
347     }
348
349   } while (!IsSelected());
350
351   return kTRUE;
352 }
353
354 Bool_t AliRawReaderDateV3::ReadNextData(UChar_t*& data)
355 {
356 // reads the next payload at the current position
357 // returns kFALSE if the data could not be read
358
359   fErrorCode = 0;
360   while (fCount == 0) {
361     if (!ReadHeader()) return kFALSE;
362   }
363   data = fPosition;
364   fPosition += fCount;  
365   fCount = 0;
366   return kTRUE;
367 }
368
369 Bool_t AliRawReaderDateV3::ReadNext(UChar_t* data, Int_t size)
370 {
371 // reads the next block of data at the current position
372 // returns kFALSE if the data could not be read
373
374   fErrorCode = 0;
375   if (fPosition + size > fEnd) {
376     Error("ReadNext", "could not read data!");
377     fErrorCode = kErrOutOfBounds;
378     return kFALSE;
379   }
380   memcpy(data, fPosition, size);
381   fPosition += size;
382   fCount -= size;
383   return kTRUE;
384 }
385
386
387 Bool_t AliRawReaderDateV3::Reset()
388 {
389 // reset the current position to the beginning of the event
390
391   fSubEvent = NULL;
392   fCount = 0;
393   fPosition = fEnd = NULL;
394   return kTRUE;
395 }
396
397
398 Bool_t AliRawReaderDateV3::NextEvent()
399 {
400 // go to the next event in the date file
401
402   if (!fFile) return kFALSE;
403
404   Reset();
405   eventHeaderStruct header;
406   UInt_t headerSize = sizeof(eventHeaderStruct);
407   if (fEvent) delete[] fEvent;
408   fEvent = &header;
409
410   while (fread(&header, 1, headerSize, fFile) == headerSize) {
411     if (!IsEventSelected()) {
412       fseek(fFile, header.size-headerSize, SEEK_CUR);
413       continue;
414     }
415     UChar_t* buffer = new UChar_t[header.size];
416     fseek(fFile, -(long)headerSize, SEEK_CUR);
417     if (Int_t(fread(buffer, 1, header.size, fFile)) != header.size) {
418       Error("NextEvent", "could not read event from file");
419       delete[] buffer;
420       break;
421     }
422     fEvent = (eventHeaderStruct*) buffer;
423     fEventNumber++;
424     return kTRUE;
425   };
426
427   fEvent = NULL;
428   return kFALSE;
429 }
430
431 Bool_t AliRawReaderDateV3::RewindEvents()
432 {
433 // go back to the beginning of the date file
434
435   if (!fFile) return kFALSE;
436
437   fseek(fFile, 0, SEEK_SET);
438   fEventNumber = -1;
439   return Reset();
440 }
441
442
443 Int_t AliRawReaderDateV3::CheckData() const
444 {
445 // check the consistency of the data
446
447   if (!fEvent) return 0;
448   // check whether there are sub events
449   if (fEvent->size <= Int_t(fEvent->headLen)) return 0;
450
451   eventHeaderStruct* subEvent = NULL;
452   UChar_t* position = 0;
453   UChar_t* end = 0;
454   Int_t result = 0;
455
456   while (kTRUE) {
457     // check for end of event data
458     if (position >= ((UChar_t*)fEvent)+fEvent->size) return result;
459     if ((fEvent->detectorId[2] & 0x8000) != 0x8000) {
460       subEvent = fEvent;   // no super event
461     } else if (subEvent) {
462       subEvent = (eventHeaderStruct*) (((UChar_t*)subEvent) + 
463                                        subEvent->size);
464     } else {
465       subEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) + 
466                                        fEvent->headLen);
467     }
468
469     // check the magic word of the sub event
470     if (subEvent->magic != EVENT_MAGIC_NUMBER) {
471       result |= kErrMagic;
472       return result;
473     }
474
475     position = ((UChar_t*)subEvent) + subEvent->headLen;
476     end = ((UChar_t*)subEvent) + subEvent->size;
477
478     // continue with the next sub event if no data left in the payload
479     if (position >= end) continue;
480
481     if (fRequireHeader) {
482       // check that there are enough bytes left for the data header
483       if (position + sizeof(AliRawDataHeader) > end) {
484         result |= kErrNoDataHeader;
485         position = end;
486         continue;
487       }
488
489       // check consistency of data size in the data header and in the sub event
490       AliRawDataHeader* header = (AliRawDataHeader*) position;
491       if ((position + header->fSize) != end) {
492         if (header->fSize != 0xFFFFFFFF)
493           Warning("ReadHeader",
494                   "raw data size found in the header is wrong (%d != %d)! Using the equipment size instead !",
495                   header->fSize, end - position);
496         header->fSize = end - position;
497         result |= kErrSize;
498       }
499     }
500     position = end;
501   };
502
503   return 0;
504 }