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"
33 #include "AliDAQ.h" // RAW, for detector names and equipment ids
34 #include "TObjString.h"
37 /** ROOT macro for the implementation of ROOT specific class methods */
38 ClassImp(AliRawReaderHLT)
40 AliRawReaderHLT::AliRawReaderHLT(AliRawReader* pRawreader, const char* options)
43 fpParentReader(pRawreader),
56 fpPluginBase(new AliHLTPluginBase)
58 // see header file for class documentation
60 // refer to README to build package
62 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
67 AliRawReaderHLT::~AliRawReaderHLT()
69 // see header file for class documentation
71 if (fpPluginBase) delete fpPluginBase;
75 UInt_t AliRawReaderHLT::GetType() const
77 // see header file for class documentation
78 return fpParentReader->GetType();
81 UInt_t AliRawReaderHLT::GetRunNumber() const
83 // see header file for class documentation
84 return fpParentReader->GetRunNumber();
87 const UInt_t* AliRawReaderHLT::GetEventId() const
89 // see header file for class documentation
90 return fpParentReader->GetEventId();
93 const UInt_t* AliRawReaderHLT::GetTriggerPattern() const
95 // see header file for class documentation
96 return fpParentReader->GetTriggerPattern();
99 const UInt_t* AliRawReaderHLT::GetDetectorPattern() const
101 // see header file for class documentation
102 return fpParentReader->GetDetectorPattern();
105 const UInt_t* AliRawReaderHLT::GetAttributes() const
107 // see header file for class documentation
108 return fpParentReader->GetAttributes();
111 const UInt_t* AliRawReaderHLT::GetSubEventAttributes() const
113 // see header file for class documentation
114 return fpParentReader->GetSubEventAttributes();
117 UInt_t AliRawReaderHLT::GetLDCId() const
119 // see header file for class documentation
120 return fpParentReader->GetLDCId();
123 UInt_t AliRawReaderHLT::GetGDCId() const
125 // see header file for class documentation
126 return fpParentReader->GetGDCId();
129 UInt_t AliRawReaderHLT::GetTimestamp() const
131 // see header file for class documentation
132 return fpParentReader->GetTimestamp();
135 const UInt_t* AliRawReaderHLT::GetEquipmentAttributes() const
137 // see header file for class documentation
138 return fpParentReader->GetEquipmentAttributes();
141 Int_t AliRawReaderHLT::GetEquipmentElementSize() const
143 // don't know what it really means, bu the AliRawReaderFile
145 // do the same if we have a valid equipment data set from
147 if (fEquipmentId>=0) return 0;
148 return fpParentReader->GetEquipmentElementSize();
151 Int_t AliRawReaderHLT::GetEquipmentHeaderSize() const
153 // equipment header means the additional data header?
154 // if we have a valid equipment data set from the HLT stream
155 // there is no additional header
156 if (fEquipmentId>=0) return 0;
157 return fpParentReader->GetEquipmentHeaderSize();
160 Int_t AliRawReaderHLT::GetEquipmentSize() const
162 // return the equipment size, that's including the CDH
163 // fDataSize has been set to the full size of the block if it is from HLTOUT
164 // if the data block is from the parent rawreader it is only the pointer
165 // to the payload and the size of the CDH must be added
166 if (fEquipmentId>=0) return fDataSize + (fbHaveHLTData?0:sizeof(AliRawDataHeader));
167 return fpParentReader->GetEquipmentSize();
170 Int_t AliRawReaderHLT::GetEquipmentType() const
172 // see header file for class documentation
173 return fpParentReader->GetEquipmentType();
176 Int_t AliRawReaderHLT::GetEquipmentId() const
178 // id of current equipment
180 if (fEquipmentId>=0) id=fEquipmentId;
181 else id=fpParentReader->GetEquipmentId();
185 Bool_t AliRawReaderHLT::ReadHeader()
187 // read the header of the next equipment
188 // depending on whether there is data redirected from HLT for the current event
189 // first the data in the HLTOUT is tried
190 Bool_t result=kFALSE;
191 Bool_t firstParentCycle=fbHaveHLTData;
192 while ((fbHaveHLTData=(fbHaveHLTData && ReadNextHLTData()))) {
193 // all internal data variables set
194 assert(fpData!=NULL);
195 fHeader=reinterpret_cast<AliRawDataHeader*>(const_cast<AliHLTUInt8_t*>(fpData));
196 fOffset=sizeof(AliRawDataHeader);
198 if ((result=IsSelected())) break;
200 firstParentCycle&=!fbHaveHLTData; // true if it just changed from true to false
202 if (firstParentCycle) {
203 firstParentCycle=kFALSE;
204 // reset and set the selection back to the original one
205 fpParentReader->Reset();
206 fpParentReader->SelectEquipment(fSelectEquipmentType, fSelectMinEquipmentId, fSelectMaxEquipmentId);
209 if (!(result=fpParentReader->ReadHeader())) {
213 fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader());
214 fDataSize=fpParentReader->GetDataSize();
218 // filter out all equipment ids which should be taken from the HLT stream
219 int id=fpParentReader->GetEquipmentId();
220 if ((result=!IsHLTInput(id))) break;
225 Bool_t AliRawReaderHLT::ReadNextData(UChar_t*& data)
227 // read data from equipment, return pointer to data, GetDataSize
228 // provides the data size
229 return ReadNextData(data, kTRUE);
232 Bool_t AliRawReaderHLT::ReadNextData(UChar_t*& data, Bool_t readHeader)
234 // this function is the backbone of the ReadNext functions, it gets the
235 // whole data block either from the HLT stream or the parent raw reader.
236 // Each call of ReadNextData directly jumps to the next data set.
239 // read new header if data already read
240 if (fPosition<fDataSize || (result=(readHeader && ReadHeader()))) {
241 if (fbHaveHLTData && fpHLTOUT!=NULL) {
242 // all internal data variables set
244 data=const_cast<AliHLTUInt8_t*>(fpData+sizeof(AliRawDataHeader));
245 // fpData includes the CDH, set offset behind CDH
246 fOffset=sizeof(AliRawDataHeader);
248 // no data in the HLT stream, read real data
249 //AliInfo(Form("read from parent reader: min=%d max=%d", fSelectMinEquipmentId, fSelectMaxEquipmentId));
252 result=fpParentReader->ReadNextData(data);
255 fDataSize=fpParentReader->GetDataSize();
256 // fpData is without CDH
270 Bool_t AliRawReaderHLT::ReadNextInt(UInt_t& data)
272 // see header file for class documentation
273 int iCopy=sizeof(UInt_t);
276 if (fpData && (fDataSize-fOffset)>=iCopy) {
277 data=*reinterpret_cast<const UInt_t*>(fpData+fOffset);
281 } while (ReadNextData(dummy, kTRUE));
285 Bool_t AliRawReaderHLT::ReadNextShort(UShort_t& data)
287 // see header file for class documentation
288 int iCopy=sizeof(UShort_t);
291 if (fpData && (fDataSize-fOffset)>=iCopy) {
292 data=*reinterpret_cast<const UShort_t*>(fpData+fOffset);
296 } while (ReadNextData(dummy, kTRUE));
300 Bool_t AliRawReaderHLT::ReadNextChar(UChar_t& data)
302 // see header file for class documentation
303 int iCopy=sizeof(UChar_t);
306 if (fpData && (fDataSize-fOffset)>=iCopy) {
307 data=*reinterpret_cast<const UChar_t*>(fpData+fOffset);
311 } while (ReadNextData(dummy, kTRUE));
315 Bool_t AliRawReaderHLT::ReadNext(UChar_t* data, Int_t size)
317 // see header file for class documentation
320 if (fpData && (fDataSize-fOffset)>=size) {
321 // copy remaining data
322 int iCopy=fDataSize-fOffset;
323 if (iCopy>size) iCopy=size;
324 memcpy(data, fpData+fOffset, iCopy);
328 // By convention, the ReadNextData function stays in the
329 // current block and does not switch to the next one
330 // automatically -> kFALSE
331 } while (ReadNextData(dummy, kFALSE));
335 Bool_t AliRawReaderHLT::Reset()
337 // see header file for class documentation
338 ReleaseHLTData(false/* keep HLTOUT instance */);
339 Bool_t result=fpParentReader->Reset();
342 // check if redirection is enabled for at least one detector in the selected range
343 fbHaveHLTData=EvaluateSelection();
345 // start reading HLTOUT data blocks from the beginning
351 Bool_t AliRawReaderHLT::NextEvent()
353 // see header file for class documentation
357 Bool_t result=fpParentReader->NextEvent();
365 Bool_t AliRawReaderHLT::RewindEvents()
367 // see header file for class documentation
370 return fpParentReader->RewindEvents();
373 void AliRawReaderHLT::Select(Int_t detectorID, Int_t minDDLID, Int_t maxDDLID)
375 // see header file for class documentation
376 AliRawReader::Select(detectorID, minDDLID, maxDDLID);
377 fpParentReader->Select(detectorID, minDDLID, maxDDLID);
378 fbHaveHLTData=EvaluateSelection();
381 // most likely we do not need this method since the base class directly forwards
383 // void AliRawReaderHLT::Select(const char *detectorName, Int_t minDDLID, Int_t maxDDLID)
385 // AliInfo(Form("detectorName=%s, minDDLID=%d, maxDDLID=%d", detectorName, minDDLID, maxDDLID));
386 // AliRawReader::Select(detectorName, minDDLID, maxDDLID);
387 // fpParentReader->Select(detectorName, minDDLID, maxDDLID);
390 void AliRawReaderHLT::SelectEquipment(Int_t equipmentType, Int_t minEquipmentId, Int_t maxEquipmentId)
392 // see header file for class documentation
394 //AliInfo(Form("equipmentType=%d, minEquipmentId=%d, maxEquipmentId=%d", equipmentType, minEquipmentId, maxEquipmentId));
395 AliRawReader::SelectEquipment(equipmentType, minEquipmentId, maxEquipmentId);
396 fpParentReader->SelectEquipment(equipmentType, minEquipmentId, maxEquipmentId);
397 fbHaveHLTData=EvaluateSelection();
400 void AliRawReaderHLT::SkipInvalid(Bool_t skip)
402 // see header file for class documentation
404 AliRawReader::SkipInvalid(skip);
405 fpParentReader->SkipInvalid(skip);
409 void AliRawReaderHLT::SelectEvents(Int_t type)
411 // see header file for class documentation
413 //AliInfo(Form("type=%d", type));
414 AliRawReader::SelectEvents(type);
415 fpParentReader->SelectEvents(type);
419 int AliRawReaderHLT::ScanOptions(const char* options)
421 // see header file for class documentation
423 TString optString(options);
427 TObjArray* pTokens=optString.Tokenize(" ");
429 int iEntries=pTokens->GetEntries();
430 for (int i =0; i<iEntries; i++) {
431 argument=((TObjString*)pTokens->At(i))->GetString();
432 // first scan all the other options
433 // no other options for the moment
435 // it must be a detector name
436 int detId=AliDAQ::DetectorID(argument.Data());
438 fDetectors.push_back(detId);
439 if (!detectors.IsNull()) detectors+=" ";
442 if (!fSystemOptions.IsNull()) fSystemOptions+=" ";
443 fSystemOptions+=argument;
449 if (iResult>=0 && !detectors.IsNull()) {
450 AliInfo(Form("running reconstruction from HLT data: %s", detectors.Data()));
455 Bool_t AliRawReaderHLT::ReadNextHLTData()
457 // see header file for class documentation
459 if (fbReadFirst || !fpHLTOUT) {
461 fpHLTOUT=new AliHLTOUTRawReader(fpParentReader);
462 if ((result=(fpHLTOUT!=NULL))) {
464 AliFatal("internal data error: can not get AliHLTSystem instance from plugin");
467 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
469 pSystem->ScanOptions(fSystemOptions.Data());
471 if ((result=(fpHLTOUT->Init())>=0)) {
476 result=fpHLTOUT->SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec,
477 AliHLTModuleAgent::kRawReader)>=0;
481 // first release the data buffer
482 ReleaseHLTData(false /* keep HLTOUT instance */);
483 result=fpHLTOUT->SelectNextDataBlock()>=0;
486 AliHLTComponentDataType dt=kAliHLTVoidDataType;
487 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
488 fpHLTOUT->GetDataBlockDescription(dt, spec);
489 AliHLTUInt32_t size=0;
490 AliHLTOUTHandler* pHandler=fpHLTOUT->GetHandler();
492 if (dynamic_cast<AliHLTOUTHandlerEquId*>(pHandler)!=NULL) {
493 AliHLTOUT::AliHLTOUTSelectionGuard g(fpHLTOUT);
494 fEquipmentId=pHandler->ProcessData(fpHLTOUT);
496 fDataSize=pHandler->GetProcessedData(fpData);
498 result=fpHLTOUT->GetDataBuffer(fpData, size)>=0;
500 AliDebug(AliLog::kDebug, Form("forward data block from HLTOUT stream to equipment %d", fEquipmentId));
503 // remember the current handler in order to properly release the data buffer
504 fpDataHandler=pHandler;
505 AliDebug(AliLog::kDebug, Form("forward decoded data block provided by handler to equipment %d", fEquipmentId));
509 AliError(Form("handler is not of type AliHLTOUTHandlerEquId for block %x data type %s spec %#x; data block skipped",
510 fpHLTOUT->GetDataBlockIndex(), AliHLTComponent::DataType2Text(dt).c_str(), spec));
513 AliWarning(Form("no data handler found for block %x data type %s spec %#x; data block skipped",
514 fpHLTOUT->GetDataBlockIndex(), AliHLTComponent::DataType2Text(dt).c_str(), spec));
517 ReleaseHLTData(false /* keep HLTOUT instance */);
522 Bool_t AliRawReaderHLT::IsHLTInput(int ddlid)
524 // see header file for class documentation
525 vector<int>::iterator detector=fDetectors.begin();
526 for (; detector!=fDetectors.end(); detector++) {
527 int ddlOffset=AliDAQ::DdlIDOffset(*detector);
528 int nofDDLs=AliDAQ::NumberOfDdls(*detector);
529 if (ddlid>=ddlOffset && ddlid<ddlOffset+nofDDLs)
535 int AliRawReaderHLT::ReleaseHLTData(bool bReleaseHLTOUT)
537 // see header file for class documentation
539 if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize);
540 else fpHLTOUT->ReleaseDataBuffer(fpData);
542 if (bReleaseHLTOUT) {
557 Bool_t AliRawReaderHLT::EvaluateSelection()
559 // see header file for class documentation
560 Bool_t bHaveHLTData=kFALSE;
561 if ((bHaveHLTData=(fDetectors.size())>0)) {
562 vector<int>::iterator detector=fDetectors.begin();
563 for (; detector!=fDetectors.end(); detector++) {
564 int ddlOffset=AliDAQ::DdlIDOffset(*detector);
565 int nofDDLs=AliDAQ::NumberOfDdls(*detector);
566 if ((fSelectMinEquipmentId<0 || fSelectMinEquipmentId<ddlOffset+nofDDLs) &&
567 (fSelectMaxEquipmentId<0 || fSelectMaxEquipmentId>=ddlOffset))
570 bHaveHLTData=detector!=fDetectors.end();
575 AliRawReader* AliRawReaderHLTCreateInstance(AliRawReader* pParentReader, const char* options)
577 // see header file for class documentation
578 if (!pParentReader) return NULL;
579 return new AliRawReaderHLT(pParentReader, options);