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