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 // see header file for class documentation
27 // refer to README to build package
29 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
31 #include "AliRawReaderHLT.h"
32 #include "AliHLTOUTRawReader.h"
33 #include "AliHLTModuleAgent.h"
34 #include "AliHLTOUTHandler.h"
35 #include "AliHLTOUTHandlerEquId.h"
36 #include "AliHLTSystem.h"
38 #include "AliDAQ.h" // RAW, for detector names and equipment ids
39 #include "TObjString.h"
42 /** ROOT macro for the implementation of ROOT specific class methods */
43 ClassImp(AliRawReaderHLT)
45 AliRawReaderHLT::AliRawReaderHLT(AliRawReader* pRawreader, const char* options)
49 fpParentReader(pRawreader),
63 // see header file for class documentation
65 // refer to README to build package
67 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
72 AliRawReaderHLT::~AliRawReaderHLT()
74 // see header file for class documentation
78 UInt_t AliRawReaderHLT::GetType() const
80 // see header file for class documentation
81 return fpParentReader->GetType();
84 UInt_t AliRawReaderHLT::GetRunNumber() const
86 // see header file for class documentation
87 return fpParentReader->GetRunNumber();
90 const UInt_t* AliRawReaderHLT::GetEventId() const
92 // see header file for class documentation
93 return fpParentReader->GetEventId();
96 const UInt_t* AliRawReaderHLT::GetTriggerPattern() const
98 // see header file for class documentation
99 return fpParentReader->GetTriggerPattern();
102 const UInt_t* AliRawReaderHLT::GetDetectorPattern() const
104 // see header file for class documentation
105 return fpParentReader->GetDetectorPattern();
108 const UInt_t* AliRawReaderHLT::GetAttributes() const
110 // see header file for class documentation
111 return fpParentReader->GetAttributes();
114 const UInt_t* AliRawReaderHLT::GetSubEventAttributes() const
116 // see header file for class documentation
117 return fpParentReader->GetSubEventAttributes();
120 UInt_t AliRawReaderHLT::GetLDCId() const
122 // see header file for class documentation
123 return fpParentReader->GetLDCId();
126 UInt_t AliRawReaderHLT::GetGDCId() const
128 // see header file for class documentation
129 return fpParentReader->GetGDCId();
132 UInt_t AliRawReaderHLT::GetTimestamp() const
134 // see header file for class documentation
135 return fpParentReader->GetTimestamp();
138 const UInt_t* AliRawReaderHLT::GetEquipmentAttributes() const
140 // see header file for class documentation
141 return fpParentReader->GetEquipmentAttributes();
144 Int_t AliRawReaderHLT::GetEquipmentElementSize() const
146 // see header file for class documentation
147 // don't know what it really means, bu the AliRawReaderFile
149 // do the same if we have a valid equipment data set from
151 if (fEquipmentId>=0) return 0;
152 return fpParentReader->GetEquipmentElementSize();
155 Int_t AliRawReaderHLT::GetEquipmentHeaderSize() const
157 // see header file for class documentation
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;
163 return fpParentReader->GetEquipmentHeaderSize();
166 Int_t AliRawReaderHLT::GetEquipmentSize() const
168 // see header file for class documentation
169 if (fEquipmentId>=0) return fDataSize+sizeof(AliRawDataHeader);
170 return fpParentReader->GetEquipmentSize();
173 Int_t AliRawReaderHLT::GetEquipmentType() const
175 // see header file for class documentation
176 return fpParentReader->GetEquipmentType();
179 Int_t AliRawReaderHLT::GetEquipmentId() const
181 // see header file for class documentation
183 if (fEquipmentId>=0) id=fEquipmentId;
184 else id=fpParentReader->GetEquipmentId();
188 Bool_t AliRawReaderHLT::ReadHeader()
190 // see header file for class documentation
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 fHeader=reinterpret_cast<AliRawDataHeader*>(const_cast<AliHLTUInt8_t*>(fpData));
197 fOffset=sizeof(AliRawDataHeader);
199 if ((result=IsSelected())) break;
201 firstParentCycle&=!fbHaveHLTData; // true if it just changed from true to false
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);
210 if (!(result=fpParentReader->ReadHeader())) {
214 fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader());
215 fDataSize=fpParentReader->GetDataSize();
219 // filter out all equipment ids which should be taken from the HLT stream
220 int id=fpParentReader->GetEquipmentId();
221 if ((result=!IsHLTInput(id))) break;
226 Bool_t AliRawReaderHLT::ReadNextData(UChar_t*& data)
228 // see header file for class documentation
229 return ReadNextData(data, kTRUE);
232 Bool_t AliRawReaderHLT::ReadNextData(UChar_t*& data, Bool_t readHeader)
234 // see header file for class documentation
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.
241 // read new header if data already read
242 if (fPosition<fDataSize || (result=(readHeader && ReadHeader()))) {
243 if (fbHaveHLTData && fpHLTOUT!=NULL) {
244 // all internal data variables set
246 data=const_cast<AliHLTUInt8_t*>(fpData+sizeof(AliRawDataHeader));
247 // fpData includes the CDH, set offset behind CDH
248 fOffset=sizeof(AliRawDataHeader);
250 // no data in the HLT stream, read real data
251 //AliInfo(Form("read from parent reader: min=%d max=%d", fSelectMinEquipmentId, fSelectMaxEquipmentId));
254 result=fpParentReader->ReadNextData(data);
257 fDataSize=fpParentReader->GetDataSize();
258 // fpData is without CDH
272 Bool_t AliRawReaderHLT::ReadNextInt(UInt_t& data)
274 // see header file for class documentation
275 int iCopy=sizeof(UInt_t);
278 if (fpData && (fDataSize-fOffset)>=iCopy) {
279 data=*reinterpret_cast<const UInt_t*>(fpData+fOffset);
283 } while (ReadNextData(dummy, kTRUE));
287 Bool_t AliRawReaderHLT::ReadNextShort(UShort_t& data)
289 // see header file for class documentation
290 int iCopy=sizeof(UShort_t);
293 if (fpData && (fDataSize-fOffset)>=iCopy) {
294 data=*reinterpret_cast<const UShort_t*>(fpData+fOffset);
298 } while (ReadNextData(dummy, kTRUE));
302 Bool_t AliRawReaderHLT::ReadNextChar(UChar_t& data)
304 // see header file for class documentation
305 int iCopy=sizeof(UChar_t);
308 if (fpData && (fDataSize-fOffset)>=iCopy) {
309 data=*reinterpret_cast<const UChar_t*>(fpData+fOffset);
313 } while (ReadNextData(dummy, kTRUE));
317 Bool_t AliRawReaderHLT::ReadNext(UChar_t* data, Int_t size)
319 // see header file for class documentation
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);
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));
337 Bool_t AliRawReaderHLT::Reset()
339 // see header file for class documentation
340 ReleaseHLTData(false/* keep HLTOUT instance */);
341 Bool_t result=fpParentReader->Reset();
344 // check if redirection is enabled for at least one detector in the selected range
345 fbHaveHLTData=EvaluateSelection();
347 // start reading HLTOUT data blocks from the beginning
353 Bool_t AliRawReaderHLT::NextEvent()
355 // see header file for class documentation
359 Bool_t result=fpParentReader->NextEvent();
367 Bool_t AliRawReaderHLT::RewindEvents()
369 // see header file for class documentation
372 return fpParentReader->RewindEvents();
375 void AliRawReaderHLT::Select(Int_t detectorID, Int_t minDDLID, Int_t maxDDLID)
377 // see header file for class documentation
378 AliRawReader::Select(detectorID, minDDLID, maxDDLID);
379 fpParentReader->Select(detectorID, minDDLID, maxDDLID);
380 fbHaveHLTData=EvaluateSelection();
383 // most likely we do not need this method since the base class directly forwards
385 // void AliRawReaderHLT::Select(const char *detectorName, Int_t minDDLID, Int_t maxDDLID)
387 // AliInfo(Form("detectorName=%s, minDDLID=%d, maxDDLID=%d", detectorName, minDDLID, maxDDLID));
388 // AliRawReader::Select(detectorName, minDDLID, maxDDLID);
389 // fpParentReader->Select(detectorName, minDDLID, maxDDLID);
392 void AliRawReaderHLT::SelectEquipment(Int_t equipmentType, Int_t minEquipmentId, Int_t maxEquipmentId)
394 // see header file for class documentation
396 //AliInfo(Form("equipmentType=%d, minEquipmentId=%d, maxEquipmentId=%d", equipmentType, minEquipmentId, maxEquipmentId));
397 AliRawReader::SelectEquipment(equipmentType, minEquipmentId, maxEquipmentId);
398 fpParentReader->SelectEquipment(equipmentType, minEquipmentId, maxEquipmentId);
399 fbHaveHLTData=EvaluateSelection();
402 void AliRawReaderHLT::SkipInvalid(Bool_t skip)
404 // see header file for class documentation
406 AliRawReader::SkipInvalid(skip);
407 fpParentReader->SkipInvalid(skip);
411 void AliRawReaderHLT::SelectEvents(Int_t type)
413 // see header file for class documentation
415 //AliInfo(Form("type=%d", type));
416 AliRawReader::SelectEvents(type);
417 fpParentReader->SelectEvents(type);
421 int AliRawReaderHLT::ScanOptions(const char* options)
423 // see header file for class documentation
425 TString optString(options);
429 TObjArray* pTokens=optString.Tokenize(" ");
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
437 // it must be a detector name
438 int detId=AliDAQ::DetectorID(argument.Data());
440 fDetectors.push_back(detId);
441 if (!detectors.IsNull()) detectors+=" ";
444 if (!fSystemOptions.IsNull()) fSystemOptions+=" ";
445 fSystemOptions+=argument;
451 if (iResult>=0 && !detectors.IsNull()) {
452 AliInfo(Form("running reconstruction from HLT data: %s", detectors.Data()));
457 Bool_t AliRawReaderHLT::ReadNextHLTData()
459 // see header file for class documentation
461 if (fbReadFirst || !fpHLTOUT) {
463 fpHLTOUT=new AliHLTOUTRawReader(fpParentReader);
464 if ((result=(fpHLTOUT!=NULL))) {
465 AliHLTSystem* pSystem=GetInstance();
467 pSystem->ScanOptions(fSystemOptions.Data());
469 if ((result=(fpHLTOUT->Init())>=0)) {
474 result=fpHLTOUT->SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec,
475 AliHLTModuleAgent::kRawReader)>=0;
479 // first release the data buffer
480 ReleaseHLTData(false /* keep HLTOUT instance */);
481 result=fpHLTOUT->SelectNextDataBlock()>=0;
484 AliHLTComponentDataType dt=kAliHLTVoidDataType;
485 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
486 fpHLTOUT->GetDataBlockDescription(dt, spec);
487 AliHLTUInt32_t size=0;
488 AliHLTOUTHandler* pHandler=fpHLTOUT->GetHandler();
490 if (dynamic_cast<AliHLTOUTHandlerEquId*>(pHandler)!=NULL) {
491 AliHLTOUT::AliHLTOUTSelectionGuard g(fpHLTOUT);
492 fEquipmentId=pHandler->ProcessData(fpHLTOUT);
494 fDataSize=pHandler->GetProcessedData(fpData);
496 result=fpHLTOUT->GetDataBuffer(fpData, size)>=0;
498 AliDebug(AliLog::kDebug, Form("forward data block from HLTOUT stream to equipment %d", fEquipmentId));
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));
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));
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));
515 ReleaseHLTData(false /* keep HLTOUT instance */);
520 Bool_t AliRawReaderHLT::IsHLTInput(int ddlid)
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)
533 int AliRawReaderHLT::ReleaseHLTData(bool bReleaseHLTOUT)
535 // see header file for class documentation
537 if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize);
538 else fpHLTOUT->ReleaseDataBuffer(fpData);
540 if (bReleaseHLTOUT) {
555 Bool_t AliRawReaderHLT::EvaluateSelection()
557 // see header file for class documentation
558 Bool_t bHaveHLTData=kFALSE;
559 if ((bHaveHLTData=(fDetectors.size())>0)) {
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))
568 bHaveHLTData=detector!=fDetectors.end();
573 AliRawReader* AliRawReaderHLTCreateInstance(AliRawReader* pParentReader, const char* options)
575 // see header file for class documentation
576 if (!pParentReader) return NULL;
577 return new AliRawReaderHLT(pParentReader, options);