readers updated (mini header -> data header)
[u/mrichter/AliRoot.git] / RAW / AliRawReaderDate.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 ///////////////////////////////////////////////////////////////////////////////
17 //
18 // This is a class for reading a raw data from a date event and providing
19 // information about digits
20 //
21 ///////////////////////////////////////////////////////////////////////////////
22
23 #include "AliRawReaderDate.h"
24 #ifdef ALI_DATE
25 #include "event.h"
26 #endif
27
28 ClassImp(AliRawReaderDate)
29
30
31 AliRawReaderDate::AliRawReaderDate(
32 #ifdef ALI_DATE
33                                    void* event
34 #else
35                                    void* /* event */
36 #endif
37                                    ) :
38   fRequireHeader(kTRUE),
39   fEvent(NULL),
40   fSubEvent(NULL),
41   fEquipment(NULL),
42   fIsOwner(kFALSE),
43   fPosition(NULL),
44   fEnd(NULL)
45 {
46 // create an object to read digits from the given date event
47
48 #ifdef ALI_DATE
49   fEvent = (eventHeaderStruct*) event;
50 #else
51   Fatal("AliRawReaderDate", "this class was compiled without DATE");
52 #endif
53 }
54
55 AliRawReaderDate::AliRawReaderDate(
56 #ifdef ALI_DATE
57                                    const char* fileName, Int_t eventNumber
58 #else
59                                    const char* /*fileName*/, 
60                                    Int_t /*eventNumber*/
61 #endif
62                                    ) :
63   fRequireHeader(kTRUE),
64   fEvent(NULL),
65   fSubEvent(NULL),
66   fEquipment(NULL),
67   fIsOwner(kFALSE),
68   fPosition(NULL),
69   fEnd(NULL)
70 {
71 // create an object to read digits from the given date event
72
73 #ifdef ALI_DATE
74   FILE* file = fopen(fileName, "rb");
75   if (!file) {
76     Error("AliRawReaderDate", "could not open file %s", fileName);
77     return;
78   }
79   eventHeaderStruct header;
80   UInt_t headerSize = sizeof(eventHeaderStruct);
81   while (fread(&header, 1, headerSize, file) == headerSize) {
82     if (eventNumber == 0) {
83       UChar_t* buffer = new UChar_t[header.eventSize];
84       fseek(file, -headerSize, SEEK_CUR);
85       if (fread(buffer, 1, header.eventSize, file) != header.eventSize) break;
86       fEvent = (eventHeaderStruct*) buffer;
87       fIsOwner = kTRUE;
88       break;
89     }
90     fseek(file, header.eventSize-headerSize, SEEK_CUR);
91     eventNumber--;
92   }
93   fclose(file);
94
95 #else
96   Fatal("AliRawReaderDate", "this class was compiled without DATE");
97 #endif
98 }
99
100 AliRawReaderDate::AliRawReaderDate(const AliRawReaderDate& rawReader) :
101   AliRawReader(rawReader),
102   fRequireHeader(rawReader.fRequireHeader),
103   fEvent(rawReader.fEvent),
104   fSubEvent(rawReader.fSubEvent),
105   fEquipment(rawReader.fEquipment),
106   fIsOwner(kFALSE),
107   fPosition(rawReader.fPosition),
108   fEnd(rawReader.fEnd)
109
110 {
111 // copy constructor
112
113 }
114
115 AliRawReaderDate& AliRawReaderDate::operator = (const AliRawReaderDate& 
116                                                 rawReader)
117 {
118 // assignment operator
119
120   this->~AliRawReaderDate();
121   new(this) AliRawReaderDate(rawReader);
122   return *this;
123 }
124
125 AliRawReaderDate::~AliRawReaderDate()
126 {
127 // destructor
128
129 #ifdef ALI_DATE
130   if (fIsOwner) delete[] fEvent;
131 #endif
132 }
133
134
135 UInt_t AliRawReaderDate::GetType() const
136 {
137 // get the type from the event header
138
139 #ifdef ALI_DATE
140   if (!fEvent) return 0;
141   return fEvent->eventType;
142 #else
143   return 0;
144 #endif
145 }
146
147 UInt_t AliRawReaderDate::GetRunNumber() const
148 {
149 // get the run number from the event header
150
151 #ifdef ALI_DATE
152   if (!fEvent) return 0;
153   return fEvent->eventRunNb;
154 #else
155   return 0;
156 #endif
157 }
158
159 const UInt_t* AliRawReaderDate::GetEventId() const
160 {
161 // get the event id from the event header
162
163 #ifdef ALI_DATE
164   if (!fEvent) return NULL;
165   return fEvent->eventId;
166 #else
167   return NULL;
168 #endif
169 }
170
171 const UInt_t* AliRawReaderDate::GetTriggerPattern() const
172 {
173 // get the trigger pattern from the event header
174
175 #ifdef ALI_DATE
176   if (!fEvent) return NULL;
177   return fEvent->eventTriggerPattern;
178 #else
179   return NULL;
180 #endif
181 }
182
183 const UInt_t* AliRawReaderDate::GetDetectorPattern() const
184 {
185 // get the detector pattern from the event header
186
187 #ifdef ALI_DATE
188   if (!fEvent) return NULL;
189   return fEvent->eventDetectorPattern;
190 #else
191   return NULL;
192 #endif
193 }
194
195 const UInt_t* AliRawReaderDate::GetAttributes() const
196 {
197 // get the type attributes from the event header
198
199 #ifdef ALI_DATE
200   if (!fEvent) return NULL;
201   return fEvent->eventTypeAttribute;
202 #else
203   return NULL;
204 #endif
205 }
206
207 UInt_t AliRawReaderDate::GetLDCId() const
208 {
209 // get the LDC Id from the event header
210
211 #ifdef ALI_DATE
212   if (!fSubEvent) return 0;
213   return fSubEvent->eventLdcId;
214 #else
215   return 0;
216 #endif
217 }
218
219 UInt_t AliRawReaderDate::GetGDCId() const
220 {
221 // get the GDC Id from the event header
222
223 #ifdef ALI_DATE
224   if (!fEvent) return 0;
225   return fEvent->eventGdcId;
226 #else
227   return 0;
228 #endif
229 }
230
231
232 Int_t AliRawReaderDate::GetEquipmentSize() const
233 {
234 // get the size of the equipment
235
236 #ifdef ALI_DATE
237   if (!fEquipment) return 0;
238   return fEquipment->equipmentSize;
239 #else
240   return 0;
241 #endif
242 }
243
244 Int_t AliRawReaderDate::GetEquipmentType() const
245 {
246 // get the type from the equipment header
247
248 #ifdef ALI_DATE
249   if (!fEquipment) return -1;
250   return fEquipment->equipmentType;
251 #else
252   return 0;
253 #endif
254 }
255
256 Int_t AliRawReaderDate::GetEquipmentId() const
257 {
258 // get the ID from the equipment header
259
260 #ifdef ALI_DATE
261   if (!fEquipment) return -1;
262   return fEquipment->equipmentId;
263 #else
264   return 0;
265 #endif
266 }
267
268 const UInt_t* AliRawReaderDate::GetEquipmentAttributes() const
269 {
270 // get the attributes from the equipment header
271
272 #ifdef ALI_DATE
273   if (!fEquipment) return NULL;
274   return fEquipment->equipmentTypeAttribute;
275 #else
276   return 0;
277 #endif
278 }
279
280 Int_t AliRawReaderDate::GetEquipmentElementSize() const
281 {
282 // get the basic element size from the equipment header
283
284 #ifdef ALI_DATE
285   if (!fEquipment) return 0;
286   return fEquipment->equipmentBasicElementSize;
287 #else
288   return 0;
289 #endif
290 }
291
292
293 Bool_t AliRawReaderDate::ReadHeader()
294 {
295 // read a data header at the current position
296 // returns kFALSE if the data header could not be read
297
298   fErrorCode = 0;
299
300 #ifdef ALI_DATE
301   if (!fEvent) return kFALSE;
302   // check whether there are sub events
303   if (fEvent->eventSize <= fEvent->eventHeadSize) return kFALSE;
304
305   do {
306     // skip payload (if event was not selected)
307     if (fCount > 0) fPosition += fCount;
308
309     // get the first or the next equipment if at the end of an equipment
310     if (!fEquipment || (fPosition >= fEnd)) {
311
312       // get the first or the next sub event if at the end of a sub event
313       if (!fSubEvent || 
314           (fPosition >= ((UChar_t*)fSubEvent) + fSubEvent->eventSize)) {
315
316         // check for end of event data
317         if (fPosition >= ((UChar_t*)fEvent)+fEvent->eventSize) return kFALSE;
318         if (fSubEvent) {
319           fSubEvent = (eventHeaderStruct*) (((UChar_t*)fSubEvent) + 
320                                             fSubEvent->eventSize);
321         } else {
322           fSubEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) + 
323                                             fEvent->eventHeadSize);
324         }
325
326         // check the magic word of the sub event
327         if (fSubEvent->eventMagic != EVENT_MAGIC_NUMBER) {
328           Error("ReadHeader", "wrong magic number in sub event!\n"
329                 " run: %d  event: %d %d  LDC: %d  GDC: %d\n", 
330                 fSubEvent->eventRunNb, 
331                 fSubEvent->eventId[0], fSubEvent->eventId[1],
332                 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
333           fErrorCode = kErrMagic;
334           return kFALSE;
335         }
336
337         fEquipment = (equipmentHeaderStruct*)
338           (((UChar_t*)fSubEvent) + fSubEvent->eventHeadSize);
339
340       } else {
341         fEquipment = (equipmentHeaderStruct*) fEnd;
342       }
343
344       fCount = 0;
345       fPosition = ((UChar_t*)fEquipment) + sizeof(equipmentHeaderStruct);
346       fEnd = fPosition + fEquipment->equipmentSize;
347     }
348
349     // continue with the next sub event if no data left in the payload
350     if (fPosition >= fEnd) continue;
351
352     fHeader = NULL;
353     if (fRequireHeader) {
354       // check that there are enough bytes left for the data header
355       if (fPosition + sizeof(AliRawDataHeader) > fEnd) {
356         Error("ReadHeader", "could not read data header data!");
357         Warning("ReadHeader", "skipping %d bytes\n"
358                 " run: %d  event: %d %d  LDC: %d  GDC: %d\n", 
359                 fEnd - fPosition, fSubEvent->eventRunNb, 
360                 fSubEvent->eventId[0], fSubEvent->eventId[1],
361                 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
362         fCount = 0;
363         fPosition = fEnd;
364         fErrorCode = kErrNoDataHeader;
365         continue;
366       }
367
368       // "read" the data header
369       fHeader = (AliRawDataHeader*) fPosition;
370       fPosition += sizeof(AliRawDataHeader);
371     }
372
373     if (fHeader && (fHeader->fSize != 0xFFFFFFFF)) {
374       fCount = fHeader->fSize - sizeof(AliRawDataHeader);
375
376       // check consistency of data size in the header and in the sub event
377       if (fPosition + fCount > fEnd) {
378         Error("ReadHeader", "size in data header exceeds event size!");
379         Warning("ReadHeader", "skipping %d bytes\n"
380                 " run: %d  event: %d %d  LDC: %d  GDC: %d\n", 
381                 fEnd - fPosition, fSubEvent->eventRunNb, 
382                 fSubEvent->eventId[0], fSubEvent->eventId[1],
383                 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
384         fCount = 0;
385         fPosition = fEnd;
386         fErrorCode = kErrSize;
387         continue;
388       }
389
390     } else {
391       fCount = fEnd - fPosition;
392     }
393
394   } while (!IsSelected());
395
396   return kTRUE;
397 #else
398   return kFALSE;
399 #endif
400 }
401
402 Bool_t AliRawReaderDate::ReadNextData(UChar_t*& data)
403 {
404 // reads the next payload at the current position
405 // returns kFALSE if the data could not be read
406
407   fErrorCode = 0;
408   while (fCount == 0) {
409     if (!ReadHeader()) return kFALSE;
410   }
411   data = fPosition;
412   fPosition += fCount;  
413   fCount = 0;
414   return kTRUE;
415 }
416
417 Bool_t AliRawReaderDate::ReadNext(UChar_t* data, Int_t size)
418 {
419 // reads the next block of data at the current position
420 // returns kFALSE if the data could not be read
421
422   fErrorCode = 0;
423   if (fPosition + size > fEnd) {
424     Error("ReadNext", "could not read data!");
425     fErrorCode = kErrOutOfBounds;
426     return kFALSE;
427   }
428   memcpy(data, fPosition, size);
429   fPosition += size;
430   fCount -= size;
431   return kTRUE;
432 }
433
434
435 Bool_t AliRawReaderDate::Reset()
436 {
437 // reset the current position to the beginning of the event
438
439 #ifdef ALI_DATE
440   fSubEvent = NULL;
441 #endif
442   fCount = 0;
443   fPosition = fEnd = NULL;
444   return kTRUE;
445 }
446
447
448 Int_t AliRawReaderDate::CheckData() const
449 {
450 // check the consistency of the data
451
452 #ifdef ALI_DATE
453   if (!fEvent) return 0;
454   // check whether there are sub events
455   if (fEvent->eventSize <= fEvent->eventHeadSize) return 0;
456
457   eventHeaderStruct* subEvent = NULL;
458   UChar_t* position = 0;
459   UChar_t* end = 0;
460   Int_t result = 0;
461
462   while (kTRUE) {
463     // get the first or the next sub event if at the end of a sub event
464     if (!subEvent || (position >= end)) {
465
466       // check for end of event data
467       if (position >= ((UChar_t*)fEvent)+fEvent->eventSize) return result;
468       if (subEvent) {
469         subEvent = (eventHeaderStruct*) (((UChar_t*)subEvent) + 
470                                          subEvent->eventSize);
471       } else {
472         subEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) + 
473                                          fEvent->eventHeadSize);
474       }
475
476       // check the magic word of the sub event
477       if (subEvent->eventMagic != EVENT_MAGIC_NUMBER) {
478         result |= kErrMagic;
479         return result;
480       }
481
482       position = ((UChar_t*)subEvent) + subEvent->eventHeadSize + 
483         sizeof(equipmentHeaderStruct);
484       end = ((UChar_t*)subEvent) + subEvent->eventSize;
485     }
486
487     // continue with the next sub event if no data left in the payload
488     if (position >= end) continue;
489
490     // check that there are enough bytes left for the data header
491     if (position + sizeof(AliRawDataHeader) > end) {
492       result |= kErrNoDataHeader;
493       position = end;
494       continue;
495     }
496
497     // check consistency of data size in the data header and in the sub event
498     AliRawDataHeader* header = (AliRawDataHeader*) position;
499     if (fHeader->fSize != 0xFFFFFFFF) {
500       if (position + header->fSize > end) {
501         result |= kErrSize;
502         position = end;
503       } else {
504         position += header->fSize;
505       }
506     } else {
507       position = end;
508     }
509   };
510
511 #endif
512   return 0;
513 }