]>
Commit | Line | Data |
---|---|---|
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 | ||
42 | ClassImp(AliRawReaderRoot) | |
1d6124f3 | 43 | Bool_t AliRawReaderRoot::fgUseOrder = kFALSE; |
44 | ||
04fa961a | 45 | |
6923e953 | 46 | AliRawReaderRoot::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 | 65 | AliRawReaderRoot::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 | 115 | AliRawReaderRoot::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 | 134 | AliRawReaderRoot::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(); | |
dd9a70fe | 194 | fCount = 0; |
195 | fHeader = (AliRawDataHeader*) ((UChar_t*) fRawData->GetBuffer() + | |
196 | ((UChar_t*) rawReader.fHeader - | |
197 | (UChar_t*) rawReader.fRawData->GetBuffer())); | |
198 | fPosition = (UChar_t*) fRawData->GetBuffer() + | |
199 | (rawReader.fPosition - (UChar_t*) rawReader.fRawData->GetBuffer()); | |
200 | fEnd = ((UChar_t*) fRawData->GetBuffer()) + fRawData->GetSize(); | |
201 | } | |
42d20574 | 202 | } |
203 | ||
204 | AliRawReaderRoot& AliRawReaderRoot::operator = (const AliRawReaderRoot& | |
205 | rawReader) | |
206 | { | |
207 | // assignment operator | |
208 | ||
209 | this->~AliRawReaderRoot(); | |
210 | new(this) AliRawReaderRoot(rawReader); | |
211 | return *this; | |
212 | } | |
213 | ||
04fa961a | 214 | AliRawReaderRoot::~AliRawReaderRoot() |
215 | { | |
216 | // delete objects and close root file | |
217 | ||
218 | if (fFile) { | |
219 | if (fEvent) delete fEvent; | |
220 | fFile->Close(); | |
221 | delete fFile; | |
222 | } | |
223 | } | |
224 | ||
1fb5b4a8 | 225 | const AliRawEventHeaderBase* AliRawReaderRoot::GetEventHeader() const |
226 | { | |
227 | // Get the even header | |
228 | // Return NULL in case of failure | |
33314186 | 229 | return fEventHeader; |
1fb5b4a8 | 230 | } |
04fa961a | 231 | |
42d20574 | 232 | UInt_t AliRawReaderRoot::GetType() const |
04fa961a | 233 | { |
234 | // get the type from the event header | |
235 | ||
33314186 | 236 | if (!fEventHeader) return 0; |
237 | return fEventHeader->Get("Type"); | |
04fa961a | 238 | } |
239 | ||
42d20574 | 240 | UInt_t AliRawReaderRoot::GetRunNumber() const |
04fa961a | 241 | { |
242 | // get the run number from the event header | |
243 | ||
33314186 | 244 | if (!fEventHeader) return 0; |
245 | return fEventHeader->Get("RunNb"); | |
04fa961a | 246 | } |
247 | ||
42d20574 | 248 | const UInt_t* AliRawReaderRoot::GetEventId() const |
04fa961a | 249 | { |
250 | // get the event id from the event header | |
251 | ||
33314186 | 252 | if (!fEventHeader) return NULL; |
253 | return fEventHeader->GetP("Id"); | |
04fa961a | 254 | } |
255 | ||
42d20574 | 256 | const UInt_t* AliRawReaderRoot::GetTriggerPattern() const |
04fa961a | 257 | { |
258 | // get the trigger pattern from the event header | |
259 | ||
33314186 | 260 | if (!fEventHeader) return NULL; |
261 | return fEventHeader->GetP("TriggerPattern"); | |
04fa961a | 262 | } |
263 | ||
42d20574 | 264 | const UInt_t* AliRawReaderRoot::GetDetectorPattern() const |
04fa961a | 265 | { |
266 | // get the detector pattern from the event header | |
267 | ||
33314186 | 268 | if (!fEventHeader) return NULL; |
269 | return fEventHeader->GetP("DetectorPattern"); | |
04fa961a | 270 | } |
271 | ||
42d20574 | 272 | const UInt_t* AliRawReaderRoot::GetAttributes() const |
04fa961a | 273 | { |
274 | // get the type attributes from the event header | |
275 | ||
33314186 | 276 | if (!fEventHeader) return NULL; |
277 | return fEventHeader->GetP("TypeAttribute"); | |
04fa961a | 278 | } |
279 | ||
e94ad92c | 280 | const UInt_t* AliRawReaderRoot::GetSubEventAttributes() const |
281 | { | |
282 | // get the type attributes from the sub event header | |
283 | ||
284 | if (!fSubEvent) return NULL; | |
f2dc6b20 | 285 | return fSubEvent->GetHeader()->GetP("TypeAttribute"); |
e94ad92c | 286 | } |
287 | ||
c946ab02 | 288 | UInt_t AliRawReaderRoot::GetLDCId() const |
289 | { | |
290 | // get the LDC Id from the event header | |
291 | ||
94d918a7 | 292 | if (!fEvent || !fSubEvent) return 0; |
f2dc6b20 | 293 | return fSubEvent->GetHeader()->Get("LdcId"); |
c946ab02 | 294 | } |
295 | ||
42d20574 | 296 | UInt_t AliRawReaderRoot::GetGDCId() const |
04fa961a | 297 | { |
298 | // get the GDC Id from the event header | |
299 | ||
33314186 | 300 | if (!fEventHeader) return 0; |
301 | return fEventHeader->Get("GdcId"); | |
04fa961a | 302 | } |
303 | ||
741c154c | 304 | UInt_t AliRawReaderRoot::GetTimestamp() const |
305 | { | |
33314186 | 306 | if (!fEventHeader) return 0; |
307 | return fEventHeader->Get("Timestamp"); | |
741c154c | 308 | } |
04fa961a | 309 | |
c946ab02 | 310 | Int_t AliRawReaderRoot::GetEquipmentSize() const |
311 | { | |
312 | // get the size of the equipment | |
313 | ||
94d918a7 | 314 | if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return 0; |
315 | return fEquipment->GetEquipmentHeader()->GetEquipmentSize(); | |
c946ab02 | 316 | } |
317 | ||
318 | Int_t AliRawReaderRoot::GetEquipmentType() const | |
319 | { | |
320 | // get the type from the equipment header | |
321 | ||
94d918a7 | 322 | if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return -1; |
323 | return fEquipment->GetEquipmentHeader()->GetEquipmentType(); | |
c946ab02 | 324 | } |
325 | ||
326 | Int_t AliRawReaderRoot::GetEquipmentId() const | |
327 | { | |
328 | // get the ID from the equipment header | |
329 | ||
94d918a7 | 330 | if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return -1; |
331 | return fEquipment->GetEquipmentHeader()->GetId(); | |
c946ab02 | 332 | } |
333 | ||
334 | const UInt_t* AliRawReaderRoot::GetEquipmentAttributes() const | |
335 | { | |
336 | // get the attributes from the equipment header | |
337 | ||
94d918a7 | 338 | if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return NULL; |
339 | return fEquipment->GetEquipmentHeader()->GetTypeAttribute(); | |
c946ab02 | 340 | } |
341 | ||
342 | Int_t AliRawReaderRoot::GetEquipmentElementSize() const | |
343 | { | |
344 | // get the basic element size from the equipment header | |
345 | ||
94d918a7 | 346 | if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return 0; |
347 | return fEquipment->GetEquipmentHeader()->GetBasicSizeType(); | |
c946ab02 | 348 | } |
349 | ||
299738b9 | 350 | Int_t AliRawReaderRoot::GetEquipmentHeaderSize() const |
351 | { | |
352 | // get the size of the equipment header (28 bytes by default) | |
353 | ||
354 | if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return 0; | |
355 | return fEquipment->GetEquipmentHeader()->HeaderSize(); | |
356 | } | |
357 | ||
edd06192 | 358 | // _________________________________________________________________________ |
edd06192 | 359 | void AliRawReaderRoot::SwapData(const void* inbuf, const void* outbuf, UInt_t size) { |
360 | // The method swaps the contents of the | |
361 | // raw-data event header | |
91f76e9b | 362 | UInt_t intCount = (size+3)/sizeof(UInt_t); |
edd06192 | 363 | |
364 | UInt_t* buf = (UInt_t*) inbuf; // temporary integers buffer | |
365 | for (UInt_t i=0; i<intCount; i++, buf++) { | |
366 | UInt_t value = SwapWord(*buf); | |
dae3f0d9 | 367 | if (i==(intCount-1)) |
368 | memcpy((UInt_t*)outbuf+i, &value, size%sizeof(UInt_t)); | |
369 | else | |
370 | memcpy((UInt_t*)outbuf+i, &value, sizeof(UInt_t)); | |
edd06192 | 371 | } |
372 | } | |
373 | // _________________________________________________________________________ | |
c946ab02 | 374 | |
375 | Bool_t AliRawReaderRoot::ReadHeader() | |
04fa961a | 376 | { |
39f9963f | 377 | // read a data header at the current position |
378 | // returns kFALSE if the data header could not be read | |
04fa961a | 379 | |
b4857df7 | 380 | fErrorCode = 0; |
04fa961a | 381 | if (!fEvent) return kFALSE; |
b4857df7 | 382 | |
04fa961a | 383 | do { |
b4857df7 | 384 | // skip payload (if event was not selected) |
385 | if (fCount > 0) fPosition += fCount; | |
386 | ||
94d918a7 | 387 | // get the first or the next equipment if at the end of an equipment |
388 | if (!fEquipment || (fPosition >= fEnd)) { | |
b4857df7 | 389 | |
94d918a7 | 390 | // get the first or the next sub event if at the end of a sub event |
391 | if (!fSubEvent || (fEquipmentIndex >= fSubEvent->GetNEquipments())) { | |
b4857df7 | 392 | |
94d918a7 | 393 | // check for end of event data |
394 | if (fSubEventIndex >= fEvent->GetNSubEvents()) return kFALSE; | |
395 | fSubEvent = fEvent->GetSubEvent(fSubEventIndex++); | |
396 | ||
397 | // check the magic word of the sub event | |
398 | if (!fSubEvent->GetHeader()->IsValid()) { | |
399 | Error("ReadHeader", "wrong magic number in sub event!"); | |
400 | fSubEvent->GetHeader()->Dump(); | |
401 | fErrorCode = kErrMagic; | |
402 | return kFALSE; | |
403 | } | |
404 | ||
405 | fEquipmentIndex = 0; | |
406 | fEquipment = NULL; | |
407 | fRawData = NULL; | |
b4857df7 | 408 | } |
409 | ||
94d918a7 | 410 | // get the next equipment and raw data |
04fa961a | 411 | fCount = 0; |
f49c01bc | 412 | if (fEquipmentIndex >= fSubEvent->GetNEquipments()) { |
413 | fEquipment = NULL; | |
414 | continue; | |
415 | } | |
94d918a7 | 416 | fEquipment = fSubEvent->GetEquipment(fEquipmentIndex++); |
417 | if (!fEquipment) continue; | |
3d65cc80 | 418 | if (!IsSelected()) { |
419 | fPosition = fEnd; | |
420 | continue; | |
421 | } | |
94d918a7 | 422 | fRawData = fEquipment->GetRawData(); |
423 | if (!fRawData) { | |
424 | fPosition = fEnd; | |
425 | continue; | |
426 | } | |
04fa961a | 427 | fPosition = (UChar_t*) fRawData->GetBuffer(); |
428 | fEnd = ((UChar_t*) fRawData->GetBuffer()) + fRawData->GetSize(); | |
429 | } | |
b4857df7 | 430 | |
94d918a7 | 431 | // continue with the next equipment if no data left in the payload |
b4857df7 | 432 | if (fPosition >= fEnd) continue; |
433 | ||
18882b3b | 434 | if (fRequireHeader) { |
435 | // check that there are enough bytes left for the data header | |
436 | if (fPosition + sizeof(AliRawDataHeader) > fEnd) { | |
437 | Error("ReadHeader", "could not read data header!"); | |
6c12d59f | 438 | Warning("ReadHeader", "skipping %ld bytes", fEnd - fPosition); |
18882b3b | 439 | fEquipment->GetEquipmentHeader()->Dump(); |
440 | fCount = 0; | |
441 | fPosition = fEnd; | |
442 | fErrorCode = kErrNoDataHeader; | |
443 | continue; | |
444 | } | |
445 | ||
446 | // "read" the data header | |
447 | fHeader = (AliRawDataHeader*) fPosition; | |
edd06192 | 448 | #ifndef R__BYTESWAP |
449 | SwapData((void*) fHeader, (void*) fHeaderSwapped, sizeof(AliRawDataHeader)); | |
450 | fHeader=fHeaderSwapped; | |
451 | #endif | |
299738b9 | 452 | if ((fPosition + fHeader->fSize) != fEnd) { |
806e573c | 453 | if (fHeader->fSize != 0xFFFFFFFF) |
454 | Warning("ReadHeader", | |
6c12d59f | 455 | "Equipment %d : raw data size found in the header is wrong (%d != %ld)! Using the equipment size instead !", |
806e573c | 456 | fEquipment->GetEquipmentHeader()->GetId(),fHeader->fSize, fEnd - fPosition); |
299738b9 | 457 | fHeader->fSize = fEnd - fPosition; |
458 | } | |
18882b3b | 459 | fPosition += sizeof(AliRawDataHeader); |
04fa961a | 460 | } |
b4857df7 | 461 | |
7c726b91 | 462 | if (fHeader && (fHeader->fSize != 0xFFFFFFFF)) { |
39f9963f | 463 | fCount = fHeader->fSize - sizeof(AliRawDataHeader); |
7c726b91 | 464 | |
465 | // check consistency of data size in the header and in the sub event | |
466 | if (fPosition + fCount > fEnd) { | |
467 | Error("ReadHeader", "size in data header exceeds event size!"); | |
6c12d59f | 468 | Warning("ReadHeader", "skipping %ld bytes", fEnd - fPosition); |
7c726b91 | 469 | fEquipment->GetEquipmentHeader()->Dump(); |
470 | fCount = 0; | |
471 | fPosition = fEnd; | |
472 | fErrorCode = kErrSize; | |
473 | continue; | |
474 | } | |
475 | ||
39f9963f | 476 | } else { |
477 | fCount = fEnd - fPosition; | |
72dd1d4f | 478 | } |
b4857df7 | 479 | |
04fa961a | 480 | } while (!IsSelected()); |
b4857df7 | 481 | |
04fa961a | 482 | return kTRUE; |
483 | } | |
484 | ||
485 | Bool_t AliRawReaderRoot::ReadNextData(UChar_t*& data) | |
486 | { | |
487 | // reads the next payload at the current position | |
488 | // returns kFALSE if the data could not be read | |
489 | ||
b4857df7 | 490 | fErrorCode = 0; |
04fa961a | 491 | while (fCount == 0) { |
c946ab02 | 492 | if (!ReadHeader()) return kFALSE; |
04fa961a | 493 | } |
494 | data = fPosition; | |
495 | fPosition += fCount; | |
496 | fCount = 0; | |
497 | return kTRUE; | |
498 | } | |
499 | ||
500 | Bool_t AliRawReaderRoot::ReadNext(UChar_t* data, Int_t size) | |
501 | { | |
502 | // reads the next block of data at the current position | |
503 | // returns kFALSE if the data could not be read | |
504 | ||
b4857df7 | 505 | fErrorCode = 0; |
04fa961a | 506 | if (fPosition + size > fEnd) { |
507 | Error("ReadNext", "could not read data!"); | |
b4857df7 | 508 | fErrorCode = kErrOutOfBounds; |
04fa961a | 509 | return kFALSE; |
510 | } | |
511 | memcpy(data, fPosition, size); | |
dae3f0d9 | 512 | |
04fa961a | 513 | fPosition += size; |
514 | fCount -= size; | |
515 | return kTRUE; | |
516 | } | |
517 | ||
518 | ||
519 | Bool_t AliRawReaderRoot::Reset() | |
520 | { | |
521 | // reset the current position to the beginning of the event | |
522 | ||
523 | fSubEventIndex = 0; | |
524 | fSubEvent = NULL; | |
94d918a7 | 525 | fEquipmentIndex = 0; |
526 | fEquipment = NULL; | |
04fa961a | 527 | fRawData = NULL; |
39f9963f | 528 | fHeader = NULL; |
04fa961a | 529 | |
530 | fCount = 0; | |
531 | fPosition = fEnd = NULL; | |
532 | return kTRUE; | |
533 | } | |
534 | ||
b4857df7 | 535 | |
dd9a70fe | 536 | Bool_t AliRawReaderRoot::NextEvent() |
537 | { | |
538 | // go to the next event in the root file | |
539 | ||
2da4ef20 | 540 | if (!fBranch) return kFALSE; |
dd9a70fe | 541 | |
1d6124f3 | 542 | // check if it uses order or not |
543 | if (fgUseOrder && !fIndex) MakeIndex(); | |
544 | ||
dd9a70fe | 545 | do { |
d41ecdd0 | 546 | delete fEvent; |
33314186 | 547 | fEvent = NULL; |
548 | fEventHeader = NULL; | |
d41ecdd0 | 549 | fBranch->SetAddress(&fEvent); |
1d6124f3 | 550 | Int_t entryToGet = fEventIndex + 1; |
551 | if (fgUseOrder | |
552 | && fIndex | |
553 | && entryToGet<fBranch->GetEntries() | |
554 | && entryToGet>-1 ) entryToGet = fIndex[entryToGet]; | |
555 | if (fBranch->GetEntry(entryToGet) <= 0) | |
dd9a70fe | 556 | return kFALSE; |
33314186 | 557 | fEventHeader = fEvent->GetHeader(); |
dd9a70fe | 558 | fEventIndex++; |
559 | } while (!IsEventSelected()); | |
38cf12f3 | 560 | fEventNumber++; |
dd9a70fe | 561 | return Reset(); |
562 | } | |
563 | ||
564 | Bool_t AliRawReaderRoot::RewindEvents() | |
565 | { | |
566 | // go back to the beginning of the root file | |
567 | ||
2da4ef20 | 568 | if (!fBranch) return kFALSE; |
dd9a70fe | 569 | |
570 | fEventIndex = -1; | |
571 | delete fEvent; | |
33314186 | 572 | fEvent = NULL; |
573 | fEventHeader = NULL; | |
dd9a70fe | 574 | fBranch->SetAddress(&fEvent); |
38cf12f3 | 575 | fEventNumber = -1; |
dd9a70fe | 576 | return Reset(); |
577 | } | |
578 | ||
636c1780 | 579 | Bool_t AliRawReaderRoot::GotoEvent(Int_t event) |
580 | { | |
581 | // go to a particular event | |
582 | // Uses the absolute event index inside the | |
583 | // raw-data file | |
584 | ||
585 | if (!fBranch) return kFALSE; | |
586 | ||
1d6124f3 | 587 | // check if it uses order or not |
588 | if (fgUseOrder && !fIndex) MakeIndex(); | |
589 | ||
636c1780 | 590 | delete fEvent; |
33314186 | 591 | fEvent = NULL; |
592 | fEventHeader = NULL; | |
636c1780 | 593 | fBranch->SetAddress(&fEvent); |
1d6124f3 | 594 | Int_t entryToGet = event; |
595 | if (fgUseOrder | |
596 | && fIndex | |
597 | && entryToGet<fBranch->GetEntries() | |
598 | && entryToGet>-1 ) entryToGet = fIndex[entryToGet]; | |
599 | if (fBranch->GetEntry(entryToGet) <= 0) | |
636c1780 | 600 | return kFALSE; |
33314186 | 601 | fEventHeader = fEvent->GetHeader(); |
636c1780 | 602 | fEventIndex = event; |
603 | fEventNumber++; | |
604 | return Reset(); | |
605 | } | |
dd9a70fe | 606 | |
25e82ff5 | 607 | Int_t AliRawReaderRoot::GetNumberOfEvents() const |
608 | { | |
609 | // Get the total number of events in | |
610 | // the raw-data tree | |
611 | ||
612 | if (!fBranch) return -1; | |
613 | ||
614 | return fBranch->GetEntries(); | |
615 | } | |
616 | ||
b4857df7 | 617 | Int_t AliRawReaderRoot::CheckData() const |
618 | { | |
619 | // check the consistency of the data | |
620 | ||
621 | if (!fEvent) return 0; | |
622 | ||
33314186 | 623 | AliRawVEvent* subEvent = NULL; |
b4857df7 | 624 | Int_t subEventIndex = 0; |
33314186 | 625 | AliRawVEquipment* equipment = NULL; |
94d918a7 | 626 | Int_t equipmentIndex = 0; |
b4857df7 | 627 | UChar_t* position = 0; |
628 | UChar_t* end = 0; | |
be50fca2 | 629 | Int_t result = 0; |
b4857df7 | 630 | |
631 | while (kTRUE) { | |
94d918a7 | 632 | // get the first or the next sub event if at the end of an equipment |
633 | if (!subEvent || (equipmentIndex >= subEvent->GetNEquipments())) { | |
b4857df7 | 634 | |
635 | // check for end of event data | |
be50fca2 | 636 | if (subEventIndex >= fEvent->GetNSubEvents()) return result; |
b4857df7 | 637 | subEvent = fEvent->GetSubEvent(subEventIndex++); |
638 | ||
639 | // check the magic word of the sub event | |
be50fca2 | 640 | if (!fSubEvent->GetHeader()->IsValid()) { |
641 | result |= kErrMagic; | |
642 | return result; | |
643 | } | |
b4857df7 | 644 | |
94d918a7 | 645 | equipmentIndex = 0; |
b4857df7 | 646 | } |
647 | ||
94d918a7 | 648 | // get the next equipment and raw data |
f49c01bc | 649 | if (equipmentIndex >= subEvent->GetNEquipments()) { |
650 | equipment = NULL; | |
651 | continue; | |
652 | } | |
94d918a7 | 653 | equipment = subEvent->GetEquipment(equipmentIndex++); |
654 | if (!equipment) continue; | |
655 | AliRawData* rawData = equipment->GetRawData(); | |
656 | if (!rawData) continue; | |
657 | position = (UChar_t*) rawData->GetBuffer(); | |
658 | end = ((UChar_t*) rawData->GetBuffer()) + rawData->GetSize(); | |
659 | ||
b4857df7 | 660 | // continue with the next sub event if no data left in the payload |
661 | if (position >= end) continue; | |
662 | ||
18882b3b | 663 | if (fRequireHeader) { |
39f9963f | 664 | // check that there are enough bytes left for the data header |
18882b3b | 665 | if (position + sizeof(AliRawDataHeader) > end) { |
666 | result |= kErrNoDataHeader; | |
667 | continue; | |
668 | } | |
b4857df7 | 669 | |
18882b3b | 670 | // check consistency of data size in the header and in the equipment |
671 | AliRawDataHeader* header = (AliRawDataHeader*) position; | |
299738b9 | 672 | if ((position + header->fSize) != end) { |
806e573c | 673 | if (header->fSize != 0xFFFFFFFF) |
674 | Warning("ReadHeader", | |
6c12d59f | 675 | "Equipment %d : raw data size found in the header is wrong (%d != %ld)! Using the equipment size instead !", |
806e573c | 676 | equipment->GetEquipmentHeader()->GetId(),header->fSize, end - position); |
299738b9 | 677 | header->fSize = end - position; |
678 | result |= kErrSize; | |
39f9963f | 679 | } |
be50fca2 | 680 | } |
299738b9 | 681 | position = end; |
b4857df7 | 682 | }; |
fd0de2e2 | 683 | |
684 | return result; | |
b4857df7 | 685 | } |
b900a426 | 686 | |
687 | AliRawReader* AliRawReaderRoot::CloneSingleEvent() const | |
688 | { | |
689 | // Clones the current event and | |
690 | // creates raw-reader for the cloned event | |
691 | // Can be used in order to make asynchronious | |
692 | // access to the current raw data within | |
693 | // several threads (online event display/reco) | |
694 | ||
243e7b72 | 695 | if (fEvent) { |
b900a426 | 696 | // Root formatted raw data |
243e7b72 | 697 | AliRawVEvent *gdcRootEvent = (AliRawVEvent*)fEvent->Clone(); |
b900a426 | 698 | for (Int_t ldcCounter=0; ldcCounter < gdcRootEvent->GetNSubEvents(); ldcCounter++) { |
699 | AliRawVEvent *ldcRootEvent = gdcRootEvent->GetSubEvent(ldcCounter); | |
243e7b72 | 700 | AliRawVEvent *subEvent = fEvent->GetSubEvent(ldcCounter); |
b900a426 | 701 | for (Int_t eqCounter=0; eqCounter < ldcRootEvent->GetNEquipments(); eqCounter++) { |
702 | AliRawVEquipment *equipment=ldcRootEvent->GetEquipment(eqCounter); | |
243e7b72 | 703 | AliRawVEquipment *eq = subEvent->GetEquipment(eqCounter); |
704 | equipment->CloneRawData(eq->GetRawData()); | |
b900a426 | 705 | } |
706 | } | |
243e7b72 | 707 | // Reset original event and newly |
708 | // produced one | |
709 | gdcRootEvent->GetSubEvent(-1); | |
710 | fEvent->GetSubEvent(-1); | |
b900a426 | 711 | return new AliRawReaderRoot(gdcRootEvent); |
712 | } | |
713 | return NULL; | |
714 | } | |
1d6124f3 | 715 | |
716 | void AliRawReaderRoot::MakeIndex() { | |
717 | // Make index | |
718 | if (fBranch) { | |
719 | TTree * rawTree = fBranch->GetTree(); | |
720 | if (rawTree) { | |
721 | rawTree->BuildIndex("-fEvtHdrs[0].fSize"); // Minus sign to get largest first | |
722 | TTreeIndex * treeInd = (TTreeIndex*)rawTree->GetTreeIndex(); | |
723 | if (treeInd) fIndex = treeInd->GetIndex(); | |
724 | } | |
725 | } | |
726 | } |