]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RAW/AliRawReaderDate.cxx
fix for equipment size
[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 (without header)
254
255 #ifdef ALI_DATE
256   if (!fEquipment) return 0;
257   if (fSubEvent->eventVersion <= 0x00030001) {
258     return fEquipment->equipmentSize;
259   } else {
260     return fEquipment->equipmentSize - sizeof(equipmentHeaderStruct);
261   }
262 #else
263   return 0;
264 #endif
265 }
266
267 Int_t AliRawReaderDate::GetEquipmentType() const
268 {
269 // get the type from the equipment header
270
271 #ifdef ALI_DATE
272   if (!fEquipment) return -1;
273   return fEquipment->equipmentType;
274 #else
275   return 0;
276 #endif
277 }
278
279 Int_t AliRawReaderDate::GetEquipmentId() const
280 {
281 // get the ID from the equipment header
282
283 #ifdef ALI_DATE
284   if (!fEquipment) return -1;
285   return fEquipment->equipmentId;
286 #else
287   return 0;
288 #endif
289 }
290
291 const UInt_t* AliRawReaderDate::GetEquipmentAttributes() const
292 {
293 // get the attributes from the equipment header
294
295 #ifdef ALI_DATE
296   if (!fEquipment) return NULL;
297   return fEquipment->equipmentTypeAttribute;
298 #else
299   return 0;
300 #endif
301 }
302
303 Int_t AliRawReaderDate::GetEquipmentElementSize() const
304 {
305 // get the basic element size from the equipment header
306
307 #ifdef ALI_DATE
308   if (!fEquipment) return 0;
309   return fEquipment->equipmentBasicElementSize;
310 #else
311   return 0;
312 #endif
313 }
314
315
316 Bool_t AliRawReaderDate::ReadHeader()
317 {
318 // read a data header at the current position
319 // returns kFALSE if the data header could not be read
320
321   fErrorCode = 0;
322
323 #ifdef ALI_DATE
324   fHeader = NULL;
325   if (!fEvent) return kFALSE;
326   // check whether there are sub events
327   if (fEvent->eventSize <= fEvent->eventHeadSize) return kFALSE;
328
329   do {
330     // skip payload (if event was not selected)
331     if (fCount > 0) fPosition += fCount;
332
333     // get the first or the next equipment if at the end of an equipment
334     if (!fEquipment || (fPosition >= fEnd)) {
335       fEquipment = NULL;
336
337       // get the first or the next sub event if at the end of a sub event
338       if (!fSubEvent || 
339           (fPosition >= ((UChar_t*)fSubEvent) + fSubEvent->eventSize)) {
340
341         // check for end of event data
342         if (fPosition >= ((UChar_t*)fEvent)+fEvent->eventSize) return kFALSE;
343         if (!TEST_SYSTEM_ATTRIBUTE(fEvent->eventTypeAttribute, 
344                                    ATTR_SUPER_EVENT)) {
345           fSubEvent = fEvent;   // no super event
346         } else if (fSubEvent) {
347           fSubEvent = (eventHeaderStruct*) (((UChar_t*)fSubEvent) + 
348                                             fSubEvent->eventSize);
349         } else {
350           fSubEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) + 
351                                             fEvent->eventHeadSize);
352         }
353
354         // check the magic word of the sub event
355         if (fSubEvent->eventMagic != EVENT_MAGIC_NUMBER) {
356           Error("ReadHeader", "wrong magic number in sub event!\n"
357                 " run: %d  event: %d %d  LDC: %d  GDC: %d\n", 
358                 fSubEvent->eventRunNb, 
359                 fSubEvent->eventId[0], fSubEvent->eventId[1],
360                 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
361           fErrorCode = kErrMagic;
362           return kFALSE;
363         }
364
365         // continue if no data in the subevent
366         if (fSubEvent->eventSize == fSubEvent->eventHeadSize) {
367           fPosition = fEnd = ((UChar_t*)fSubEvent) + fSubEvent->eventSize;
368           fCount = 0;
369           continue;
370         }
371
372         fEquipment = (equipmentHeaderStruct*)
373           (((UChar_t*)fSubEvent) + fSubEvent->eventHeadSize);
374
375       } else {
376         fEquipment = (equipmentHeaderStruct*) fEnd;
377       }
378
379       fCount = 0;
380       fPosition = ((UChar_t*)fEquipment) + sizeof(equipmentHeaderStruct);
381       if (fSubEvent->eventVersion <= 0x00030001) {
382         fEnd = fPosition + fEquipment->equipmentSize;
383       } else {
384         fEnd = ((UChar_t*)fEquipment) + fEquipment->equipmentSize;
385       }
386     }
387
388     // continue with the next sub event if no data left in the payload
389     if (fPosition >= fEnd) continue;
390
391     if (fRequireHeader) {
392       // check that there are enough bytes left for the data header
393       if (fPosition + sizeof(AliRawDataHeader) > fEnd) {
394         Error("ReadHeader", "could not read data header data!");
395         Warning("ReadHeader", "skipping %d bytes\n"
396                 " run: %d  event: %d %d  LDC: %d  GDC: %d\n", 
397                 fEnd - fPosition, fSubEvent->eventRunNb, 
398                 fSubEvent->eventId[0], fSubEvent->eventId[1],
399                 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
400         fCount = 0;
401         fPosition = fEnd;
402         fErrorCode = kErrNoDataHeader;
403         continue;
404       }
405
406       // "read" the data header
407       fHeader = (AliRawDataHeader*) fPosition;
408       fPosition += sizeof(AliRawDataHeader);
409     }
410
411     if (fHeader && (fHeader->fSize != 0xFFFFFFFF)) {
412       fCount = fHeader->fSize - sizeof(AliRawDataHeader);
413
414       // check consistency of data size in the header and in the sub event
415       if (fPosition + fCount > fEnd) {
416         Error("ReadHeader", "size in data header exceeds event size!");
417         Warning("ReadHeader", "skipping %d bytes\n"
418                 " run: %d  event: %d %d  LDC: %d  GDC: %d\n", 
419                 fEnd - fPosition, fSubEvent->eventRunNb, 
420                 fSubEvent->eventId[0], fSubEvent->eventId[1],
421                 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
422         fCount = 0;
423         fPosition = fEnd;
424         fErrorCode = kErrSize;
425         continue;
426       }
427
428     } else {
429       fCount = fEnd - fPosition;
430     }
431
432   } while (!fEquipment || !IsSelected());
433
434   return kTRUE;
435 #else
436   return kFALSE;
437 #endif
438 }
439
440 Bool_t AliRawReaderDate::ReadNextData(UChar_t*& data)
441 {
442 // reads the next payload at the current position
443 // returns kFALSE if the data could not be read
444
445   fErrorCode = 0;
446   while (fCount == 0) {
447     if (!ReadHeader()) return kFALSE;
448   }
449   data = fPosition;
450   fPosition += fCount;  
451   fCount = 0;
452   return kTRUE;
453 }
454
455 Bool_t AliRawReaderDate::ReadNext(UChar_t* data, Int_t size)
456 {
457 // reads the next block of data at the current position
458 // returns kFALSE if the data could not be read
459
460   fErrorCode = 0;
461   if (fPosition + size > fEnd) {
462     Error("ReadNext", "could not read data!");
463     fErrorCode = kErrOutOfBounds;
464     return kFALSE;
465   }
466   memcpy(data, fPosition, size);
467   fPosition += size;
468   fCount -= size;
469   return kTRUE;
470 }
471
472
473 Bool_t AliRawReaderDate::Reset()
474 {
475 // reset the current position to the beginning of the event
476
477 #ifdef ALI_DATE
478   fSubEvent = NULL;
479   fEquipment = NULL;
480 #endif
481   fCount = 0;
482   fPosition = fEnd = NULL;
483   return kTRUE;
484 }
485
486
487 Bool_t AliRawReaderDate::NextEvent()
488 {
489 // go to the next event in the date file
490
491 #ifdef ALI_DATE
492   if (!fFile) return kFALSE;
493
494   Reset();
495   eventHeaderStruct header;
496   UInt_t headerSize = sizeof(eventHeaderStruct);
497   if (fEvent) delete[] fEvent;
498   fEvent = &header;
499
500   while (fread(&header, 1, headerSize, fFile) == headerSize) {
501     if (!IsEventSelected()) {
502       fseek(fFile, header.eventSize-headerSize, SEEK_CUR);
503       continue;
504     }
505     UChar_t* buffer = new UChar_t[header.eventSize];
506     fseek(fFile, -headerSize, SEEK_CUR);
507     if (fread(buffer, 1, header.eventSize, fFile) != header.eventSize) {
508       Error("NextEvent", "could not read event from file");
509       delete[] buffer;
510       break;
511     }
512     fEvent = (eventHeaderStruct*) buffer;
513     return kTRUE;
514   };
515
516   fEvent = NULL;
517 #endif
518
519   return kFALSE;
520 }
521
522 Bool_t AliRawReaderDate::RewindEvents()
523 {
524 // go back to the beginning of the date file
525
526   if (!fFile) return kFALSE;
527
528   fseek(fFile, 0, SEEK_SET);
529   return Reset();
530 }
531
532
533 Int_t AliRawReaderDate::CheckData() const
534 {
535 // check the consistency of the data
536
537 #ifdef ALI_DATE
538   if (!fEvent) return 0;
539   // check whether there are sub events
540   if (fEvent->eventSize <= fEvent->eventHeadSize) return 0;
541
542   eventHeaderStruct* subEvent = NULL;
543   UChar_t* position = 0;
544   UChar_t* end = 0;
545   Int_t result = 0;
546
547   while (kTRUE) {
548     // get the first or the next sub event if at the end of a sub event
549     if (!subEvent || (position >= end)) {
550
551       // check for end of event data
552       if (position >= ((UChar_t*)fEvent)+fEvent->eventSize) return result;
553       if (!TEST_SYSTEM_ATTRIBUTE(fEvent->eventTypeAttribute, 
554                                  ATTR_SUPER_EVENT)) {
555         subEvent = fEvent;   // no super event
556       } else if (subEvent) {
557         subEvent = (eventHeaderStruct*) (((UChar_t*)subEvent) + 
558                                          subEvent->eventSize);
559       } else {
560         subEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) + 
561                                          fEvent->eventHeadSize);
562       }
563
564       // check the magic word of the sub event
565       if (subEvent->eventMagic != EVENT_MAGIC_NUMBER) {
566         result |= kErrMagic;
567         return result;
568       }
569
570       position = ((UChar_t*)subEvent) + subEvent->eventHeadSize + 
571         sizeof(equipmentHeaderStruct);
572       end = ((UChar_t*)subEvent) + subEvent->eventSize;
573     }
574
575     // continue with the next sub event if no data left in the payload
576     if (position >= end) continue;
577
578     // check that there are enough bytes left for the data header
579     if (position + sizeof(AliRawDataHeader) > end) {
580       result |= kErrNoDataHeader;
581       position = end;
582       continue;
583     }
584
585     // check consistency of data size in the data header and in the sub event
586     AliRawDataHeader* header = (AliRawDataHeader*) position;
587     if (header->fSize != 0xFFFFFFFF) {
588       if (position + header->fSize > end) {
589         result |= kErrSize;
590         position = end;
591       } else {
592         position += header->fSize;
593       }
594     } else {
595       position = end;
596     }
597   };
598
599 #endif
600   return 0;
601 }