3 /**************************************************************************
4 * This file is property of and copyright by the ALICE HLT Project *
5 * ALICE Experiment at CERN, All rights reserved. *
7 * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 * for The ALICE HLT Project. *
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 **************************************************************************/
19 /// @file AliRawReaderHLT.cxx
20 /// @author Matthias Richter
22 /// @brief AliRawReader implementation which replaces original input of
23 /// detectors with the appropriate HLT output.
25 #include "AliRawReaderHLT.h"
26 #include "AliHLTOUTRawReader.h"
27 #include "AliHLTModuleAgent.h"
28 #include "AliHLTOUTHandler.h"
29 #include "AliHLTOUTHandlerEquId.h"
30 #include "AliHLTSystem.h"
31 #include "AliHLTPluginBase.h"
32 #include "AliHLTCDHWrapper.h"
34 #include "AliDAQ.h" // RAW, for detector names and equipment ids
35 #include "TObjString.h"
38 /** ROOT macro for the implementation of ROOT specific class methods */
39 ClassImp(AliRawReaderHLT)
41 AliRawReaderHLT::AliRawReaderHLT(AliRawReader* pRawreader, const char* options)
44 fpParentReader(pRawreader),
57 fpPluginBase(new AliHLTPluginBase)
59 // see header file for class documentation
61 // refer to README to build package
63 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
68 AliRawReaderHLT::~AliRawReaderHLT()
70 // see header file for class documentation
72 if (fpPluginBase) delete fpPluginBase;
76 UInt_t AliRawReaderHLT::GetType() const
78 // see header file for class documentation
79 return fpParentReader->GetType();
82 UInt_t AliRawReaderHLT::GetRunNumber() const
84 // see header file for class documentation
85 return fpParentReader->GetRunNumber();
88 const UInt_t* AliRawReaderHLT::GetEventId() const
90 // see header file for class documentation
91 return fpParentReader->GetEventId();
94 const UInt_t* AliRawReaderHLT::GetTriggerPattern() const
96 // see header file for class documentation
97 return fpParentReader->GetTriggerPattern();
100 const UInt_t* AliRawReaderHLT::GetDetectorPattern() const
102 // see header file for class documentation
103 return fpParentReader->GetDetectorPattern();
106 const UInt_t* AliRawReaderHLT::GetAttributes() const
108 // see header file for class documentation
109 return fpParentReader->GetAttributes();
112 const UInt_t* AliRawReaderHLT::GetSubEventAttributes() const
114 // see header file for class documentation
115 return fpParentReader->GetSubEventAttributes();
118 UInt_t AliRawReaderHLT::GetLDCId() const
120 // see header file for class documentation
121 return fpParentReader->GetLDCId();
124 UInt_t AliRawReaderHLT::GetGDCId() const
126 // see header file for class documentation
127 return fpParentReader->GetGDCId();
130 UInt_t AliRawReaderHLT::GetTimestamp() const
132 // see header file for class documentation
133 return fpParentReader->GetTimestamp();
136 const UInt_t* AliRawReaderHLT::GetEquipmentAttributes() const
138 // see header file for class documentation
139 return fpParentReader->GetEquipmentAttributes();
142 Int_t AliRawReaderHLT::GetEquipmentElementSize() const
144 // don't know what it really means, bu the AliRawReaderFile
146 // do the same if we have a valid equipment data set from
148 if (fEquipmentId>=0) return 0;
149 return fpParentReader->GetEquipmentElementSize();
152 Int_t AliRawReaderHLT::GetEquipmentHeaderSize() const
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;
158 return fpParentReader->GetEquipmentHeaderSize();
161 Int_t AliRawReaderHLT::GetEquipmentSize() const
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
167 if (fEquipmentId>=0) return fDataSize + (fbHaveHLTData?0:GetEquipmentHeaderSize());
168 return fpParentReader->GetEquipmentSize();
171 Int_t AliRawReaderHLT::GetEquipmentType() const
173 // see header file for class documentation
174 return fpParentReader->GetEquipmentType();
177 Int_t AliRawReaderHLT::GetEquipmentId() const
179 // id of current equipment
181 if (fEquipmentId>=0) id=fEquipmentId;
182 else id=fpParentReader->GetEquipmentId();
186 Bool_t AliRawReaderHLT::ReadHeader()
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
191 Bool_t result=kFALSE;
192 Bool_t firstParentCycle=fbHaveHLTData;
193 while ((fbHaveHLTData=(fbHaveHLTData && ReadNextHLTData()))) {
194 // all internal data variables set
195 assert(fpData!=NULL);
196 AliHLTCDHWrapper cdh((void*)fpData);
197 if(cdh.GetVersion()==2){
198 fHeader=reinterpret_cast<AliRawDataHeader*>(const_cast<AliHLTUInt8_t*>(fpData));
202 fHeaderV3=reinterpret_cast<AliRawDataHeaderV3*>(const_cast<AliHLTUInt8_t*>(fpData));
204 fOffset=cdh.GetHeaderSize();
206 if ((result=IsSelected())) break;
208 firstParentCycle&=!fbHaveHLTData; // true if it just changed from true to false
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);
217 if (!(result=fpParentReader->ReadHeader())) {
222 fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader());
223 fHeaderV3=const_cast<AliRawDataHeaderV3*>(fpParentReader->GetDataHeaderV3());
224 fDataSize=fpParentReader->GetDataSize();
228 // filter out all equipment ids which should be taken from the HLT stream
229 int id=fpParentReader->GetEquipmentId();
230 if ((result=!IsHLTInput(id))) break;
235 Bool_t AliRawReaderHLT::ReadNextData(UChar_t*& data)
237 // read data from equipment, return pointer to data, GetDataSize
238 // provides the data size
239 return ReadNextData(data, kTRUE);
242 Bool_t AliRawReaderHLT::ReadNextData(UChar_t*& data, Bool_t readHeader)
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.
249 // read new header if data already read
250 if (fPosition<fDataSize || (result=(readHeader && ReadHeader()))) {
251 if (fbHaveHLTData && fpHLTOUT!=NULL) {
252 // all internal data variables set
254 AliHLTCDHWrapper cdh((void*) fpData);
255 data=const_cast<AliHLTUInt8_t*>(fpData+cdh.GetHeaderSize());
256 // fpData includes the CDH, set offset behind CDH
257 fOffset=cdh.GetHeaderSize();
259 // no data in the HLT stream, read real data
260 //AliInfo(Form("read from parent reader: min=%d max=%d", fSelectMinEquipmentId, fSelectMaxEquipmentId));
263 result=fpParentReader->ReadNextData(data);
266 fDataSize=fpParentReader->GetDataSize();
267 // fpData is without CDH
281 Bool_t AliRawReaderHLT::ReadNextInt(UInt_t& data)
283 // see header file for class documentation
284 int iCopy=sizeof(UInt_t);
287 if (fpData && (fDataSize-fOffset)>=iCopy) {
288 data=*reinterpret_cast<const UInt_t*>(fpData+fOffset);
292 } while (ReadNextData(dummy, kTRUE));
296 Bool_t AliRawReaderHLT::ReadNextShort(UShort_t& data)
298 // see header file for class documentation
299 int iCopy=sizeof(UShort_t);
302 if (fpData && (fDataSize-fOffset)>=iCopy) {
303 data=*reinterpret_cast<const UShort_t*>(fpData+fOffset);
307 } while (ReadNextData(dummy, kTRUE));
311 Bool_t AliRawReaderHLT::ReadNextChar(UChar_t& data)
313 // see header file for class documentation
314 int iCopy=sizeof(UChar_t);
317 if (fpData && (fDataSize-fOffset)>=iCopy) {
318 data=*reinterpret_cast<const UChar_t*>(fpData+fOffset);
322 } while (ReadNextData(dummy, kTRUE));
326 Bool_t AliRawReaderHLT::ReadNext(UChar_t* data, Int_t size)
328 // see header file for class documentation
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);
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));
346 Bool_t AliRawReaderHLT::Reset()
348 // see header file for class documentation
349 ReleaseHLTData(false/* keep HLTOUT instance */);
350 Bool_t result=fpParentReader->Reset();
353 // check if redirection is enabled for at least one detector in the selected range
354 fbHaveHLTData=EvaluateSelection();
356 // start reading HLTOUT data blocks from the beginning
362 Bool_t AliRawReaderHLT::NextEvent()
364 // see header file for class documentation
368 Bool_t result=fpParentReader->NextEvent();
376 Bool_t AliRawReaderHLT::RewindEvents()
378 // see header file for class documentation
381 return fpParentReader->RewindEvents();
384 void AliRawReaderHLT::Select(Int_t detectorID, Int_t minDDLID, Int_t maxDDLID)
386 // see header file for class documentation
387 AliRawReader::Select(detectorID, minDDLID, maxDDLID);
388 fpParentReader->Select(detectorID, minDDLID, maxDDLID);
389 fbHaveHLTData=EvaluateSelection();
392 // most likely we do not need this method since the base class directly forwards
394 // void AliRawReaderHLT::Select(const char *detectorName, Int_t minDDLID, Int_t maxDDLID)
396 // AliInfo(Form("detectorName=%s, minDDLID=%d, maxDDLID=%d", detectorName, minDDLID, maxDDLID));
397 // AliRawReader::Select(detectorName, minDDLID, maxDDLID);
398 // fpParentReader->Select(detectorName, minDDLID, maxDDLID);
401 void AliRawReaderHLT::SelectEquipment(Int_t equipmentType, Int_t minEquipmentId, Int_t maxEquipmentId)
403 // see header file for class documentation
405 //AliInfo(Form("equipmentType=%d, minEquipmentId=%d, maxEquipmentId=%d", equipmentType, minEquipmentId, maxEquipmentId));
406 AliRawReader::SelectEquipment(equipmentType, minEquipmentId, maxEquipmentId);
407 fpParentReader->SelectEquipment(equipmentType, minEquipmentId, maxEquipmentId);
408 fbHaveHLTData=EvaluateSelection();
411 void AliRawReaderHLT::SkipInvalid(Bool_t skip)
413 // see header file for class documentation
415 AliRawReader::SkipInvalid(skip);
416 fpParentReader->SkipInvalid(skip);
420 void AliRawReaderHLT::SelectEvents(Int_t type)
422 // see header file for class documentation
424 //AliInfo(Form("type=%d", type));
425 AliRawReader::SelectEvents(type);
426 fpParentReader->SelectEvents(type);
430 int AliRawReaderHLT::ScanOptions(const char* options)
432 // see header file for class documentation
434 TString optString(options);
438 TObjArray* pTokens=optString.Tokenize(" ");
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
446 // it must be a detector name
447 int detId=AliDAQ::DetectorID(argument.Data());
449 fDetectors.push_back(detId);
450 if (!detectors.IsNull()) detectors+=" ";
453 if (!fSystemOptions.IsNull()) fSystemOptions+=" ";
454 fSystemOptions+=argument;
460 if (iResult>=0 && !detectors.IsNull()) {
461 AliInfo(Form("running reconstruction from HLT data: %s", detectors.Data()));
466 Bool_t AliRawReaderHLT::ReadNextHLTData()
468 // see header file for class documentation
470 if (fbReadFirst || !fpHLTOUT) {
472 fpHLTOUT=new AliHLTOUTRawReader(fpParentReader);
473 if ((result=(fpHLTOUT!=NULL))) {
475 AliFatal("internal data error: can not get AliHLTSystem instance from plugin");
478 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
480 pSystem->ScanOptions(fSystemOptions.Data());
482 if ((result=(fpHLTOUT->Init())>=0)) {
487 result=fpHLTOUT->SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec,
488 AliHLTModuleAgent::kRawReader)>=0;
492 // first release the data buffer
493 ReleaseHLTData(false /* keep HLTOUT instance */);
494 result=fpHLTOUT->SelectNextDataBlock()>=0;
497 AliHLTComponentDataType dt=kAliHLTVoidDataType;
498 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
499 fpHLTOUT->GetDataBlockDescription(dt, spec);
500 AliHLTUInt32_t size=0;
501 AliHLTOUTHandler* pHandler=fpHLTOUT->GetHandler();
503 if (dynamic_cast<AliHLTOUTHandlerEquId*>(pHandler)!=NULL) {
504 AliHLTOUT::AliHLTOUTSelectionGuard g(fpHLTOUT);
505 fEquipmentId=pHandler->ProcessData(fpHLTOUT);
507 fDataSize=pHandler->GetProcessedData(fpData);
509 result=fpHLTOUT->GetDataBuffer(fpData, size)>=0;
511 AliDebug(AliLog::kDebug, Form("forward data block from HLTOUT stream to equipment %d", fEquipmentId));
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));
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));
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));
528 ReleaseHLTData(false /* keep HLTOUT instance */);
533 Bool_t AliRawReaderHLT::IsHLTInput(int ddlid)
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)
546 int AliRawReaderHLT::ReleaseHLTData(bool bReleaseHLTOUT)
548 // see header file for class documentation
550 if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize);
551 else fpHLTOUT->ReleaseDataBuffer(fpData);
553 if (bReleaseHLTOUT) {
568 Bool_t AliRawReaderHLT::EvaluateSelection()
570 // see header file for class documentation
571 Bool_t bHaveHLTData=kFALSE;
572 if ((bHaveHLTData=(fDetectors.size())>0)) {
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))
581 bHaveHLTData=detector!=fDetectors.end();
586 AliRawReader* AliRawReaderHLTCreateInstance(AliRawReader* pParentReader, const char* options)
588 // see header file for class documentation
589 if (!pParentReader) return NULL;
590 return new AliRawReaderHLT(pParentReader, options);