bugfix: instead of unloading from the cache, retrieve the latest version and subversi...
[u/mrichter/AliRoot.git] / HLT / rec / AliRawReaderHLT.cxx
CommitLineData
7e914051 1// $Id$
9c7b5023 2
3/**************************************************************************
4 * This file is property of and copyright by the ALICE HLT Project *
5 * ALICE Experiment at CERN, All rights reserved. *
6 * *
7 * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 * for The ALICE HLT Project. *
9 * *
10 * Permission to use, copy, modify and distribute this software and its *
11 * documentation strictly for non-commercial purposes is hereby granted *
12 * without fee, provided that the above copyright notice appears in all *
13 * copies and that both the copyright notice and this permission notice *
14 * appear in the supporting documentation. The authors make no claims *
15 * about the suitability of this software for any purpose. It is *
16 * provided "as is" without express or implied warranty. *
17 **************************************************************************/
18
19/** @file AliRawReaderHLT.cxx
20 @author Matthias Richter
21 @date
22 @brief AliRawReader implementation which replaces original input of
23 detectors with the appropriate HLT output. */
24
25// see header file for class documentation
26// or
27// refer to README to build package
28// or
29// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
30
31#include "AliRawReaderHLT.h"
13b78f4c 32#include "AliHLTOUTRawReader.h"
33#include "AliHLTModuleAgent.h"
626bfcc1 34#include "AliHLTOUTHandler.h"
35#include "AliHLTOUTHandlerEquId.h"
a3ef3c1d 36#include "AliHLTSystem.h"
00ddfaca 37#include "AliHLTPluginBase.h"
e3917543 38#include "AliLog.h"
13b78f4c 39#include "AliDAQ.h" // RAW, for detector names and equipment ids
40#include "TObjString.h"
41#include <cassert>
9c7b5023 42
43/** ROOT macro for the implementation of ROOT specific class methods */
44ClassImp(AliRawReaderHLT)
45
46AliRawReaderHLT::AliRawReaderHLT(AliRawReader* pRawreader, const char* options)
47 :
48 AliRawReader(),
49 fpParentReader(pRawreader),
13b78f4c 50 fOptions(),
a3ef3c1d 51 fSystemOptions(),
13b78f4c 52 fpData(NULL),
53 fDataSize(0),
54 fOffset(0),
d3833f99 55 fPosition(0),
13b78f4c 56 fEquipmentId(-1),
57 fbHaveHLTData(false),
58 fDetectors(),
626bfcc1 59 fpHLTOUT(NULL),
44dc7683 60 fbReadFirst(true),
00ddfaca 61 fpDataHandler(NULL),
62 fpPluginBase(new AliHLTPluginBase)
9c7b5023 63{
64 // see header file for class documentation
65 // or
66 // refer to README to build package
67 // or
68 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
69 fOptions=options;
13b78f4c 70 ScanOptions(options);
9c7b5023 71}
72
73AliRawReaderHLT::~AliRawReaderHLT()
74{
75 // see header file for class documentation
d3833f99 76 ReleaseHLTData();
00ddfaca 77 if (fpPluginBase) delete fpPluginBase;
78 fpPluginBase=NULL;
9c7b5023 79}
80
81UInt_t AliRawReaderHLT::GetType() const
82{
83 // see header file for class documentation
84 return fpParentReader->GetType();
85}
86
87UInt_t AliRawReaderHLT::GetRunNumber() const
88{
89 // see header file for class documentation
90 return fpParentReader->GetRunNumber();
91}
92
93const UInt_t* AliRawReaderHLT::GetEventId() const
94{
95 // see header file for class documentation
96 return fpParentReader->GetEventId();
97}
98
99const UInt_t* AliRawReaderHLT::GetTriggerPattern() const
100{
101 // see header file for class documentation
102 return fpParentReader->GetTriggerPattern();
103}
104
105const UInt_t* AliRawReaderHLT::GetDetectorPattern() const
106{
107 // see header file for class documentation
108 return fpParentReader->GetDetectorPattern();
109}
110
111const UInt_t* AliRawReaderHLT::GetAttributes() const
112{
113 // see header file for class documentation
114 return fpParentReader->GetAttributes();
115}
116
117const UInt_t* AliRawReaderHLT::GetSubEventAttributes() const
118{
119 // see header file for class documentation
120 return fpParentReader->GetSubEventAttributes();
121}
122
123UInt_t AliRawReaderHLT::GetLDCId() const
124{
125 // see header file for class documentation
126 return fpParentReader->GetLDCId();
127}
128
129UInt_t AliRawReaderHLT::GetGDCId() const
130{
131 // see header file for class documentation
132 return fpParentReader->GetGDCId();
133}
134
135UInt_t AliRawReaderHLT::GetTimestamp() const
136{
137 // see header file for class documentation
138 return fpParentReader->GetTimestamp();
139}
140
141const UInt_t* AliRawReaderHLT::GetEquipmentAttributes() const
142{
143 // see header file for class documentation
144 return fpParentReader->GetEquipmentAttributes();
145}
146
147Int_t AliRawReaderHLT::GetEquipmentElementSize() const
148{
149 // see header file for class documentation
13b78f4c 150 // don't know what it really means, bu the AliRawReaderFile
151 // just sets it to 0
152 // do the same if we have a valid equipment data set from
153 // the HLT stream
154 if (fEquipmentId>=0) return 0;
9c7b5023 155 return fpParentReader->GetEquipmentElementSize();
156}
157
158Int_t AliRawReaderHLT::GetEquipmentHeaderSize() const
159{
160 // see header file for class documentation
13b78f4c 161
162 // equipment header means the additional data header?
163 // if we have a valid equipment data set from the HLT stream
164 // there is no additional header
165 if (fEquipmentId>=0) return 0;
9c7b5023 166 return fpParentReader->GetEquipmentHeaderSize();
167}
168
169Int_t AliRawReaderHLT::GetEquipmentSize() const
170{
171 // see header file for class documentation
13b78f4c 172 if (fEquipmentId>=0) return fDataSize+sizeof(AliRawDataHeader);
9c7b5023 173 return fpParentReader->GetEquipmentSize();
174}
175
176Int_t AliRawReaderHLT::GetEquipmentType() const
177{
178 // see header file for class documentation
179 return fpParentReader->GetEquipmentType();
180}
181
182Int_t AliRawReaderHLT::GetEquipmentId() const
183{
184 // see header file for class documentation
13b78f4c 185 Int_t id=-1;
186 if (fEquipmentId>=0) id=fEquipmentId;
187 else id=fpParentReader->GetEquipmentId();
e3917543 188 return id;
9c7b5023 189}
190
191Bool_t AliRawReaderHLT::ReadHeader()
192{
193 // see header file for class documentation
e94eb049 194 Bool_t result=kFALSE;
d3833f99 195 Bool_t firstParentCycle=fbHaveHLTData;
9d5f00ad 196 while ((fbHaveHLTData=(fbHaveHLTData && ReadNextHLTData()))) {
e94eb049 197 // all internal data variables set
198 assert(fpData!=NULL);
199 fHeader=reinterpret_cast<AliRawDataHeader*>(const_cast<AliHLTUInt8_t*>(fpData));
d3833f99 200 fOffset=sizeof(AliRawDataHeader);
201 fPosition=fOffset;
9d5f00ad 202 if ((result=IsSelected())) break;
e94eb049 203 }
d3833f99 204 firstParentCycle&=!fbHaveHLTData; // true if it just changed from true to false
205 while (!result) {
206 if (firstParentCycle) {
207 firstParentCycle=kFALSE;
208 // reset and set the selection back to the original one
209 fpParentReader->Reset();
210 fpParentReader->SelectEquipment(fSelectEquipmentType, fSelectMinEquipmentId, fSelectMaxEquipmentId);
211 }
e94eb049 212
d3833f99 213 if (!(result=fpParentReader->ReadHeader())) {
214 fHeader=NULL;
215 break;
216 }
e94eb049 217 fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader());
4cd5258a 218 fDataSize=fpParentReader->GetDataSize();
219 fPosition=0;
220 fpData=NULL;
d3833f99 221
222 // filter out all equipment ids which should be taken from the HLT stream
223 int id=fpParentReader->GetEquipmentId();
9d5f00ad 224 if ((result=!IsHLTInput(id))) break;
e94eb049 225 }
e3917543 226 return result;
9c7b5023 227}
228
229Bool_t AliRawReaderHLT::ReadNextData(UChar_t*& data)
4cd5258a 230{
231 // see header file for class documentation
232 return ReadNextData(data, kTRUE);
233}
234
235Bool_t AliRawReaderHLT::ReadNextData(UChar_t*& data, Bool_t readHeader)
9c7b5023 236{
237 // see header file for class documentation
13b78f4c 238
239 // this function is the backbone of the ReadNext functions, it gets the
240 // whole data block either from the HLT stream or the parent raw reader.
241 // Each call of ReadNextData directly jumps to the next data set.
d3833f99 242 Bool_t result=kTRUE;
243
244 // read new header if data already read
4cd5258a 245 if (fPosition<fDataSize || (result=(readHeader && ReadHeader()))) {
44dc7683 246 if (fbHaveHLTData && fpHLTOUT!=NULL) {
d3833f99 247 // all internal data variables set
248 result=kTRUE;
249 data=const_cast<AliHLTUInt8_t*>(fpData+sizeof(AliRawDataHeader));
21743c3a 250 // fpData includes the CDH, set offset behind CDH
251 fOffset=sizeof(AliRawDataHeader);
13b78f4c 252 } else {
d3833f99 253 // no data in the HLT stream, read real data
254 //AliInfo(Form("read from parent reader: min=%d max=%d", fSelectMinEquipmentId, fSelectMaxEquipmentId));
255
256 // read data
257 result=fpParentReader->ReadNextData(data);
258 if (result) {
259 fpData=data;
260 fDataSize=fpParentReader->GetDataSize();
21743c3a 261 // fpData is without CDH
262 fOffset=0;
d3833f99 263 } else {
264 fpData=NULL;
265 fDataSize=0;
266 }
267
268 fEquipmentId=-1;
13b78f4c 269 }
d3833f99 270 fPosition=fDataSize;
13b78f4c 271 }
e3917543 272 return result;
9c7b5023 273}
274
275Bool_t AliRawReaderHLT::ReadNextInt(UInt_t& data)
276{
277 // see header file for class documentation
13b78f4c 278 int iCopy=sizeof(UInt_t);
279 UChar_t* dummy=NULL;
280 do {
281 if (fpData && (fDataSize-fOffset)>=iCopy) {
282 data=*reinterpret_cast<const UInt_t*>(fpData+fOffset);
283 fOffset+=iCopy;
284 return kTRUE;
285 }
4cd5258a 286 } while (ReadNextData(dummy, kTRUE));
13b78f4c 287 return kFALSE;
9c7b5023 288}
289
290Bool_t AliRawReaderHLT::ReadNextShort(UShort_t& data)
291{
292 // see header file for class documentation
13b78f4c 293 int iCopy=sizeof(UShort_t);
294 UChar_t* dummy=NULL;
295 do {
296 if (fpData && (fDataSize-fOffset)>=iCopy) {
297 data=*reinterpret_cast<const UShort_t*>(fpData+fOffset);
298 fOffset+=iCopy;
299 return kTRUE;
300 }
4cd5258a 301 } while (ReadNextData(dummy, kTRUE));
13b78f4c 302 return kFALSE;
9c7b5023 303}
304
305Bool_t AliRawReaderHLT::ReadNextChar(UChar_t& data)
306{
307 // see header file for class documentation
13b78f4c 308 int iCopy=sizeof(UChar_t);
309 UChar_t* dummy=NULL;
310 do {
311 if (fpData && (fDataSize-fOffset)>=iCopy) {
312 data=*reinterpret_cast<const UChar_t*>(fpData+fOffset);
313 fOffset+=iCopy;
314 return kTRUE;
315 }
4cd5258a 316 } while (ReadNextData(dummy, kTRUE));
13b78f4c 317 return kFALSE;
9c7b5023 318}
319
320Bool_t AliRawReaderHLT::ReadNext(UChar_t* data, Int_t size)
321{
322 // see header file for class documentation
13b78f4c 323 UChar_t* dummy=NULL;
324 do {
325 if (fpData && (fDataSize-fOffset)>=size) {
326 // copy remaining data
327 int iCopy=fDataSize-fOffset;
328 if (iCopy>size) iCopy=size;
329 memcpy(data, fpData+fOffset, iCopy);
330 fOffset+=iCopy;
331 return kTRUE;
332 }
4cd5258a 333 // By convention, the ReadNextData function stays in the
334 // current block and does not switch to the next one
335 // automatically -> kFALSE
336 } while (ReadNextData(dummy, kFALSE));
13b78f4c 337 return kFALSE;
9c7b5023 338}
339
340Bool_t AliRawReaderHLT::Reset()
341{
342 // see header file for class documentation
44dc7683 343 ReleaseHLTData(false/* keep HLTOUT instance */);
13b78f4c 344 Bool_t result=fpParentReader->Reset();
13b78f4c 345 fEquipmentId=-1;
626bfcc1 346
d3833f99 347 // check if redirection is enabled for at least one detector in the selected range
348 fbHaveHLTData=EvaluateSelection();
626bfcc1 349
44dc7683 350 // start reading HLTOUT data blocks from the beginning
351 fbReadFirst=true;
352
13b78f4c 353 return result;
9c7b5023 354}
355
356Bool_t AliRawReaderHLT::NextEvent()
357{
358 // see header file for class documentation
44dc7683 359
360 ReleaseHLTData();
361
e3917543 362 Bool_t result=fpParentReader->NextEvent();
13b78f4c 363 if (result) {
364 fEventNumber++;
365 Reset();
366 }
e3917543 367 return result;
9c7b5023 368}
369
370Bool_t AliRawReaderHLT::RewindEvents()
371{
372 // see header file for class documentation
e3917543 373 fEventNumber=-1;
13b78f4c 374 Reset();
9c7b5023 375 return fpParentReader->RewindEvents();
376}
377
e3917543 378void AliRawReaderHLT::Select(Int_t detectorID, Int_t minDDLID, Int_t maxDDLID)
379{
13b78f4c 380 // see header file for class documentation
e3917543 381 AliRawReader::Select(detectorID, minDDLID, maxDDLID);
382 fpParentReader->Select(detectorID, minDDLID, maxDDLID);
d3833f99 383 fbHaveHLTData=EvaluateSelection();
e3917543 384}
385
386// most likely we do not need this method since the base class directly forwards
387// to this method
388// void AliRawReaderHLT::Select(const char *detectorName, Int_t minDDLID, Int_t maxDDLID)
389// {
390// AliInfo(Form("detectorName=%s, minDDLID=%d, maxDDLID=%d", detectorName, minDDLID, maxDDLID));
391// AliRawReader::Select(detectorName, minDDLID, maxDDLID);
392// fpParentReader->Select(detectorName, minDDLID, maxDDLID);
393// }
394
395void AliRawReaderHLT::SelectEquipment(Int_t equipmentType, Int_t minEquipmentId, Int_t maxEquipmentId)
396{
13b78f4c 397 // see header file for class documentation
398
093f4dba 399 //AliInfo(Form("equipmentType=%d, minEquipmentId=%d, maxEquipmentId=%d", equipmentType, minEquipmentId, maxEquipmentId));
d3833f99 400 AliRawReader::SelectEquipment(equipmentType, minEquipmentId, maxEquipmentId);
401 fpParentReader->SelectEquipment(equipmentType, minEquipmentId, maxEquipmentId);
402 fbHaveHLTData=EvaluateSelection();
e3917543 403}
404
405void AliRawReaderHLT::SkipInvalid(Bool_t skip)
406{
13b78f4c 407 // see header file for class documentation
408
e3917543 409 AliRawReader::SkipInvalid(skip);
410 fpParentReader->SkipInvalid(skip);
411}
412
3f7450e0 413/*
e3917543 414void AliRawReaderHLT::SelectEvents(Int_t type)
415{
13b78f4c 416 // see header file for class documentation
417
093f4dba 418 //AliInfo(Form("type=%d", type));
e3917543 419 AliRawReader::SelectEvents(type);
420 fpParentReader->SelectEvents(type);
421}
3f7450e0 422*/
e3917543 423
13b78f4c 424int AliRawReaderHLT::ScanOptions(const char* options)
425{
426 // see header file for class documentation
427 int iResult=0;
428 TString optString(options);
429 TString argument;
430 TString parameter;
21743c3a 431 TString detectors;
13b78f4c 432 TObjArray* pTokens=optString.Tokenize(" ");
433 if (pTokens) {
434 int iEntries=pTokens->GetEntries();
435 for (int i =0; i<iEntries; i++) {
436 argument=((TObjString*)pTokens->At(i))->GetString();
437 // first scan all the other options
438 // no other options for the moment
439
440 // it must be a detector name
441 int detId=AliDAQ::DetectorID(argument.Data());
442 if (detId>=0) {
443 fDetectors.push_back(detId);
21743c3a 444 if (!detectors.IsNull()) detectors+=" ";
445 detectors+=argument;
a3ef3c1d 446 } else {
447 if (!fSystemOptions.IsNull()) fSystemOptions+=" ";
448 fSystemOptions+=argument;
13b78f4c 449 }
450 }
451 delete pTokens;
452 }
453
21743c3a 454 if (iResult>=0 && !detectors.IsNull()) {
455 AliInfo(Form("running reconstruction from HLT data: %s", detectors.Data()));
456 }
13b78f4c 457 return iResult;
458}
459
460Bool_t AliRawReaderHLT::ReadNextHLTData()
461{
462 // see header file for class documentation
463 bool result=kTRUE;
44dc7683 464 if (fbReadFirst || !fpHLTOUT) {
465 if (!fpHLTOUT) {
13b78f4c 466 fpHLTOUT=new AliHLTOUTRawReader(fpParentReader);
9d5f00ad 467 if ((result=(fpHLTOUT!=NULL))) {
00ddfaca 468 if (!fpPluginBase) {
469 AliFatal("internal data error: can not get AliHLTSystem instance from plugin");
470 return false;
471 }
472 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
a3ef3c1d 473 if (pSystem) {
474 pSystem->ScanOptions(fSystemOptions.Data());
475 }
9d5f00ad 476 if ((result=(fpHLTOUT->Init())>=0)) {
13b78f4c 477 }
478 }
44dc7683 479 }
480 if (result) {
481 result=fpHLTOUT->SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec,
482 AliHLTModuleAgent::kRawReader)>=0;
483 }
484 fbReadFirst=false;
13b78f4c 485 } else {
626bfcc1 486 // first release the data buffer
d3833f99 487 ReleaseHLTData(false /* keep HLTOUT instance */);
488 result=fpHLTOUT->SelectNextDataBlock()>=0;
13b78f4c 489 }
490 if (result) {
626bfcc1 491 AliHLTComponentDataType dt=kAliHLTVoidDataType;
492 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
493 fpHLTOUT->GetDataBlockDescription(dt, spec);
13b78f4c 494 AliHLTUInt32_t size=0;
626bfcc1 495 AliHLTOUTHandler* pHandler=fpHLTOUT->GetHandler();
496 if (pHandler) {
497 if (dynamic_cast<AliHLTOUTHandlerEquId*>(pHandler)!=NULL) {
0f1882a7 498 AliHLTOUT::AliHLTOUTSelectionGuard g(fpHLTOUT);
626bfcc1 499 fEquipmentId=pHandler->ProcessData(fpHLTOUT);
500 fpData=NULL;
501 fDataSize=pHandler->GetProcessedData(fpData);
502 if (!fpData) {
503 result=fpHLTOUT->GetDataBuffer(fpData, size)>=0;
44dc7683 504 fpDataHandler=NULL;
626bfcc1 505 AliDebug(AliLog::kDebug, Form("forward data block from HLTOUT stream to equipment %d", fEquipmentId));
506 fDataSize=(int)size;
507 } else {
508 // remember the current handler in order to properly release the data buffer
509 fpDataHandler=pHandler;
510 AliDebug(AliLog::kDebug, Form("forward decoded data block provided by handler to equipment %d", fEquipmentId));
511 }
e94eb049 512 return kTRUE;
626bfcc1 513 } else {
514 AliError(Form("handler is not of type AliHLTOUTHandlerEquId for block %x data type %s spec %#x; data block skipped",
515 fpHLTOUT->GetDataBlockIndex(), AliHLTComponent::DataType2Text(dt).c_str(), spec));
516 }
517 } else {
518 AliWarning(Form("no data handler found for block %x data type %s spec %#x; data block skipped",
519 fpHLTOUT->GetDataBlockIndex(), AliHLTComponent::DataType2Text(dt).c_str(), spec));
520 }
13b78f4c 521 } else {
44dc7683 522 ReleaseHLTData(false /* keep HLTOUT instance */);
13b78f4c 523 }
e94eb049 524 return kFALSE;
13b78f4c 525}
526
527Bool_t AliRawReaderHLT::IsHLTInput(int ddlid)
528{
529 // see header file for class documentation
530 vector<int>::iterator detector=fDetectors.begin();
531 for (; detector!=fDetectors.end(); detector++) {
532 int ddlOffset=AliDAQ::DdlIDOffset(*detector);
533 int nofDDLs=AliDAQ::NumberOfDdls(*detector);
534 if (ddlid>=ddlOffset && ddlid<ddlOffset+nofDDLs)
535 return kTRUE;
536 }
537 return kFALSE;
538}
539
d3833f99 540int AliRawReaderHLT::ReleaseHLTData(bool bReleaseHLTOUT)
541{
542 // see header file for class documentation
543 if (fpHLTOUT) {
544 if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize);
545 else fpHLTOUT->ReleaseDataBuffer(fpData);
546 fpDataHandler=NULL;
547 if (bReleaseHLTOUT) {
548 delete fpHLTOUT;
549 fpHLTOUT=NULL;
550 }
551 }
552
553 fpData=NULL;
554 fDataSize=0;
555 fOffset=0;
556 fPosition=0;
557 fEquipmentId=-1;
558
559 return 0;
560}
561
562Bool_t AliRawReaderHLT::EvaluateSelection()
563{
564 // see header file for class documentation
565 Bool_t bHaveHLTData=kFALSE;
9d5f00ad 566 if ((bHaveHLTData=(fDetectors.size())>0)) {
d3833f99 567 vector<int>::iterator detector=fDetectors.begin();
568 for (; detector!=fDetectors.end(); detector++) {
569 int ddlOffset=AliDAQ::DdlIDOffset(*detector);
570 int nofDDLs=AliDAQ::NumberOfDdls(*detector);
571 if ((fSelectMinEquipmentId<0 || fSelectMinEquipmentId<ddlOffset+nofDDLs) &&
572 (fSelectMaxEquipmentId<0 || fSelectMaxEquipmentId>=ddlOffset))
573 break;
574 }
575 bHaveHLTData=detector!=fDetectors.end();
576 }
577 return bHaveHLTData;
578}
579
9c7b5023 580AliRawReader* AliRawReaderHLTCreateInstance(AliRawReader* pParentReader, const char* options)
581{
582 // see header file for class documentation
e3917543 583 if (!pParentReader) return NULL;
9c7b5023 584 return new AliRawReaderHLT(pParentReader, options);
585}