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