]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RAW/AliRawReaderDate.cxx
access to equipment header data, reading of DATE files, support of DATE events withou...
[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   fRequireMiniHeader(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   fRequireMiniHeader(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   fRequireMiniHeader(rawReader.fRequireMiniHeader),
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 mini header at the current position
296 // returns kFALSE if the mini 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     fMiniHeader = NULL;
353     if (fRequireMiniHeader) {
354       // check that there are enough bytes left for the mini header
355       if (fPosition + sizeof(AliMiniHeader) > fEnd) {
356         Error("ReadHeader", "could not read mini 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 = kErrNoMiniHeader;
365         continue;
366       }
367
368       // "read" and check the mini header
369       fMiniHeader = (AliMiniHeader*) fPosition;
370       fPosition += sizeof(AliMiniHeader);
371       if (!CheckMiniHeader()) {
372         Error("ReadHeader", "wrong magic word in mini header!");
373         Warning("ReadHeader", "skipping %d bytes\n"
374                 " run: %d  event: %d %d  LDC: %d  GDC: %d\n", 
375                 fEnd - fPosition, fSubEvent->eventRunNb, 
376                 fSubEvent->eventId[0], fSubEvent->eventId[1],
377                 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
378         fCount = 0;
379         fPosition = fEnd;
380         fErrorCode = kErrMiniMagic;
381         continue;
382       }
383
384     } else {  // if mini header not required
385       // assume there is a mini header if the magic word is correct
386       if ((fPosition + sizeof(AliMiniHeader) <= fEnd) &&
387           CheckMiniHeader((AliMiniHeader*) fPosition)) {
388         fMiniHeader = (AliMiniHeader*) fPosition;
389         fPosition += sizeof(AliMiniHeader);
390       }
391     }
392
393     if (fMiniHeader) {
394       fCount = fMiniHeader->fSize;
395
396       // check consistency of data size in the mini header and in the sub event
397       if (fPosition + fCount > fEnd) {
398         Error("ReadHeader", "size in mini header exceeds event size!");
399         Warning("ReadHeader", "skipping %d bytes\n"
400                 " run: %d  event: %d %d  LDC: %d  GDC: %d\n", 
401                 fEnd - fPosition, fSubEvent->eventRunNb, 
402                 fSubEvent->eventId[0], fSubEvent->eventId[1],
403                 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
404         fCount = 0;
405         fPosition = fEnd;
406         fErrorCode = kErrSize;
407         continue;
408       }
409
410     } else {
411       fCount = fEnd - fPosition;
412     }
413
414   } while (!IsSelected());
415
416   return kTRUE;
417 #else
418   return kFALSE;
419 #endif
420 }
421
422 Bool_t AliRawReaderDate::ReadNextData(UChar_t*& data)
423 {
424 // reads the next payload at the current position
425 // returns kFALSE if the data could not be read
426
427   fErrorCode = 0;
428   while (fCount == 0) {
429     if (!ReadHeader()) return kFALSE;
430   }
431   data = fPosition;
432   fPosition += fCount;  
433   fCount = 0;
434   return kTRUE;
435 }
436
437 Bool_t AliRawReaderDate::ReadNext(UChar_t* data, Int_t size)
438 {
439 // reads the next block of data at the current position
440 // returns kFALSE if the data could not be read
441
442   fErrorCode = 0;
443   if (fPosition + size > fEnd) {
444     Error("ReadNext", "could not read data!");
445     fErrorCode = kErrOutOfBounds;
446     return kFALSE;
447   }
448   memcpy(data, fPosition, size);
449   fPosition += size;
450   fCount -= size;
451   return kTRUE;
452 }
453
454
455 Bool_t AliRawReaderDate::Reset()
456 {
457 // reset the current position to the beginning of the event
458
459 #ifdef ALI_DATE
460   fSubEvent = NULL;
461 #endif
462   fCount = 0;
463   fPosition = fEnd = NULL;
464   return kTRUE;
465 }
466
467
468 Int_t AliRawReaderDate::CheckData() const
469 {
470 // check the consistency of the data
471
472 #ifdef ALI_DATE
473   if (!fEvent) return 0;
474   // check whether there are sub events
475   if (fEvent->eventSize <= fEvent->eventHeadSize) return 0;
476
477   eventHeaderStruct* subEvent = NULL;
478   UChar_t* position = 0;
479   UChar_t* end = 0;
480   Int_t result = 0;
481
482   while (kTRUE) {
483     // get the first or the next sub event if at the end of a sub event
484     if (!subEvent || (position >= end)) {
485
486       // check for end of event data
487       if (position >= ((UChar_t*)fEvent)+fEvent->eventSize) return result;
488       if (subEvent) {
489         subEvent = (eventHeaderStruct*) (((UChar_t*)subEvent) + 
490                                          subEvent->eventSize);
491       } else {
492         subEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) + 
493                                          fEvent->eventHeadSize);
494       }
495
496       // check the magic word of the sub event
497       if (subEvent->eventMagic != EVENT_MAGIC_NUMBER) {
498         result |= kErrMagic;
499         return result;
500       }
501
502       position = ((UChar_t*)subEvent) + subEvent->eventHeadSize + 
503         sizeof(equipmentHeaderStruct);
504       end = ((UChar_t*)subEvent) + subEvent->eventSize;
505     }
506
507     // continue with the next sub event if no data left in the payload
508     if (position >= end) continue;
509
510     // check that there are enough bytes left for the mini header
511     if (position + sizeof(AliMiniHeader) > end) {
512       result |= kErrNoMiniHeader;
513       position = end;
514       continue;
515     }
516
517     // "read" and check the mini header
518     AliMiniHeader* miniHeader = (AliMiniHeader*) position;
519     position += sizeof(AliMiniHeader);
520     if (!CheckMiniHeader(miniHeader)){
521       result |= kErrMiniMagic;
522       position = end;
523       continue;
524     }
525
526     // check consistency of data size in the mini header and in the sub event
527     if (position + miniHeader->fSize > end) result |= kErrSize;
528     position += miniHeader->fSize;
529   };
530
531 #endif
532   return 0;
533 }