Adding a method to access the event timestamp - GetTimestamp(). The method does not...
[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     return;
81   }
82   if (eventNumber < 0) return;
83
84   eventHeaderStruct header;
85   UInt_t headerSize = sizeof(eventHeaderStruct);
86   while (fread(&header, 1, headerSize, fFile) == headerSize) {
87     if (eventNumber == 0) {
88       UChar_t* buffer = new UChar_t[header.size];
89       fseek(fFile, -headerSize, SEEK_CUR);
90       if (Int_t(fread(buffer, 1, header.size, fFile)) != header.size) break;
91       fEvent = (eventHeaderStruct*) buffer;
92       break;
93     }
94     fseek(fFile, header.size-headerSize, SEEK_CUR);
95     eventNumber--;
96   }
97 }
98
99 AliRawReaderDateV3::AliRawReaderDateV3(const AliRawReaderDateV3& rawReader) :
100   AliRawReader(rawReader),
101   fFile(rawReader.fFile),
102   fEvent(rawReader.fEvent),
103   fSubEvent(rawReader.fSubEvent),
104   fPosition(rawReader.fPosition),
105   fEnd(rawReader.fEnd)
106
107 {
108 // copy constructor
109
110   Fatal("AliRawReaderDateV3", "copy constructor not implemented");
111 }
112
113 AliRawReaderDateV3& AliRawReaderDateV3::operator = (const AliRawReaderDateV3& 
114                                                 /*rawReader*/)
115 {
116 // assignment operator
117
118   Fatal("operator =", "assignment operator not implemented");
119   return *this;
120 }
121
122 AliRawReaderDateV3::~AliRawReaderDateV3()
123 {
124 // destructor
125
126   if (fFile) {
127     delete[] fEvent;
128     fclose(fFile);
129   }
130 }
131
132
133 UInt_t AliRawReaderDateV3::GetType() const
134 {
135 // get the type from the event header
136
137   if (!fEvent) return 0;
138   return fEvent->type;
139 }
140
141 UInt_t AliRawReaderDateV3::GetRunNumber() const
142 {
143 // get the run number from the event header
144
145   if (!fEvent) return 0;
146   return fEvent->runNb;
147 }
148
149 const UInt_t* AliRawReaderDateV3::GetEventId() const
150 {
151 // get the event id from the event header
152
153   if (!fEvent) return NULL;
154   return &(fEvent->nbInRun);
155 }
156
157 const UInt_t* AliRawReaderDateV3::GetTriggerPattern() const
158 {
159 // get the trigger pattern from the event header
160
161   return NULL;
162 }
163
164 const UInt_t* AliRawReaderDateV3::GetDetectorPattern() const
165 {
166 // get the detector pattern from the event header
167
168   if (!fEvent) return NULL;
169   return fEvent->detectorId;
170 }
171
172 const UInt_t* AliRawReaderDateV3::GetAttributes() const
173 {
174 // get the type attributes from the event header
175
176   if (!fEvent) return NULL;
177   return fEvent->typeAttribute;
178 }
179
180 const UInt_t* AliRawReaderDateV3::GetSubEventAttributes() const
181 {
182 // get the type attributes from the sub event header
183
184   if (!fSubEvent) return NULL;
185   return fSubEvent->typeAttribute;
186 }
187
188 UInt_t AliRawReaderDateV3::GetLDCId() const
189 {
190 // get the LDC Id from the event header
191
192   return UInt_t(-1);
193 }
194
195 UInt_t AliRawReaderDateV3::GetGDCId() const
196 {
197 // get the GDC Id from the event header
198
199   return UInt_t(-1);
200 }
201
202 UInt_t AliRawReaderDateV3::GetTimestamp() const
203 {
204 // get the timestamp from the event header
205
206   if (!fEvent) return 0;
207   return fEvent->time;
208 }
209
210 Int_t AliRawReaderDateV3::GetEquipmentSize() const
211 {
212 // get the size of the equipment
213
214   if (!fSubEvent) return 0;
215   return fSubEvent->size;
216 }
217
218 Int_t AliRawReaderDateV3::GetEquipmentType() const
219 {
220 // get the type from the equipment header
221
222   return 0;
223 }
224
225 Int_t AliRawReaderDateV3::GetEquipmentId() const
226 {
227 // get the ID from the equipment header
228
229   return 0;
230 }
231
232 const UInt_t* AliRawReaderDateV3::GetEquipmentAttributes() const
233 {
234 // get the attributes from the equipment header
235
236   return 0;
237 }
238
239 Int_t AliRawReaderDateV3::GetEquipmentElementSize() const
240 {
241 // get the basic element size from the equipment header
242
243   return 0;
244 }
245
246 Int_t AliRawReaderDateV3::GetEquipmentHeaderSize() const
247 {
248 // get the size of the equipment header
249
250   return 0;
251 }
252
253 Bool_t AliRawReaderDateV3::ReadHeader()
254 {
255 // read a data header at the current position
256 // returns kFALSE if the data header could not be read
257
258   fErrorCode = 0;
259
260   fHeader = NULL;
261   if (!fEvent) return kFALSE;
262   // check whether there are sub events
263   if (fEvent->size <= Int_t(fEvent->headLen)) return kFALSE;
264
265   do {
266     // skip payload (if event was not selected)
267     if (fCount > 0) fPosition += fCount;
268
269     // check for end of event data
270     if (fPosition >= ((UChar_t*)fEvent)+fEvent->size) return kFALSE;
271     if ((fEvent->detectorId[2] & 0x8000) != 0x8000) {
272       fSubEvent = fEvent;   // no super event
273     } else if (fSubEvent) {
274       fSubEvent = (eventHeaderStruct*) (((UChar_t*)fSubEvent) + 
275                                         fSubEvent->size);
276     } else {
277       fSubEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) + 
278                                         fEvent->headLen);
279     }
280
281     // check the magic word of the sub event
282     if (fSubEvent->magic != EVENT_MAGIC_NUMBER) {
283       Error("ReadHeader", "wrong magic number in sub event!\n"
284             " run: %d  event: %d\n", 
285             fSubEvent->runNb, fSubEvent->nbInRun);
286       fErrorCode = kErrMagic;
287       return kFALSE;
288     }
289
290     // continue if no data in the subevent
291     if (fSubEvent->size == Int_t(fSubEvent->headLen)) {
292       fPosition = fEnd = ((UChar_t*)fSubEvent) + fSubEvent->size;
293       fCount = 0;
294       continue;
295     }
296
297     fCount = 0;
298     fPosition = ((UChar_t*)fSubEvent) + sizeof(eventHeaderStruct);
299     fEnd = ((UChar_t*)fSubEvent) + fSubEvent->size;
300
301     // continue with the next sub event if no data left in the payload
302     if (fPosition >= fEnd) continue;
303
304     if (fRequireHeader) {
305       // check that there are enough bytes left for the data header
306       if (fPosition + sizeof(AliRawDataHeader) > fEnd) {
307         Error("ReadHeader", "could not read data header data!");
308         Warning("ReadHeader", "skipping %d bytes\n"
309                 " run: %d  event: %d\n", 
310                 fEnd - fPosition, fSubEvent->runNb, fSubEvent->nbInRun);
311         fCount = 0;
312         fPosition = fEnd;
313         fErrorCode = kErrNoDataHeader;
314         continue;
315       }
316
317       // "read" the data header
318       fHeader = (AliRawDataHeader*) fPosition;
319       if ((fPosition + fHeader->fSize) != fEnd) {
320         Warning("ReadHeader",
321                 "raw data size found in the header is wrong (%d != %d)! Using the equipment size instead !",
322                 fHeader->fSize, fEnd - fPosition);
323         fHeader->fSize = fEnd - fPosition;
324       }
325       fPosition += sizeof(AliRawDataHeader);
326     }
327
328     if (fHeader && (fHeader->fSize != 0xFFFFFFFF)) {
329       fCount = fHeader->fSize - sizeof(AliRawDataHeader);
330
331       // check consistency of data size in the header and in the sub event
332       if (fPosition + fCount > fEnd) {
333         Error("ReadHeader", "size in data header exceeds event size!");
334         Warning("ReadHeader", "skipping %d bytes\n"
335                 " run: %d  event: %d\n", 
336                 fEnd - fPosition, fSubEvent->runNb, fSubEvent->nbInRun);
337         fCount = 0;
338         fPosition = fEnd;
339         fErrorCode = kErrSize;
340         continue;
341       }
342
343     } else {
344       fCount = fEnd - fPosition;
345     }
346
347   } while (!IsSelected());
348
349   return kTRUE;
350 }
351
352 Bool_t AliRawReaderDateV3::ReadNextData(UChar_t*& data)
353 {
354 // reads the next payload at the current position
355 // returns kFALSE if the data could not be read
356
357   fErrorCode = 0;
358   while (fCount == 0) {
359     if (!ReadHeader()) return kFALSE;
360   }
361   data = fPosition;
362   fPosition += fCount;  
363   fCount = 0;
364   return kTRUE;
365 }
366
367 Bool_t AliRawReaderDateV3::ReadNext(UChar_t* data, Int_t size)
368 {
369 // reads the next block of data at the current position
370 // returns kFALSE if the data could not be read
371
372   fErrorCode = 0;
373   if (fPosition + size > fEnd) {
374     Error("ReadNext", "could not read data!");
375     fErrorCode = kErrOutOfBounds;
376     return kFALSE;
377   }
378   memcpy(data, fPosition, size);
379   fPosition += size;
380   fCount -= size;
381   return kTRUE;
382 }
383
384
385 Bool_t AliRawReaderDateV3::Reset()
386 {
387 // reset the current position to the beginning of the event
388
389   fSubEvent = NULL;
390   fCount = 0;
391   fPosition = fEnd = NULL;
392   return kTRUE;
393 }
394
395
396 Bool_t AliRawReaderDateV3::NextEvent()
397 {
398 // go to the next event in the date file
399
400   if (!fFile) return kFALSE;
401
402   Reset();
403   eventHeaderStruct header;
404   UInt_t headerSize = sizeof(eventHeaderStruct);
405   if (fEvent) delete[] fEvent;
406   fEvent = &header;
407
408   while (fread(&header, 1, headerSize, fFile) == headerSize) {
409     if (!IsEventSelected()) {
410       fseek(fFile, header.size-headerSize, SEEK_CUR);
411       continue;
412     }
413     UChar_t* buffer = new UChar_t[header.size];
414     fseek(fFile, -headerSize, SEEK_CUR);
415     if (Int_t(fread(buffer, 1, header.size, fFile)) != header.size) {
416       Error("NextEvent", "could not read event from file");
417       delete[] buffer;
418       break;
419     }
420     fEvent = (eventHeaderStruct*) buffer;
421     fEventNumber++;
422     return kTRUE;
423   };
424
425   fEvent = NULL;
426   return kFALSE;
427 }
428
429 Bool_t AliRawReaderDateV3::RewindEvents()
430 {
431 // go back to the beginning of the date file
432
433   if (!fFile) return kFALSE;
434
435   fseek(fFile, 0, SEEK_SET);
436   fEventNumber = -1;
437   return Reset();
438 }
439
440
441 Int_t AliRawReaderDateV3::CheckData() const
442 {
443 // check the consistency of the data
444
445   if (!fEvent) return 0;
446   // check whether there are sub events
447   if (fEvent->size <= Int_t(fEvent->headLen)) return 0;
448
449   eventHeaderStruct* subEvent = NULL;
450   UChar_t* position = 0;
451   UChar_t* end = 0;
452   Int_t result = 0;
453
454   while (kTRUE) {
455     // check for end of event data
456     if (position >= ((UChar_t*)fEvent)+fEvent->size) return result;
457     if ((fEvent->detectorId[2] & 0x8000) != 0x8000) {
458       subEvent = fEvent;   // no super event
459     } else if (subEvent) {
460       subEvent = (eventHeaderStruct*) (((UChar_t*)subEvent) + 
461                                        subEvent->size);
462     } else {
463       subEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) + 
464                                        fEvent->headLen);
465     }
466
467     // check the magic word of the sub event
468     if (subEvent->magic != EVENT_MAGIC_NUMBER) {
469       result |= kErrMagic;
470       return result;
471     }
472
473     position = ((UChar_t*)subEvent) + subEvent->headLen;
474     end = ((UChar_t*)subEvent) + subEvent->size;
475
476     // continue with the next sub event if no data left in the payload
477     if (position >= end) continue;
478
479     if (fRequireHeader) {
480       // check that there are enough bytes left for the data header
481       if (position + sizeof(AliRawDataHeader) > end) {
482         result |= kErrNoDataHeader;
483         position = end;
484         continue;
485       }
486
487       // check consistency of data size in the data header and in the sub event
488       AliRawDataHeader* header = (AliRawDataHeader*) position;
489       if ((position + header->fSize) != end) {
490         Warning("ReadHeader",
491                 "raw data size found in the header is wrong (%d != %d)! Using the equipment size instead !",
492                 header->fSize, end - position);
493         header->fSize = end - position;
494         result |= kErrSize;
495       }
496     }
497     position = end;
498   };
499
500   return 0;
501 }