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