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