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