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 AliHLTOUT.cxx
20 @author Matthias Richter
22 @brief The control class for HLTOUT data. */
24 // see header file for class documentation
26 // refer to README to build package
28 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
32 #include "AliHLTOUT.h"
37 /** ROOT macro for the implementation of ROOT specific class methods */
40 AliHLTOUT::AliHLTOUT()
42 fSearchDataType(kAliHLTVoidDataType),
43 fSearchSpecification(kAliHLTVoidDataSpec),
44 fSearchHandlerType(AliHLTModuleAgent::kUnknownOutput),
47 fCurrent(fBlockDescList.begin()),
52 // see header file for class documentation
54 // refer to README to build package
56 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
59 AliHLTOUT::~AliHLTOUT()
61 // see header file for class documentation
66 // see header file for class documentation
68 SetStatusFlag(kCollecting);
69 if ((iResult=GenerateIndex())>=0) {
70 if ((iResult=InitHandlers())>=0) {
73 ClearStatusFlag(kCollecting);
77 int AliHLTOUT::GetNofDataBlocks()
79 // see header file for class documentation
80 return fBlockDescList.size();
83 int AliHLTOUT::SelectFirstDataBlock(AliHLTComponentDataType dt, AliHLTUInt32_t spec,
84 AliHLTModuleAgent::AliHLTOUTHandlerType handlerType)
86 // see header file for class documentation
87 if (CheckStatusFlag(kLocked)) return -EPERM;
88 fCurrent=fBlockDescList.begin();
90 fSearchSpecification=spec;
91 fSearchHandlerType=handlerType;
92 return FindAndSelectDataBlock();
95 int AliHLTOUT::SelectNextDataBlock()
97 // see header file for class documentation
98 if (CheckStatusFlag(kLocked)) return -EPERM;
99 if (fCurrent==fBlockDescList.end()) return -ENOENT;
101 return FindAndSelectDataBlock();
104 int AliHLTOUT::FindAndSelectDataBlock()
106 // see header file for class documentation
107 if (CheckStatusFlag(kLocked)) return -EPERM;
109 while (fCurrent!=fBlockDescList.end() && iResult==-ENOENT) {
110 if ((*fCurrent)==fSearchDataType &&
111 (fSearchSpecification==kAliHLTVoidDataSpec || (*fCurrent)==fSearchSpecification) &&
112 (fSearchHandlerType==AliHLTModuleAgent::kUnknownOutput || FindHandlerDesc(fCurrent->GetIndex())==fSearchHandlerType)) {
113 iResult=fCurrent->GetIndex();
114 // TODO: check the byte order on the current system and the byte order of the
115 // data block, print warning when mismatch and user did not check
116 //AliHLTOUTByteOrder blockBO=CheckByteOrder();
119 if (blockBO!=fByteOrder) {
120 SetStatusFlag(kByteOrderWarning);
124 ClearStatusFlag(kByteOrderChecked);
126 // TODO: check the alignment on the current system and the alignment of the
127 // data block, print warning when mismatch and user did not check
128 ClearStatusFlag(kAlignmentChecked);
137 int AliHLTOUT::GetDataBlockDescription(AliHLTComponentDataType& dt, AliHLTUInt32_t& spec)
139 // see header file for class documentation
141 if (fCurrent!=fBlockDescList.end()) {
149 const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::GetDataBlockHandlerDesc()
151 // see header file for class documentation
152 return FindHandlerDesc(GetDataBlockIndex());
155 AliHLTModuleAgent::AliHLTOUTHandlerType AliHLTOUT::GetDataBlockHandlerType()
157 // see header file for class documentation
158 AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=FindHandlerDesc(GetDataBlockIndex());
159 AliHLTModuleAgent::AliHLTOUTHandlerType type=desc;
163 AliHLTUInt32_t AliHLTOUT::GetDataBlockIndex()
165 // see header file for class documentation
166 if (fCurrent==fBlockDescList.end()) return AliHLTOUTInvalidIndex;
167 return fCurrent->GetIndex();
170 int AliHLTOUT::GetDataBuffer(const AliHLTUInt8_t* &pBuffer, AliHLTUInt32_t& size)
172 // see header file for class documentation
176 if (fCurrent!=fBlockDescList.end()) {
177 if ((iResult=GetDataBuffer(fCurrent->GetIndex(), pBuffer, size))>=0) {
184 int AliHLTOUT::ReleaseDataBuffer(const AliHLTUInt8_t* pBuffer)
186 // see header file for class documentation
188 if (pBuffer==fpBuffer) {
191 HLTWarning("buffer %p does not match the provided one %p", pBuffer, fpBuffer);
196 AliHLTModuleAgent* AliHLTOUT::GetAgent()
198 // see header file for class documentation
199 AliHLTModuleAgent* pAgent=NULL;
200 pAgent=FindHandlerDesc(GetDataBlockIndex());
204 AliHLTOUTHandler* AliHLTOUT::GetHandler()
206 // see header file for class documentation
207 AliHLTOUTHandler* pHandler=NULL;
208 pHandler=FindHandlerDesc(GetDataBlockIndex());
212 int AliHLTOUT::WriteESD(const AliHLTUInt8_t* /*pBuffer*/, AliHLTUInt32_t /*size*/, AliHLTComponentDataType /*dt*/, AliESDEvent* /*tgtesd*/) const
214 // see header file for class documentation
215 HLTWarning("method not implemented in base class");
219 int AliHLTOUT::AddBlockDescriptor(const AliHLTOUTBlockDescriptor desc)
221 // see header file for class documentation
222 if (!CheckStatusFlag(kCollecting)) return -EPERM;
224 fBlockDescList.push_back(desc);
228 AliHLTOUT::AliHLTOUTByteOrder AliHLTOUT::CheckByteOrder()
230 // see header file for class documentation
231 if (fCurrent!=fBlockDescList.end()) {
232 SetStatusFlag(kByteOrderChecked);
233 AliHLTOUT::AliHLTOUTByteOrder order=CheckBlockByteOrder((*fCurrent).GetIndex());
236 return kInvalidByteOrder;
239 int AliHLTOUT::CheckAlignment(AliHLTOUT::AliHLTOUTDataType type)
241 // see header file for class documentation
242 if (fCurrent!=fBlockDescList.end()) {
243 SetStatusFlag(kAlignmentChecked);
244 int alignment=CheckBlockAlignment((*fCurrent).GetIndex(), type);
250 int AliHLTOUT::InitHandlers()
252 // see header file for class documentation
254 AliHLTOUTIndexList remnants;
256 for (int havedata=SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec); havedata>=0; havedata=SelectNextDataBlock()) {
258 remnants.push_back(GetDataBlockIndex());
259 AliHLTComponentDataType dt=kAliHLTVoidDataType;
260 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
261 if (GetDataBlockDescription(dt, spec)<0) break;
262 bool bHaveHandler=false;
263 for (AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent(); pAgent && iResult>=0; pAgent=AliHLTModuleAgent::GetNextAgent()) {
264 AliHLTModuleAgent::AliHLTOUTHandlerDesc handlerDesc;
265 if (pAgent->GetHandlerDescription(dt, spec, handlerDesc)>0) {
266 AliHLTOUTHandlerListEntry entry(pAgent->GetOutputHandler(dt, spec), handlerDesc, pAgent, GetDataBlockIndex());
267 InsertHandler(fDataHandlers, entry);
273 if (!bHaveHandler && (dt==kAliHLTDataTypeESDObject || dt==kAliHLTDataTypeESDTree)) {
274 // ESDs are handled by the framework
279 // warning if some of the data blocks are not selected by the kAliHLTAnyDataType
281 if (GetNofDataBlocks()>iCount) {
282 HLTWarning("incomplete data type in %d out of %d data block(s)", GetNofDataBlocks()-iCount, iCount);
285 // warning if handler not found
286 if (remnants.size()>0) {
287 HLTWarning("no handlers found for %d data blocks out of %d", remnants.size(), iCount);
288 AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
289 for (AliHLTOUTIndexList::iterator element=remnants.begin(); element!=remnants.end(); element++) {
290 for (int trials=0; trials<2; trials++) {
292 // we start searching the index from the current position in the block list
293 if ((*block).GetIndex()==*element) break;
294 } while ((++block)!=fBlockDescList.end());
295 if (block==fBlockDescList.end()) {
296 // rewind and try again
297 block=fBlockDescList.begin();
300 assert(block!=fBlockDescList.end());
301 if (block!=fBlockDescList.end()) {
302 HLTDebug(" %s", AliHLTComponent::DataType2Text((AliHLTComponentDataType)*block).c_str());
309 int AliHLTOUT::InsertHandler(AliHLTOUTHandlerListEntryVector& list, const AliHLTOUTHandlerListEntry &entry)
311 // see header file for class documentation
313 AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
314 while (element!=list.end()) {
315 if (entry==(*element)) break;
318 if (element==list.end()) {
319 list.push_back(entry);
321 element->AddIndex(const_cast<AliHLTOUTHandlerListEntry&>(entry));
326 const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::FindHandlerDesc(AliHLTUInt32_t blockIndex)
328 // see header file for class documentation
329 AliHLTOUTHandlerListEntryVector::iterator element=fDataHandlers.begin();
330 while (element!=fDataHandlers.end()) {
331 if (element->HasIndex(blockIndex)) {
336 return const_cast<AliHLTOUT::AliHLTOUTHandlerListEntry&>(AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry);
339 AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry()
346 // see header file for class documentation
349 AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(AliHLTOUTHandler* pHandler,
350 AliHLTModuleAgent::AliHLTOUTHandlerDesc& handlerDesc,
351 AliHLTModuleAgent* pAgent,
352 AliHLTUInt32_t index)
355 fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
359 // see header file for class documentation
360 *fpHandlerDesc=handlerDesc;
361 fBlocks.push_back(index);
364 AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(const AliHLTOUTHandlerListEntry& src)
366 fpHandler(src.fpHandler),
367 fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
368 fpAgent(src.fpAgent),
371 // see header file for class documentation
372 *fpHandlerDesc=*src.fpHandlerDesc;
373 fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
376 AliHLTOUT::AliHLTOUTHandlerListEntry::~AliHLTOUTHandlerListEntry()
378 // see header file for class documentation
379 if (fpHandlerDesc) delete fpHandlerDesc;
383 AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::AliHLTOUTHandlerListEntry::operator=(const AliHLTOUTHandlerListEntry& src)
385 // see header file for class documentation
386 fpHandler=src.fpHandler;
387 if (src.fpHandlerDesc)
388 *fpHandlerDesc=*src.fpHandlerDesc;
390 fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
394 AliHLTUInt32_t AliHLTOUT::AliHLTOUTHandlerListEntry::operator[](int i) const
396 // see header file for class documentation
397 return (int)fBlocks.size()>i?fBlocks[i]:AliHLTOUTInvalidIndex;
400 bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTOUTHandlerListEntry& entry) const
402 // see header file for class documentation
403 if (entry.fpHandler!=fpHandler || fpHandler==NULL) return false;
404 assert(entry.fpAgent==fpAgent);
405 if (entry.fpAgent!=fpAgent) return false;
409 bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTModuleAgent::AliHLTOUTHandlerType handlerType) const
411 // see header file for class documentation
412 if (!fpHandlerDesc) return false;
413 return *fpHandlerDesc==handlerType;
416 void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTOUT::AliHLTOUTHandlerListEntry &desc)
418 // see header file for class documentation
419 AliHLTOUTIndexList::iterator element;
420 for (element=desc.fBlocks.begin(); element!=desc.fBlocks.end(); element++) {
425 void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTUInt32_t index)
427 // see header file for class documentation
428 fBlocks.push_back(index);
431 bool AliHLTOUT::AliHLTOUTHandlerListEntry::HasIndex(AliHLTUInt32_t index)
433 // see header file for class documentation
434 AliHLTOUTIndexList::iterator element;
435 for (element=fBlocks.begin(); element!=fBlocks.end(); element++) {
436 if (*element==index) return true;
441 const AliHLTOUT::AliHLTOUTHandlerListEntry AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry;
443 AliHLTUInt64_t AliHLTOUT::ByteSwap64(AliHLTUInt64_t src)
445 // see header file for class documentation
446 return ((src & 0xFFULL) << 56) |
447 ((src & 0xFF00ULL) << 40) |
448 ((src & 0xFF0000ULL) << 24) |
449 ((src & 0xFF000000ULL) << 8) |
450 ((src & 0xFF00000000ULL) >> 8) |
451 ((src & 0xFF0000000000ULL) >> 24) |
452 ((src & 0xFF000000000000ULL) >> 40) |
453 ((src & 0xFF00000000000000ULL) >> 56);
456 AliHLTUInt32_t AliHLTOUT::ByteSwap32(AliHLTUInt32_t src)
458 // see header file for class documentation
459 return ((src & 0xFFULL) << 24) |
460 ((src & 0xFF00ULL) << 8) |
461 ((src & 0xFF0000ULL) >> 8) |
462 ((src & 0xFF000000ULL) >> 24);
465 AliHLTOUT* AliHLTOUT::New(AliRawReader* pRawReader)
467 // see header file for class documentation
468 AliHLTOUT* instance=New("AliHLTOUTRawReader");
470 instance->SetParam(pRawReader);
475 AliHLTOUT* AliHLTOUT::New(TTree* pDigitTree, int event)
477 // see header file for class documentation
478 AliHLTOUT* instance=New("AliHLTOUTDigitReader");
480 instance->SetParam(pDigitTree, event);
485 AliHLTOUT* AliHLTOUT::New(const char* classname)
487 // see header file for class documentation
489 AliHLTOUT* instance=NULL;
492 ROOT::NewFunc_t pNewFunc=NULL;
494 pCl=TClass::GetClass(classname);
495 } while (!pCl && (iLibResult=gSystem->Load("libHLTRec.so"))==0);
497 if (pCl && (pNewFunc=pCl->GetNew())!=NULL) {
498 void* p=(*pNewFunc)(NULL);
500 instance=reinterpret_cast<AliHLTOUT*>(p);
502 log.Logging(kHLTLogError, "AliHLTOUT::New", "HLTOUT handling", "type cast to AliHLTOUT instance failed");
505 log.Logging(kHLTLogError, "AliHLTOUT::New", "HLTOUT handling", "can not create AliHLTOUT instance from class descriptor");
508 log.Logging(kHLTLogError, "AliHLTOUT::New", "HLTOUT handling", "can not find AliHLTOUT class descriptor");
511 log.Logging(kHLTLogError, "AliHLTOUT::New", "HLTOUT handling", "can not load libHLTrec library");
516 void AliHLTOUT::Delete(AliHLTOUT* pInstance)
518 // see header file for class documentation
519 if (!pInstance) return;
521 // check if the library is still there in order to have the
522 // destructor available
523 TClass* pCl1=TClass::GetClass("AliHLTOUTRawReader");
524 TClass* pCl2=TClass::GetClass("AliHLTOUTDigitReader");
525 if (!pCl1 && !pCl2) {
527 log.Logging(kHLTLogError, "AliHLTOUT::Delete", "HLTOUT handling", "potential memory leak: libHLTrec library not available, skipping destruction %p", pInstance);
534 void AliHLTOUT::SetParam(AliRawReader* /*pRawReader*/)
536 // see header file for class documentation
537 // default implementation, we should never get here
538 // this function can only be called from the class itsself and
539 // is intended to be used with the New functions. If we get into
540 // the default implementation there is a class mismatch.
542 HLTFatal("severe internal error: class mismatch");
545 void AliHLTOUT::SetParam(TTree* /*pDigitTree*/, int /*event*/)
547 // see header file for class documentation
548 // default implementation, we should never get here
549 // this function can only be called from the class itsself and
550 // is intended to be used with the New functions. If we get into
551 // the default implementation there is a class mismatch.
553 HLTFatal("severe internal error: class mismatch");