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)
48 AliHLTReconstructorBase(),
49 fpParentReader(pRawreader),
61 // see header file for class documentation
63 // refer to README to build package
65 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
70 AliRawReaderHLT::~AliRawReaderHLT()
72 // see header file for class documentation
74 if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize);
75 else fpHLTOUT->ReleaseDataBuffer(fpData);
82 UInt_t AliRawReaderHLT::GetType() const
84 // see header file for class documentation
85 return fpParentReader->GetType();
88 UInt_t AliRawReaderHLT::GetRunNumber() const
90 // see header file for class documentation
91 return fpParentReader->GetRunNumber();
94 const UInt_t* AliRawReaderHLT::GetEventId() const
96 // see header file for class documentation
97 return fpParentReader->GetEventId();
100 const UInt_t* AliRawReaderHLT::GetTriggerPattern() const
102 // see header file for class documentation
103 return fpParentReader->GetTriggerPattern();
106 const UInt_t* AliRawReaderHLT::GetDetectorPattern() const
108 // see header file for class documentation
109 return fpParentReader->GetDetectorPattern();
112 const UInt_t* AliRawReaderHLT::GetAttributes() const
114 // see header file for class documentation
115 return fpParentReader->GetAttributes();
118 const UInt_t* AliRawReaderHLT::GetSubEventAttributes() const
120 // see header file for class documentation
121 return fpParentReader->GetSubEventAttributes();
124 UInt_t AliRawReaderHLT::GetLDCId() const
126 // see header file for class documentation
127 return fpParentReader->GetLDCId();
130 UInt_t AliRawReaderHLT::GetGDCId() const
132 // see header file for class documentation
133 return fpParentReader->GetGDCId();
136 UInt_t AliRawReaderHLT::GetTimestamp() const
138 // see header file for class documentation
139 return fpParentReader->GetTimestamp();
142 const UInt_t* AliRawReaderHLT::GetEquipmentAttributes() const
144 // see header file for class documentation
145 return fpParentReader->GetEquipmentAttributes();
148 Int_t AliRawReaderHLT::GetEquipmentElementSize() const
150 // see header file for class documentation
151 // don't know what it really means, bu the AliRawReaderFile
153 // do the same if we have a valid equipment data set from
155 if (fEquipmentId>=0) return 0;
156 return fpParentReader->GetEquipmentElementSize();
159 Int_t AliRawReaderHLT::GetEquipmentHeaderSize() const
161 // see header file for class documentation
163 // equipment header means the additional data header?
164 // if we have a valid equipment data set from the HLT stream
165 // there is no additional header
166 if (fEquipmentId>=0) return 0;
167 return fpParentReader->GetEquipmentHeaderSize();
170 Int_t AliRawReaderHLT::GetEquipmentSize() const
172 // see header file for class documentation
173 if (fEquipmentId>=0) return fDataSize+sizeof(AliRawDataHeader);
174 return fpParentReader->GetEquipmentSize();
177 Int_t AliRawReaderHLT::GetEquipmentType() const
179 // see header file for class documentation
180 return fpParentReader->GetEquipmentType();
183 Int_t AliRawReaderHLT::GetEquipmentId() const
185 // see header file for class documentation
187 if (fEquipmentId>=0) id=fEquipmentId;
188 else id=fpParentReader->GetEquipmentId();
192 Bool_t AliRawReaderHLT::ReadHeader()
194 // see header file for class documentation
195 Bool_t result=kFALSE;
196 while (fbHaveHLTData&=ReadNextHLTData()) {
197 // all internal data variables set
198 assert(fpData!=NULL);
199 fHeader=reinterpret_cast<AliRawDataHeader*>(const_cast<AliHLTUInt8_t*>(fpData));
200 if (result=IsSelected()) break;
203 // first set the selection back to the original one
204 fpParentReader->SelectEquipment(fSelectEquipmentType, fSelectMinEquipmentId, fSelectMaxEquipmentId);
206 result=fpParentReader->ReadHeader();
207 fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader());
212 Bool_t AliRawReaderHLT::ReadNextData(UChar_t*& data)
214 // see header file for class documentation
216 // this function is the backbone of the ReadNext functions, it gets the
217 // whole data block either from the HLT stream or the parent raw reader.
218 // Each call of ReadNextData directly jumps to the next data set.
219 Bool_t result=kFALSE;
220 if (ReadHeader() && fpData!=NULL) {
221 // all internal data variables set
223 data=const_cast<AliHLTUInt8_t*>(fpData+sizeof(AliRawDataHeader));
225 if (kFALSE) { // this needs more thinking
226 // no data in the HLT stream, read real data
227 //AliInfo(Form("read from parent reader: min=%d max=%d", fSelectMinEquipmentId, fSelectMaxEquipmentId));
230 while (result=fpParentReader->ReadNextData(data)) {
231 // continue if the Equipment Id is supposed to be replaced by the HLT stream
232 // in that case we do not want to read it from the parent raw reader
233 if (!IsHLTInput(fpParentReader->GetEquipmentId())) break;
236 // set the header of this reader from the parent reader.
237 // This is necessary because of a few base class methods working directly
239 fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader());
242 fDataSize=fpParentReader->GetDataSize();
253 Bool_t AliRawReaderHLT::ReadNextInt(UInt_t& data)
255 // see header file for class documentation
256 int iCopy=sizeof(UInt_t);
259 if (fpData && (fDataSize-fOffset)>=iCopy) {
260 data=*reinterpret_cast<const UInt_t*>(fpData+fOffset);
264 } while (ReadNextData(dummy));
268 Bool_t AliRawReaderHLT::ReadNextShort(UShort_t& data)
270 // see header file for class documentation
271 int iCopy=sizeof(UShort_t);
274 if (fpData && (fDataSize-fOffset)>=iCopy) {
275 data=*reinterpret_cast<const UShort_t*>(fpData+fOffset);
279 } while (ReadNextData(dummy));
283 Bool_t AliRawReaderHLT::ReadNextChar(UChar_t& data)
285 // see header file for class documentation
286 int iCopy=sizeof(UChar_t);
289 if (fpData && (fDataSize-fOffset)>=iCopy) {
290 data=*reinterpret_cast<const UChar_t*>(fpData+fOffset);
294 } while (ReadNextData(dummy));
298 Bool_t AliRawReaderHLT::ReadNext(UChar_t* data, Int_t size)
300 // see header file for class documentation
303 if (fpData && (fDataSize-fOffset)>=size) {
304 // copy remaining data
305 int iCopy=fDataSize-fOffset;
306 if (iCopy>size) iCopy=size;
307 memcpy(data, fpData+fOffset, iCopy);
311 } while (ReadNextData(dummy));
315 Bool_t AliRawReaderHLT::Reset()
317 // see header file for class documentation
318 Bool_t result=fpParentReader->Reset();
323 if (fbHaveHLTData=(fDetectors.size()>0)) {
324 vector<int>::iterator detector=fDetectors.begin();
325 for (; detector!=fDetectors.end(); detector++) {
326 int ddlOffset=AliDAQ::DdlIDOffset(*detector);
327 int nofDDLs=AliDAQ::NumberOfDdls(*detector);
328 if ((fSelectMinEquipmentId>=0 && fSelectMinEquipmentId>ddlOffset+nofDDLs) ||
329 (fSelectMinEquipmentId>=0 && fSelectMaxEquipmentId<ddlOffset))
333 fbHaveHLTData=detector!=fDetectors.end();
337 if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize);
338 else fpHLTOUT->ReleaseDataBuffer(fpData);
347 Bool_t AliRawReaderHLT::NextEvent()
349 // see header file for class documentation
350 Bool_t result=fpParentReader->NextEvent();
358 Bool_t AliRawReaderHLT::RewindEvents()
360 // see header file for class documentation
363 return fpParentReader->RewindEvents();
366 void AliRawReaderHLT::Select(Int_t detectorID, Int_t minDDLID, Int_t maxDDLID)
368 // see header file for class documentation
369 AliRawReader::Select(detectorID, minDDLID, maxDDLID);
370 fpParentReader->Select(detectorID, minDDLID, maxDDLID);
373 // most likely we do not need this method since the base class directly forwards
375 // void AliRawReaderHLT::Select(const char *detectorName, Int_t minDDLID, Int_t maxDDLID)
377 // AliInfo(Form("detectorName=%s, minDDLID=%d, maxDDLID=%d", detectorName, minDDLID, maxDDLID));
378 // AliRawReader::Select(detectorName, minDDLID, maxDDLID);
379 // fpParentReader->Select(detectorName, minDDLID, maxDDLID);
382 void AliRawReaderHLT::SelectEquipment(Int_t equipmentType, Int_t minEquipmentId, Int_t maxEquipmentId)
384 // see header file for class documentation
386 //AliInfo(Form("equipmentType=%d, minEquipmentId=%d, maxEquipmentId=%d", equipmentType, minEquipmentId, maxEquipmentId));
387 AliRawReader::Select(equipmentType, minEquipmentId, maxEquipmentId);
388 fpParentReader->Select(equipmentType, minEquipmentId, maxEquipmentId);
391 void AliRawReaderHLT::SkipInvalid(Bool_t skip)
393 // see header file for class documentation
395 AliRawReader::SkipInvalid(skip);
396 fpParentReader->SkipInvalid(skip);
399 void AliRawReaderHLT::SelectEvents(Int_t type)
401 // see header file for class documentation
403 //AliInfo(Form("type=%d", type));
404 AliRawReader::SelectEvents(type);
405 fpParentReader->SelectEvents(type);
408 int AliRawReaderHLT::ScanOptions(const char* options)
410 // see header file for class documentation
412 TString optString(options);
415 TObjArray* pTokens=optString.Tokenize(" ");
417 int iEntries=pTokens->GetEntries();
418 for (int i =0; i<iEntries; i++) {
419 argument=((TObjString*)pTokens->At(i))->GetString();
420 // first scan all the other options
421 // no other options for the moment
423 // it must be a detector name
424 int detId=AliDAQ::DetectorID(argument.Data());
426 fDetectors.push_back(detId);
428 if (!fSystemOptions.IsNull()) fSystemOptions+=" ";
429 fSystemOptions+=argument;
438 Bool_t AliRawReaderHLT::ReadNextHLTData()
440 // see header file for class documentation
443 fpHLTOUT=new AliHLTOUTRawReader(fpParentReader);
444 if (result=(fpHLTOUT!=NULL)) {
445 AliHLTSystem* pSystem=GetInstance();
447 pSystem->ScanOptions(fSystemOptions.Data());
449 if (result=(fpHLTOUT->Init()>=0)) {
450 result=fpHLTOUT->SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec,
451 AliHLTModuleAgent::kRawReader)>=0;
455 // first release the data buffer
456 if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize);
457 else fpHLTOUT->ReleaseDataBuffer(fpData);
460 if (!(result=fpHLTOUT->SelectNextDataBlock()>=0)) {
466 AliHLTComponentDataType dt=kAliHLTVoidDataType;
467 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
468 fpHLTOUT->GetDataBlockDescription(dt, spec);
469 AliHLTUInt32_t size=0;
470 AliHLTOUTHandler* pHandler=fpHLTOUT->GetHandler();
472 if (dynamic_cast<AliHLTOUTHandlerEquId*>(pHandler)!=NULL) {
473 AliHLTOUT::AliHLTOUTLockGuard g(fpHLTOUT);
474 fEquipmentId=pHandler->ProcessData(fpHLTOUT);
476 fDataSize=pHandler->GetProcessedData(fpData);
478 result=fpHLTOUT->GetDataBuffer(fpData, size)>=0;
479 AliDebug(AliLog::kDebug, Form("forward data block from HLTOUT stream to equipment %d", fEquipmentId));
482 // remember the current handler in order to properly release the data buffer
483 fpDataHandler=pHandler;
484 AliDebug(AliLog::kDebug, Form("forward decoded data block provided by handler to equipment %d", fEquipmentId));
488 AliError(Form("handler is not of type AliHLTOUTHandlerEquId for block %x data type %s spec %#x; data block skipped",
489 fpHLTOUT->GetDataBlockIndex(), AliHLTComponent::DataType2Text(dt).c_str(), spec));
492 AliWarning(Form("no data handler found for block %x data type %s spec %#x; data block skipped",
493 fpHLTOUT->GetDataBlockIndex(), AliHLTComponent::DataType2Text(dt).c_str(), spec));
504 Bool_t AliRawReaderHLT::IsHLTInput(int ddlid)
506 // see header file for class documentation
507 vector<int>::iterator detector=fDetectors.begin();
508 for (; detector!=fDetectors.end(); detector++) {
509 int ddlOffset=AliDAQ::DdlIDOffset(*detector);
510 int nofDDLs=AliDAQ::NumberOfDdls(*detector);
511 if (ddlid>=ddlOffset && ddlid<ddlOffset+nofDDLs)
517 AliRawReader* AliRawReaderHLTCreateInstance(AliRawReader* pParentReader, const char* options)
519 // see header file for class documentation
520 if (!pParentReader) return NULL;
521 return new AliRawReaderHLT(pParentReader, options);