ALIROOT-5420 Changes for CDH v3
[u/mrichter/AliRoot.git] / RAW / AliRawReaderRoot.cxx
CommitLineData
04fa961a 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
bea6b2a4 16/* $Id$ */
17
04fa961a 18///////////////////////////////////////////////////////////////////////////////
bea6b2a4 19///
20/// This is a class for reading raw data from a root file.
21///
22/// The root file is expected to contain a tree of name "RAW" with
23/// a branch of name "rawevent" which contains objects of type
33314186 24/// AliRawVEvent.
bea6b2a4 25///
26/// The file name and the event number are arguments of the constructor
27/// of AliRawReaderRoot.
28///
04fa961a 29///////////////////////////////////////////////////////////////////////////////
30
a197a4ce 31#include <TFile.h>
32#include <TTree.h>
1d6124f3 33#include <TTreeIndex.h>
04fa961a 34#include "AliRawReaderRoot.h"
33314186 35#include "AliRawVEvent.h"
f2dc6b20 36#include "AliRawEventHeaderBase.h"
33314186 37#include "AliRawVEquipment.h"
a197a4ce 38#include "AliRawEquipmentHeader.h"
39#include "AliRawData.h"
04fa961a 40
41
42ClassImp(AliRawReaderRoot)
1d6124f3 43Bool_t AliRawReaderRoot::fgUseOrder = kFALSE;
44
04fa961a 45
6923e953 46AliRawReaderRoot::AliRawReaderRoot() :
47 fFile(NULL),
48 fBranch(NULL),
49 fEventIndex(-1),
50 fEvent(NULL),
33314186 51 fEventHeader(NULL),
6923e953 52 fSubEventIndex(0),
53 fSubEvent(NULL),
54 fEquipmentIndex(0),
55 fEquipment(NULL),
56 fRawData(NULL),
57 fPosition(NULL),
1d6124f3 58 fEnd(NULL),
59 fIndex(0x0)
6923e953 60{
61// default constructor
62
63}
04fa961a 64
dd9a70fe 65AliRawReaderRoot::AliRawReaderRoot(const char* fileName, Int_t eventNumber) :
66 fFile(NULL),
67 fBranch(NULL),
68 fEventIndex(eventNumber),
69 fEvent(NULL),
33314186 70 fEventHeader(NULL),
dd9a70fe 71 fSubEventIndex(0),
72 fSubEvent(NULL),
94d918a7 73 fEquipmentIndex(0),
74 fEquipment(NULL),
dd9a70fe 75 fRawData(NULL),
76 fPosition(NULL),
1d6124f3 77 fEnd(NULL),
78 fIndex(0x0)
04fa961a 79{
80// create an object to read digits from the given input file for the
81// event with the given number
82
03c6d9a3 83 TDirectory* dir = gDirectory;
04fa961a 84 fFile = TFile::Open(fileName);
03c6d9a3 85 dir->cd();
04fa961a 86 if (!fFile || !fFile->IsOpen()) {
87 Error("AliRawReaderRoot", "could not open file %s", fileName);
a97af23d 88 fIsValid = kFALSE;
04fa961a 89 return;
90 }
91 TTree* tree = (TTree*) fFile->Get("RAW");
92 if (!tree) {
93 Error("AliRawReaderRoot", "no raw data tree found");
a97af23d 94 fIsValid = kFALSE;
04fa961a 95 return;
96 }
dd9a70fe 97 fBranch = tree->GetBranch("rawevent");
98 if (!fBranch) {
04fa961a 99 Error("AliRawReaderRoot", "no raw data branch found");
a97af23d 100 fIsValid = kFALSE;
04fa961a 101 return;
102 }
103
dd9a70fe 104 fBranch->SetAddress(&fEvent);
105 if (fEventIndex >= 0) {
106 if (fBranch->GetEntry(fEventIndex) <= 0) {
107 Error("AliRawReaderRoot", "no event with number %d found", fEventIndex);
a97af23d 108 fIsValid = kFALSE;
dd9a70fe 109 return;
110 }
33314186 111 fEventHeader = fEvent->GetHeader();
04fa961a 112 }
04fa961a 113}
114
33314186 115AliRawReaderRoot::AliRawReaderRoot(AliRawVEvent* event) :
dd9a70fe 116 fFile(NULL),
117 fBranch(NULL),
118 fEventIndex(-1),
119 fEvent(event),
33314186 120 fEventHeader(event->GetHeader()),
dd9a70fe 121 fSubEventIndex(0),
122 fSubEvent(NULL),
94d918a7 123 fEquipmentIndex(0),
124 fEquipment(NULL),
dd9a70fe 125 fRawData(NULL),
126 fPosition(NULL),
1d6124f3 127 fEnd(NULL),
128 fIndex(0x0)
04fa961a 129{
130// create an object to read digits from the given raw event
a97af23d 131 if (!fEvent) fIsValid = kFALSE;
04fa961a 132}
133
42d20574 134AliRawReaderRoot::AliRawReaderRoot(const AliRawReaderRoot& rawReader) :
dd9a70fe 135 AliRawReader(rawReader),
136 fFile(NULL),
137 fBranch(NULL),
138 fEventIndex(rawReader.fEventIndex),
139 fEvent(NULL),
33314186 140 fEventHeader(NULL),
dd9a70fe 141 fSubEventIndex(rawReader.fSubEventIndex),
142 fSubEvent(NULL),
94d918a7 143 fEquipmentIndex(rawReader.fEquipmentIndex),
144 fEquipment(NULL),
dd9a70fe 145 fRawData(NULL),
146 fPosition(NULL),
1d6124f3 147 fEnd(NULL),
148 fIndex(0x0)
42d20574 149{
150// copy constructor
151
dd9a70fe 152 if (rawReader.fFile) {
153 TDirectory* dir = gDirectory;
154 fFile = TFile::Open(rawReader.fFile->GetName());
155 dir->cd();
156 if (!fFile || !fFile->IsOpen()) {
157 Error("AliRawReaderRoot", "could not open file %s",
158 rawReader.fFile->GetName());
a97af23d 159 fIsValid = kFALSE;
dd9a70fe 160 return;
161 }
162 TTree* tree = (TTree*) fFile->Get("RAW");
163 if (!tree) {
164 Error("AliRawReaderRoot", "no raw data tree found");
a97af23d 165 fIsValid = kFALSE;
dd9a70fe 166 return;
167 }
168 fBranch = tree->GetBranch("rawevent");
169 if (!fBranch) {
170 Error("AliRawReaderRoot", "no raw data branch found");
a97af23d 171 fIsValid = kFALSE;
dd9a70fe 172 return;
173 }
174
dd9a70fe 175 fBranch->SetAddress(&fEvent);
176 if (fEventIndex >= 0) {
177 if (fBranch->GetEntry(fEventIndex) <= 0) {
178 Error("AliRawReaderRoot", "no event with number %d found",
179 fEventIndex);
a97af23d 180 fIsValid = kFALSE;
dd9a70fe 181 return;
182 }
33314186 183 fEventHeader = fEvent->GetHeader();
dd9a70fe 184 }
185 } else {
186 fEvent = rawReader.fEvent;
33314186 187 fEventHeader = rawReader.fEventHeader;
dd9a70fe 188 }
189
190 if (fSubEventIndex > 0) {
191 fSubEvent = fEvent->GetSubEvent(fSubEventIndex-1);
94d918a7 192 fEquipment = fSubEvent->GetEquipment(fEquipmentIndex);
193 fRawData = fEquipment->GetRawData();
480f0332 194 fCount = 0;
dd9a70fe 195 fHeader = (AliRawDataHeader*) ((UChar_t*) fRawData->GetBuffer() +
196 ((UChar_t*) rawReader.fHeader -
197 (UChar_t*) rawReader.fRawData->GetBuffer()));
480f0332 198 // Now check the version of the header
199 UChar_t version = 2;
200 if (fHeader) version = fHeader->GetVersion();
201 if (version==3) {
202 fHeader = NULL;
203 fHeaderV3 = (AliRawDataHeaderV3*) ((UChar_t*) fRawData->GetBuffer() +
204 ((UChar_t*) rawReader.fHeaderV3 -
205 (UChar_t*) rawReader.fRawData->GetBuffer()));
206 }
dd9a70fe 207 fPosition = (UChar_t*) fRawData->GetBuffer() +
208 (rawReader.fPosition - (UChar_t*) rawReader.fRawData->GetBuffer());
209 fEnd = ((UChar_t*) fRawData->GetBuffer()) + fRawData->GetSize();
210 }
42d20574 211}
212
213AliRawReaderRoot& AliRawReaderRoot::operator = (const AliRawReaderRoot&
214 rawReader)
215{
216// assignment operator
217
218 this->~AliRawReaderRoot();
219 new(this) AliRawReaderRoot(rawReader);
220 return *this;
221}
222
04fa961a 223AliRawReaderRoot::~AliRawReaderRoot()
224{
225// delete objects and close root file
226
227 if (fFile) {
228 if (fEvent) delete fEvent;
229 fFile->Close();
230 delete fFile;
231 }
232}
233
1fb5b4a8 234const AliRawEventHeaderBase* AliRawReaderRoot::GetEventHeader() const
235{
236 // Get the even header
237 // Return NULL in case of failure
33314186 238 return fEventHeader;
1fb5b4a8 239}
04fa961a 240
42d20574 241UInt_t AliRawReaderRoot::GetType() const
04fa961a 242{
243// get the type from the event header
244
33314186 245 if (!fEventHeader) return 0;
246 return fEventHeader->Get("Type");
04fa961a 247}
248
42d20574 249UInt_t AliRawReaderRoot::GetRunNumber() const
04fa961a 250{
251// get the run number from the event header
252
33314186 253 if (!fEventHeader) return 0;
254 return fEventHeader->Get("RunNb");
04fa961a 255}
256
42d20574 257const UInt_t* AliRawReaderRoot::GetEventId() const
04fa961a 258{
259// get the event id from the event header
260
33314186 261 if (!fEventHeader) return NULL;
262 return fEventHeader->GetP("Id");
04fa961a 263}
264
42d20574 265const UInt_t* AliRawReaderRoot::GetTriggerPattern() const
04fa961a 266{
267// get the trigger pattern from the event header
268
33314186 269 if (!fEventHeader) return NULL;
270 return fEventHeader->GetP("TriggerPattern");
04fa961a 271}
272
42d20574 273const UInt_t* AliRawReaderRoot::GetDetectorPattern() const
04fa961a 274{
275// get the detector pattern from the event header
276
33314186 277 if (!fEventHeader) return NULL;
278 return fEventHeader->GetP("DetectorPattern");
04fa961a 279}
280
42d20574 281const UInt_t* AliRawReaderRoot::GetAttributes() const
04fa961a 282{
283// get the type attributes from the event header
284
33314186 285 if (!fEventHeader) return NULL;
286 return fEventHeader->GetP("TypeAttribute");
04fa961a 287}
288
e94ad92c 289const UInt_t* AliRawReaderRoot::GetSubEventAttributes() const
290{
291// get the type attributes from the sub event header
292
293 if (!fSubEvent) return NULL;
f2dc6b20 294 return fSubEvent->GetHeader()->GetP("TypeAttribute");
e94ad92c 295}
296
c946ab02 297UInt_t AliRawReaderRoot::GetLDCId() const
298{
299// get the LDC Id from the event header
300
94d918a7 301 if (!fEvent || !fSubEvent) return 0;
f2dc6b20 302 return fSubEvent->GetHeader()->Get("LdcId");
c946ab02 303}
304
42d20574 305UInt_t AliRawReaderRoot::GetGDCId() const
04fa961a 306{
307// get the GDC Id from the event header
308
33314186 309 if (!fEventHeader) return 0;
310 return fEventHeader->Get("GdcId");
04fa961a 311}
312
741c154c 313UInt_t AliRawReaderRoot::GetTimestamp() const
314{
33314186 315 if (!fEventHeader) return 0;
316 return fEventHeader->Get("Timestamp");
741c154c 317}
04fa961a 318
c946ab02 319Int_t AliRawReaderRoot::GetEquipmentSize() const
320{
321// get the size of the equipment
322
94d918a7 323 if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return 0;
324 return fEquipment->GetEquipmentHeader()->GetEquipmentSize();
c946ab02 325}
326
327Int_t AliRawReaderRoot::GetEquipmentType() const
328{
329// get the type from the equipment header
330
94d918a7 331 if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return -1;
332 return fEquipment->GetEquipmentHeader()->GetEquipmentType();
c946ab02 333}
334
335Int_t AliRawReaderRoot::GetEquipmentId() const
336{
337// get the ID from the equipment header
338
94d918a7 339 if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return -1;
340 return fEquipment->GetEquipmentHeader()->GetId();
c946ab02 341}
342
343const UInt_t* AliRawReaderRoot::GetEquipmentAttributes() const
344{
345// get the attributes from the equipment header
346
94d918a7 347 if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return NULL;
348 return fEquipment->GetEquipmentHeader()->GetTypeAttribute();
c946ab02 349}
350
351Int_t AliRawReaderRoot::GetEquipmentElementSize() const
352{
353// get the basic element size from the equipment header
354
94d918a7 355 if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return 0;
356 return fEquipment->GetEquipmentHeader()->GetBasicSizeType();
c946ab02 357}
358
299738b9 359Int_t AliRawReaderRoot::GetEquipmentHeaderSize() const
360{
361// get the size of the equipment header (28 bytes by default)
362
363 if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return 0;
364 return fEquipment->GetEquipmentHeader()->HeaderSize();
365}
366
edd06192 367// _________________________________________________________________________
edd06192 368void AliRawReaderRoot::SwapData(const void* inbuf, const void* outbuf, UInt_t size) {
369 // The method swaps the contents of the
370 // raw-data event header
91f76e9b 371 UInt_t intCount = (size+3)/sizeof(UInt_t);
edd06192 372
373 UInt_t* buf = (UInt_t*) inbuf; // temporary integers buffer
374 for (UInt_t i=0; i<intCount; i++, buf++) {
375 UInt_t value = SwapWord(*buf);
dae3f0d9 376 if (i==(intCount-1))
377 memcpy((UInt_t*)outbuf+i, &value, size%sizeof(UInt_t));
378 else
379 memcpy((UInt_t*)outbuf+i, &value, sizeof(UInt_t));
edd06192 380 }
381}
382// _________________________________________________________________________
c946ab02 383
384Bool_t AliRawReaderRoot::ReadHeader()
04fa961a 385{
39f9963f 386// read a data header at the current position
387// returns kFALSE if the data header could not be read
04fa961a 388
b4857df7 389 fErrorCode = 0;
04fa961a 390 if (!fEvent) return kFALSE;
b4857df7 391
04fa961a 392 do {
b4857df7 393 // skip payload (if event was not selected)
394 if (fCount > 0) fPosition += fCount;
395
94d918a7 396 // get the first or the next equipment if at the end of an equipment
397 if (!fEquipment || (fPosition >= fEnd)) {
b4857df7 398
94d918a7 399 // get the first or the next sub event if at the end of a sub event
400 if (!fSubEvent || (fEquipmentIndex >= fSubEvent->GetNEquipments())) {
b4857df7 401
94d918a7 402 // check for end of event data
403 if (fSubEventIndex >= fEvent->GetNSubEvents()) return kFALSE;
404 fSubEvent = fEvent->GetSubEvent(fSubEventIndex++);
405
406 // check the magic word of the sub event
407 if (!fSubEvent->GetHeader()->IsValid()) {
408 Error("ReadHeader", "wrong magic number in sub event!");
409 fSubEvent->GetHeader()->Dump();
410 fErrorCode = kErrMagic;
411 return kFALSE;
412 }
413
414 fEquipmentIndex = 0;
415 fEquipment = NULL;
416 fRawData = NULL;
b4857df7 417 }
418
94d918a7 419 // get the next equipment and raw data
04fa961a 420 fCount = 0;
f49c01bc 421 if (fEquipmentIndex >= fSubEvent->GetNEquipments()) {
422 fEquipment = NULL;
423 continue;
424 }
94d918a7 425 fEquipment = fSubEvent->GetEquipment(fEquipmentIndex++);
426 if (!fEquipment) continue;
3d65cc80 427 if (!IsSelected()) {
428 fPosition = fEnd;
429 continue;
430 }
94d918a7 431 fRawData = fEquipment->GetRawData();
432 if (!fRawData) {
433 fPosition = fEnd;
434 continue;
435 }
04fa961a 436 fPosition = (UChar_t*) fRawData->GetBuffer();
437 fEnd = ((UChar_t*) fRawData->GetBuffer()) + fRawData->GetSize();
438 }
b4857df7 439
94d918a7 440 // continue with the next equipment if no data left in the payload
b4857df7 441 if (fPosition >= fEnd) continue;
442
18882b3b 443 if (fRequireHeader) {
444 // check that there are enough bytes left for the data header
445 if (fPosition + sizeof(AliRawDataHeader) > fEnd) {
446 Error("ReadHeader", "could not read data header!");
6c12d59f 447 Warning("ReadHeader", "skipping %ld bytes", fEnd - fPosition);
18882b3b 448 fEquipment->GetEquipmentHeader()->Dump();
449 fCount = 0;
450 fPosition = fEnd;
451 fErrorCode = kErrNoDataHeader;
452 continue;
453 }
454
455 // "read" the data header
456 fHeader = (AliRawDataHeader*) fPosition;
480f0332 457 // Now check the version of the header
458 UChar_t version = 2;
459 if (fHeader) version=fHeader->GetVersion();
460 if (version==2) {
461 #ifndef R__BYTESWAP
462 SwapData((void*) fHeader, (void*) fHeaderSwapped, sizeof(AliRawDataHeader));
463 fHeader=fHeaderSwapped;
464#endif
465 if ((fPosition + fHeader->fSize) != fEnd) {
466 if (fHeader->fSize != 0xFFFFFFFF)
467 Warning("ReadHeader",
468 "Equipment %d : raw data size found in the header is wrong (%d != %ld)! Using the equipment size instead !",
469 fEquipment->GetEquipmentHeader()->GetId(),fHeader->fSize, fEnd - fPosition);
470 fHeader->fSize = fEnd - fPosition;
471 }
472 fPosition += sizeof(AliRawDataHeader);
473 fHeaderV3 = 0;
474 } else if (version==3) {
475 fHeaderV3 = (AliRawDataHeaderV3*) fPosition;
edd06192 476#ifndef R__BYTESWAP
480f0332 477 SwapData((void*) fHeaderV3, (void*) fHeaderSwapped, sizeof(AliRawDataHeaderV3));
478 fHeaderV3=fHeaderSwappedV3;
edd06192 479#endif
480f0332 480 if ((fPosition + fHeaderV3->fSize) != fEnd) {
481 if (fHeaderV3->fSize != 0xFFFFFFFF)
482 Warning("ReadHeader",
483 "Equipment %d : raw data size found in the header is wrong (%d != %ld)! Using the equipment size instead !",
484 fEquipment->GetEquipmentHeader()->GetId(),fHeader->fSize, fEnd - fPosition);
485 fHeaderV3->fSize = fEnd - fPosition;
486 }
487 fPosition += sizeof(AliRawDataHeaderV3);
488 fHeader = 0;
299738b9 489 }
04fa961a 490 }
b4857df7 491
7c726b91 492 if (fHeader && (fHeader->fSize != 0xFFFFFFFF)) {
39f9963f 493 fCount = fHeader->fSize - sizeof(AliRawDataHeader);
7c726b91 494
495 // check consistency of data size in the header and in the sub event
496 if (fPosition + fCount > fEnd) {
497 Error("ReadHeader", "size in data header exceeds event size!");
6c12d59f 498 Warning("ReadHeader", "skipping %ld bytes", fEnd - fPosition);
7c726b91 499 fEquipment->GetEquipmentHeader()->Dump();
500 fCount = 0;
501 fPosition = fEnd;
502 fErrorCode = kErrSize;
503 continue;
504 }
480f0332 505 } else if (fHeaderV3 && (fHeaderV3->fSize != 0xFFFFFFFF)) {
506 fCount = fHeaderV3->fSize - sizeof(AliRawDataHeaderV3);
507
508 // check consistency of data size in the header and in the sub event
509 if (fPosition + fCount > fEnd) {
510 Error("ReadHeader", "size in data header exceeds event size!");
511 Warning("ReadHeader", "skipping %ld bytes", fEnd - fPosition);
512 fEquipment->GetEquipmentHeader()->Dump();
513 fCount = 0;
514 fPosition = fEnd;
515 fErrorCode = kErrSize;
516 continue;
517 }
7c726b91 518
39f9963f 519 } else {
520 fCount = fEnd - fPosition;
72dd1d4f 521 }
b4857df7 522
04fa961a 523 } while (!IsSelected());
b4857df7 524
04fa961a 525 return kTRUE;
526}
527
528Bool_t AliRawReaderRoot::ReadNextData(UChar_t*& data)
529{
530// reads the next payload at the current position
531// returns kFALSE if the data could not be read
532
b4857df7 533 fErrorCode = 0;
04fa961a 534 while (fCount == 0) {
c946ab02 535 if (!ReadHeader()) return kFALSE;
04fa961a 536 }
537 data = fPosition;
538 fPosition += fCount;
539 fCount = 0;
540 return kTRUE;
541}
542
543Bool_t AliRawReaderRoot::ReadNext(UChar_t* data, Int_t size)
544{
545// reads the next block of data at the current position
546// returns kFALSE if the data could not be read
547
b4857df7 548 fErrorCode = 0;
04fa961a 549 if (fPosition + size > fEnd) {
550 Error("ReadNext", "could not read data!");
b4857df7 551 fErrorCode = kErrOutOfBounds;
04fa961a 552 return kFALSE;
553 }
554 memcpy(data, fPosition, size);
dae3f0d9 555
04fa961a 556 fPosition += size;
557 fCount -= size;
558 return kTRUE;
559}
560
561
562Bool_t AliRawReaderRoot::Reset()
563{
564// reset the current position to the beginning of the event
565
566 fSubEventIndex = 0;
567 fSubEvent = NULL;
94d918a7 568 fEquipmentIndex = 0;
569 fEquipment = NULL;
04fa961a 570 fRawData = NULL;
39f9963f 571 fHeader = NULL;
480f0332 572 fHeaderV3 = NULL;
04fa961a 573
574 fCount = 0;
575 fPosition = fEnd = NULL;
576 return kTRUE;
577}
578
b4857df7 579
dd9a70fe 580Bool_t AliRawReaderRoot::NextEvent()
581{
582// go to the next event in the root file
583
2da4ef20 584 if (!fBranch) return kFALSE;
dd9a70fe 585
1d6124f3 586 // check if it uses order or not
587 if (fgUseOrder && !fIndex) MakeIndex();
588
dd9a70fe 589 do {
d41ecdd0 590 delete fEvent;
33314186 591 fEvent = NULL;
592 fEventHeader = NULL;
d41ecdd0 593 fBranch->SetAddress(&fEvent);
1d6124f3 594 Int_t entryToGet = fEventIndex + 1;
595 if (fgUseOrder
596 && fIndex
597 && entryToGet<fBranch->GetEntries()
598 && entryToGet>-1 ) entryToGet = fIndex[entryToGet];
599 if (fBranch->GetEntry(entryToGet) <= 0)
dd9a70fe 600 return kFALSE;
33314186 601 fEventHeader = fEvent->GetHeader();
dd9a70fe 602 fEventIndex++;
603 } while (!IsEventSelected());
38cf12f3 604 fEventNumber++;
dd9a70fe 605 return Reset();
606}
607
608Bool_t AliRawReaderRoot::RewindEvents()
609{
610// go back to the beginning of the root file
611
2da4ef20 612 if (!fBranch) return kFALSE;
dd9a70fe 613
614 fEventIndex = -1;
615 delete fEvent;
33314186 616 fEvent = NULL;
617 fEventHeader = NULL;
dd9a70fe 618 fBranch->SetAddress(&fEvent);
38cf12f3 619 fEventNumber = -1;
dd9a70fe 620 return Reset();
621}
622
636c1780 623Bool_t AliRawReaderRoot::GotoEvent(Int_t event)
624{
625 // go to a particular event
626 // Uses the absolute event index inside the
627 // raw-data file
628
629 if (!fBranch) return kFALSE;
630
1d6124f3 631 // check if it uses order or not
632 if (fgUseOrder && !fIndex) MakeIndex();
633
636c1780 634 delete fEvent;
33314186 635 fEvent = NULL;
636 fEventHeader = NULL;
636c1780 637 fBranch->SetAddress(&fEvent);
1d6124f3 638 Int_t entryToGet = event;
639 if (fgUseOrder
640 && fIndex
641 && entryToGet<fBranch->GetEntries()
642 && entryToGet>-1 ) entryToGet = fIndex[entryToGet];
643 if (fBranch->GetEntry(entryToGet) <= 0)
636c1780 644 return kFALSE;
33314186 645 fEventHeader = fEvent->GetHeader();
636c1780 646 fEventIndex = event;
647 fEventNumber++;
648 return Reset();
649}
dd9a70fe 650
25e82ff5 651Int_t AliRawReaderRoot::GetNumberOfEvents() const
652{
653 // Get the total number of events in
654 // the raw-data tree
655
656 if (!fBranch) return -1;
657
658 return fBranch->GetEntries();
659}
660
b4857df7 661Int_t AliRawReaderRoot::CheckData() const
662{
663// check the consistency of the data
664
665 if (!fEvent) return 0;
666
33314186 667 AliRawVEvent* subEvent = NULL;
b4857df7 668 Int_t subEventIndex = 0;
33314186 669 AliRawVEquipment* equipment = NULL;
94d918a7 670 Int_t equipmentIndex = 0;
b4857df7 671 UChar_t* position = 0;
672 UChar_t* end = 0;
be50fca2 673 Int_t result = 0;
b4857df7 674
675 while (kTRUE) {
94d918a7 676 // get the first or the next sub event if at the end of an equipment
677 if (!subEvent || (equipmentIndex >= subEvent->GetNEquipments())) {
b4857df7 678
679 // check for end of event data
be50fca2 680 if (subEventIndex >= fEvent->GetNSubEvents()) return result;
b4857df7 681 subEvent = fEvent->GetSubEvent(subEventIndex++);
682
683 // check the magic word of the sub event
be50fca2 684 if (!fSubEvent->GetHeader()->IsValid()) {
685 result |= kErrMagic;
686 return result;
687 }
b4857df7 688
94d918a7 689 equipmentIndex = 0;
b4857df7 690 }
691
94d918a7 692 // get the next equipment and raw data
f49c01bc 693 if (equipmentIndex >= subEvent->GetNEquipments()) {
694 equipment = NULL;
695 continue;
696 }
94d918a7 697 equipment = subEvent->GetEquipment(equipmentIndex++);
698 if (!equipment) continue;
699 AliRawData* rawData = equipment->GetRawData();
700 if (!rawData) continue;
701 position = (UChar_t*) rawData->GetBuffer();
702 end = ((UChar_t*) rawData->GetBuffer()) + rawData->GetSize();
703
b4857df7 704 // continue with the next sub event if no data left in the payload
705 if (position >= end) continue;
706
18882b3b 707 if (fRequireHeader) {
39f9963f 708 // check that there are enough bytes left for the data header
18882b3b 709 if (position + sizeof(AliRawDataHeader) > end) {
710 result |= kErrNoDataHeader;
711 continue;
712 }
b4857df7 713
18882b3b 714 // check consistency of data size in the header and in the equipment
715 AliRawDataHeader* header = (AliRawDataHeader*) position;
299738b9 716 if ((position + header->fSize) != end) {
806e573c 717 if (header->fSize != 0xFFFFFFFF)
718 Warning("ReadHeader",
6c12d59f 719 "Equipment %d : raw data size found in the header is wrong (%d != %ld)! Using the equipment size instead !",
806e573c 720 equipment->GetEquipmentHeader()->GetId(),header->fSize, end - position);
299738b9 721 header->fSize = end - position;
722 result |= kErrSize;
39f9963f 723 }
be50fca2 724 }
299738b9 725 position = end;
b4857df7 726 };
fd0de2e2 727
728 return result;
b4857df7 729}
b900a426 730
731AliRawReader* AliRawReaderRoot::CloneSingleEvent() const
732{
733 // Clones the current event and
734 // creates raw-reader for the cloned event
735 // Can be used in order to make asynchronious
736 // access to the current raw data within
737 // several threads (online event display/reco)
738
243e7b72 739 if (fEvent) {
b900a426 740 // Root formatted raw data
243e7b72 741 AliRawVEvent *gdcRootEvent = (AliRawVEvent*)fEvent->Clone();
b900a426 742 for (Int_t ldcCounter=0; ldcCounter < gdcRootEvent->GetNSubEvents(); ldcCounter++) {
743 AliRawVEvent *ldcRootEvent = gdcRootEvent->GetSubEvent(ldcCounter);
243e7b72 744 AliRawVEvent *subEvent = fEvent->GetSubEvent(ldcCounter);
b900a426 745 for (Int_t eqCounter=0; eqCounter < ldcRootEvent->GetNEquipments(); eqCounter++) {
746 AliRawVEquipment *equipment=ldcRootEvent->GetEquipment(eqCounter);
243e7b72 747 AliRawVEquipment *eq = subEvent->GetEquipment(eqCounter);
748 equipment->CloneRawData(eq->GetRawData());
b900a426 749 }
750 }
243e7b72 751 // Reset original event and newly
752 // produced one
753 gdcRootEvent->GetSubEvent(-1);
754 fEvent->GetSubEvent(-1);
b900a426 755 return new AliRawReaderRoot(gdcRootEvent);
756 }
757 return NULL;
758}
1d6124f3 759
760void AliRawReaderRoot::MakeIndex() {
761 // Make index
762 if (fBranch) {
763 TTree * rawTree = fBranch->GetTree();
764 if (rawTree) {
765 rawTree->BuildIndex("-fEvtHdrs[0].fSize"); // Minus sign to get largest first
766 TTreeIndex * treeInd = (TTreeIndex*)rawTree->GetTreeIndex();
767 if (treeInd) fIndex = treeInd->GetIndex();
768 }
769 }
770}