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"
37 #include "AliDAQ.h" // RAW, for detector names and equipment ids
38 #include "TObjString.h"
41 /** ROOT macro for the implementation of ROOT specific class methods */
42 ClassImp(AliRawReaderHLT)
44 AliRawReaderHLT::AliRawReaderHLT(AliRawReader* pRawreader, const char* options)
47 fpParentReader(pRawreader),
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 (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize);
72 else fpHLTOUT->ReleaseDataBuffer(fpData);
79 UInt_t AliRawReaderHLT::GetType() const
81 // see header file for class documentation
82 return fpParentReader->GetType();
85 UInt_t AliRawReaderHLT::GetRunNumber() const
87 // see header file for class documentation
88 return fpParentReader->GetRunNumber();
91 const UInt_t* AliRawReaderHLT::GetEventId() const
93 // see header file for class documentation
94 return fpParentReader->GetEventId();
97 const UInt_t* AliRawReaderHLT::GetTriggerPattern() const
99 // see header file for class documentation
100 return fpParentReader->GetTriggerPattern();
103 const UInt_t* AliRawReaderHLT::GetDetectorPattern() const
105 // see header file for class documentation
106 return fpParentReader->GetDetectorPattern();
109 const UInt_t* AliRawReaderHLT::GetAttributes() const
111 // see header file for class documentation
112 return fpParentReader->GetAttributes();
115 const UInt_t* AliRawReaderHLT::GetSubEventAttributes() const
117 // see header file for class documentation
118 return fpParentReader->GetSubEventAttributes();
121 UInt_t AliRawReaderHLT::GetLDCId() const
123 // see header file for class documentation
124 return fpParentReader->GetLDCId();
127 UInt_t AliRawReaderHLT::GetGDCId() const
129 // see header file for class documentation
130 return fpParentReader->GetGDCId();
133 UInt_t AliRawReaderHLT::GetTimestamp() const
135 // see header file for class documentation
136 return fpParentReader->GetTimestamp();
139 const UInt_t* AliRawReaderHLT::GetEquipmentAttributes() const
141 // see header file for class documentation
142 return fpParentReader->GetEquipmentAttributes();
145 Int_t AliRawReaderHLT::GetEquipmentElementSize() const
147 // see header file for class documentation
148 // don't know what it really means, bu the AliRawReaderFile
150 // do the same if we have a valid equipment data set from
152 if (fEquipmentId>=0) return 0;
153 return fpParentReader->GetEquipmentElementSize();
156 Int_t AliRawReaderHLT::GetEquipmentHeaderSize() const
158 // see header file for class documentation
160 // equipment header means the additional data header?
161 // if we have a valid equipment data set from the HLT stream
162 // there is no additional header
163 if (fEquipmentId>=0) return 0;
164 return fpParentReader->GetEquipmentHeaderSize();
167 Int_t AliRawReaderHLT::GetEquipmentSize() const
169 // see header file for class documentation
170 if (fEquipmentId>=0) return fDataSize+sizeof(AliRawDataHeader);
171 return fpParentReader->GetEquipmentSize();
174 Int_t AliRawReaderHLT::GetEquipmentType() const
176 // see header file for class documentation
177 return fpParentReader->GetEquipmentType();
180 Int_t AliRawReaderHLT::GetEquipmentId() const
182 // see header file for class documentation
184 if (fEquipmentId>=0) id=fEquipmentId;
185 else id=fpParentReader->GetEquipmentId();
189 Bool_t AliRawReaderHLT::ReadHeader()
191 // see header file for class documentation
192 Bool_t result=fpParentReader->ReadHeader();
193 fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader());
197 Bool_t AliRawReaderHLT::ReadNextData(UChar_t*& data)
199 // see header file for class documentation
201 // this function is the backbone of the ReadNext functions, it gets the
202 // whole data block either from the HLT stream or the parent raw reader.
203 // Each call of ReadNextData directly jumps to the next data set.
204 Bool_t result=kFALSE;
205 if (fbHaveHLTData&=ReadNextHLTData()) {
206 // all internal data variables set
207 assert(fpData!=NULL);
208 data=const_cast<AliHLTUInt8_t*>(fpData);
212 // no data in the HLT stream, read real data
213 //AliInfo(Form("read from parent reader: min=%d max=%d", fSelectMinEquipmentId, fSelectMaxEquipmentId));
215 // first set the selection back to the original one
216 fpParentReader->SelectEquipment(fSelectEquipmentType, fSelectMinEquipmentId, fSelectMaxEquipmentId);
219 while (result=fpParentReader->ReadNextData(data)) {
220 // continue if the Equipment Id is supposed to be replaced by the HLT stream
221 // in that case we do not want to read it from the parent raw reader
222 if (!IsHLTInput(fpParentReader->GetEquipmentId())) break;
225 // set the header of this reader from the parent reader.
226 // This is necessary because of a few base class methods working directly
228 fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader());
231 fDataSize=fpParentReader->GetDataSize();
242 Bool_t AliRawReaderHLT::ReadNextInt(UInt_t& data)
244 // see header file for class documentation
245 int iCopy=sizeof(UInt_t);
248 if (fpData && (fDataSize-fOffset)>=iCopy) {
249 data=*reinterpret_cast<const UInt_t*>(fpData+fOffset);
253 } while (ReadNextData(dummy));
257 Bool_t AliRawReaderHLT::ReadNextShort(UShort_t& data)
259 // see header file for class documentation
260 int iCopy=sizeof(UShort_t);
263 if (fpData && (fDataSize-fOffset)>=iCopy) {
264 data=*reinterpret_cast<const UShort_t*>(fpData+fOffset);
268 } while (ReadNextData(dummy));
272 Bool_t AliRawReaderHLT::ReadNextChar(UChar_t& data)
274 // see header file for class documentation
275 int iCopy=sizeof(UChar_t);
278 if (fpData && (fDataSize-fOffset)>=iCopy) {
279 data=*reinterpret_cast<const UChar_t*>(fpData+fOffset);
283 } while (ReadNextData(dummy));
287 Bool_t AliRawReaderHLT::ReadNext(UChar_t* data, Int_t size)
289 // see header file for class documentation
292 if (fpData && (fDataSize-fOffset)>=size) {
293 // copy remaining data
294 int iCopy=fDataSize-fOffset;
295 if (iCopy>size) iCopy=size;
296 memcpy(data, fpData+fOffset, iCopy);
300 } while (ReadNextData(dummy));
304 Bool_t AliRawReaderHLT::Reset()
306 // see header file for class documentation
307 Bool_t result=fpParentReader->Reset();
312 if (fbHaveHLTData=(fDetectors.size()>0)) {
313 vector<int>::iterator detector=fDetectors.begin();
314 for (; detector!=fDetectors.end(); detector++) {
315 int ddlOffset=AliDAQ::DdlIDOffset(*detector);
316 int nofDDLs=AliDAQ::NumberOfDdls(*detector);
317 if ((fSelectMinEquipmentId>=0 && fSelectMinEquipmentId>ddlOffset+nofDDLs) ||
318 (fSelectMinEquipmentId>=0 && fSelectMaxEquipmentId<ddlOffset))
322 fbHaveHLTData=detector!=fDetectors.end();
326 if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize);
327 else fpHLTOUT->ReleaseDataBuffer(fpData);
336 Bool_t AliRawReaderHLT::NextEvent()
338 // see header file for class documentation
339 Bool_t result=fpParentReader->NextEvent();
347 Bool_t AliRawReaderHLT::RewindEvents()
349 // see header file for class documentation
352 return fpParentReader->RewindEvents();
355 void AliRawReaderHLT::Select(Int_t detectorID, Int_t minDDLID, Int_t maxDDLID)
357 // see header file for class documentation
358 AliRawReader::Select(detectorID, minDDLID, maxDDLID);
359 fpParentReader->Select(detectorID, minDDLID, maxDDLID);
362 // most likely we do not need this method since the base class directly forwards
364 // void AliRawReaderHLT::Select(const char *detectorName, Int_t minDDLID, Int_t maxDDLID)
366 // AliInfo(Form("detectorName=%s, minDDLID=%d, maxDDLID=%d", detectorName, minDDLID, maxDDLID));
367 // AliRawReader::Select(detectorName, minDDLID, maxDDLID);
368 // fpParentReader->Select(detectorName, minDDLID, maxDDLID);
371 void AliRawReaderHLT::SelectEquipment(Int_t equipmentType, Int_t minEquipmentId, Int_t maxEquipmentId)
373 // see header file for class documentation
375 //AliInfo(Form("equipmentType=%d, minEquipmentId=%d, maxEquipmentId=%d", equipmentType, minEquipmentId, maxEquipmentId));
376 AliRawReader::Select(equipmentType, minEquipmentId, maxEquipmentId);
377 fpParentReader->Select(equipmentType, minEquipmentId, maxEquipmentId);
380 void AliRawReaderHLT::SkipInvalid(Bool_t skip)
382 // see header file for class documentation
384 AliRawReader::SkipInvalid(skip);
385 fpParentReader->SkipInvalid(skip);
388 void AliRawReaderHLT::SelectEvents(Int_t type)
390 // see header file for class documentation
392 //AliInfo(Form("type=%d", type));
393 AliRawReader::SelectEvents(type);
394 fpParentReader->SelectEvents(type);
397 int AliRawReaderHLT::ScanOptions(const char* options)
399 // see header file for class documentation
401 TString optString(options);
404 TObjArray* pTokens=optString.Tokenize(" ");
406 int iEntries=pTokens->GetEntries();
407 for (int i =0; i<iEntries; i++) {
408 argument=((TObjString*)pTokens->At(i))->GetString();
409 // first scan all the other options
410 // no other options for the moment
412 // it must be a detector name
413 int detId=AliDAQ::DetectorID(argument.Data());
415 fDetectors.push_back(detId);
424 Bool_t AliRawReaderHLT::ReadNextHLTData()
426 // see header file for class documentation
429 fpHLTOUT=new AliHLTOUTRawReader(fpParentReader);
430 if (result=(fpHLTOUT!=NULL)) {
431 if (result=(fpHLTOUT->Init()>=0)) {
432 result=fpHLTOUT->SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec,
433 AliHLTModuleAgent::kRawReader)>=0;
437 // first release the data buffer
438 if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize);
439 else fpHLTOUT->ReleaseDataBuffer(fpData);
441 if (!(result=fpHLTOUT->SelectNextDataBlock()>=0)) {
447 AliHLTComponentDataType dt=kAliHLTVoidDataType;
448 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
449 fpHLTOUT->GetDataBlockDescription(dt, spec);
450 AliHLTUInt32_t size=0;
451 AliHLTOUTHandler* pHandler=fpHLTOUT->GetHandler();
453 if (dynamic_cast<AliHLTOUTHandlerEquId*>(pHandler)!=NULL) {
454 AliHLTOUT::AliHLTOUTLockGuard g(fpHLTOUT);
455 fEquipmentId=pHandler->ProcessData(fpHLTOUT);
457 fDataSize=pHandler->GetProcessedData(fpData);
459 result=fpHLTOUT->GetDataBuffer(fpData, size)>=0;
460 AliDebug(AliLog::kDebug, Form("forward data block from HLTOUT stream to equipment %d", fEquipmentId));
463 // remember the current handler in order to properly release the data buffer
464 fpDataHandler=pHandler;
465 AliDebug(AliLog::kDebug, Form("forward decoded data block provided by handler to equipment %d", fEquipmentId));
468 AliError(Form("handler is not of type AliHLTOUTHandlerEquId for block %x data type %s spec %#x; data block skipped",
469 fpHLTOUT->GetDataBlockIndex(), AliHLTComponent::DataType2Text(dt).c_str(), spec));
472 AliWarning(Form("no data handler found for block %x data type %s spec %#x; data block skipped",
473 fpHLTOUT->GetDataBlockIndex(), AliHLTComponent::DataType2Text(dt).c_str(), spec));
484 Bool_t AliRawReaderHLT::IsHLTInput(int ddlid)
486 // see header file for class documentation
487 vector<int>::iterator detector=fDetectors.begin();
488 for (; detector!=fDetectors.end(); detector++) {
489 int ddlOffset=AliDAQ::DdlIDOffset(*detector);
490 int nofDDLs=AliDAQ::NumberOfDdls(*detector);
491 if (ddlid>=ddlOffset && ddlid<ddlOffset+nofDDLs)
497 AliRawReader* AliRawReaderHLTCreateInstance(AliRawReader* pParentReader, const char* options)
499 // see header file for class documentation
500 if (!pParentReader) return NULL;
501 return new AliRawReaderHLT(pParentReader, options);