added new helper components to libAliHLTUtil (EsdCollector and AliHLTOUTPublisher...
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTOUT.cxx
CommitLineData
62bb3cd4 1// $Id$
2
3/**************************************************************************
4 * This file is property of and copyright by the ALICE HLT Project *
5 * ALICE Experiment at CERN, All rights reserved. *
6 * *
7 * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 * for The ALICE HLT Project. *
9 * *
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 **************************************************************************/
18
19/** @file AliHLTOUT.cxx
20 @author Matthias Richter
21 @date
22 @brief The control class for HLTOUT data. */
23
4de7334f 24// see header file for class documentation
25// or
26// refer to README to build package
27// or
28// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
62bb3cd4 29
4de7334f 30#include <cerrno>
5db0e774 31#include <cassert>
62bb3cd4 32#include "AliHLTOUT.h"
c1292031 33#include "TSystem.h"
34#include "TClass.h"
35#include "TROOT.h"
62bb3cd4 36
37/** ROOT macro for the implementation of ROOT specific class methods */
38ClassImp(AliHLTOUT)
39
40AliHLTOUT::AliHLTOUT()
4de7334f 41 :
42 fSearchDataType(kAliHLTVoidDataType),
43 fSearchSpecification(kAliHLTVoidDataSpec),
44dc7683 44 fSearchHandlerType(AliHLTModuleAgent::kUnknownOutput),
049b43b2 45 fFlags(0),
4de7334f 46 fBlockDescList(),
47 fCurrent(fBlockDescList.begin()),
5db0e774 48 fpBuffer(NULL),
44dc7683 49 fDataHandlers(),
50 fbVerbose(true)
4de7334f 51{
62bb3cd4 52 // see header file for class documentation
53 // or
54 // refer to README to build package
55 // or
56 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
57}
58
59AliHLTOUT::~AliHLTOUT()
4de7334f 60{
61 // see header file for class documentation
62}
63
5db0e774 64int AliHLTOUT::Init()
65{
66 // see header file for class documentation
67 int iResult=0;
18b56222 68 SetStatusFlag(kCollecting);
5db0e774 69 if ((iResult=GenerateIndex())>=0) {
70 if ((iResult=InitHandlers())>=0) {
71 }
72 }
18b56222 73 ClearStatusFlag(kCollecting);
5db0e774 74 return iResult;
75}
76
4de7334f 77int AliHLTOUT::GetNofDataBlocks()
78{
79 // see header file for class documentation
80 return fBlockDescList.size();
81}
82
5db0e774 83int AliHLTOUT::SelectFirstDataBlock(AliHLTComponentDataType dt, AliHLTUInt32_t spec,
44dc7683 84 AliHLTModuleAgent::AliHLTOUTHandlerType handlerType)
4de7334f 85{
86 // see header file for class documentation
049b43b2 87 if (CheckStatusFlag(kLocked)) return -EPERM;
4de7334f 88 fCurrent=fBlockDescList.begin();
89 fSearchDataType=dt;
90 fSearchSpecification=spec;
44dc7683 91 fSearchHandlerType=handlerType;
049b43b2 92 return FindAndSelectDataBlock();
4de7334f 93}
94
95int AliHLTOUT::SelectNextDataBlock()
96{
97 // see header file for class documentation
049b43b2 98 if (CheckStatusFlag(kLocked)) return -EPERM;
18b56222 99 if (fCurrent==fBlockDescList.end()) return -ENOENT;
049b43b2 100 fCurrent++;
101 return FindAndSelectDataBlock();
102}
103
104int AliHLTOUT::FindAndSelectDataBlock()
105{
106 // see header file for class documentation
107 if (CheckStatusFlag(kLocked)) return -EPERM;
4de7334f 108 int iResult=-ENOENT;
109 while (fCurrent!=fBlockDescList.end() && iResult==-ENOENT) {
d8f5c9fe 110 if ((*fCurrent)==fSearchDataType &&
44dc7683 111 (fSearchSpecification==kAliHLTVoidDataSpec || (*fCurrent)==fSearchSpecification) &&
112 (fSearchHandlerType==AliHLTModuleAgent::kUnknownOutput || FindHandlerDesc(fCurrent->GetIndex())==fSearchHandlerType)) {
18b56222 113 iResult=fCurrent->GetIndex();
049b43b2 114 // TODO: check the byte order on the current system and the byte order of the
c5123824 115 // data block, print warning when mismatch and user did not check
13398559 116 //AliHLTOUTByteOrder blockBO=CheckByteOrder();
06f53caf 117 CheckByteOrder();
049b43b2 118 /*
119 if (blockBO!=fByteOrder) {
120 SetStatusFlag(kByteOrderWarning);
121
122 }
123 */
124 ClearStatusFlag(kByteOrderChecked);
125
126 // TODO: check the alignment on the current system and the alignment of the
c5123824 127 // data block, print warning when mismatch and user did not check
049b43b2 128 ClearStatusFlag(kAlignmentChecked);
18b56222 129
130 break;
4de7334f 131 }
049b43b2 132 fCurrent++;
4de7334f 133 }
134 return iResult;
135}
136
137int AliHLTOUT::GetDataBlockDescription(AliHLTComponentDataType& dt, AliHLTUInt32_t& spec)
138{
139 // see header file for class documentation
140 int iResult=-ENOENT;
141 if (fCurrent!=fBlockDescList.end()) {
142 iResult=0;
143 dt=(*fCurrent);
144 spec=(*fCurrent);
145 }
146 return iResult;
147}
148
c5123824 149const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::GetDataBlockHandlerDesc()
150{
151 // see header file for class documentation
152 return FindHandlerDesc(GetDataBlockIndex());
153}
154
155AliHLTModuleAgent::AliHLTOUTHandlerType AliHLTOUT::GetDataBlockHandlerType()
156{
157 // see header file for class documentation
158 AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=FindHandlerDesc(GetDataBlockIndex());
159 AliHLTModuleAgent::AliHLTOUTHandlerType type=desc;
160 return type;
161}
162
5db0e774 163AliHLTUInt32_t AliHLTOUT::GetDataBlockIndex()
164{
165 // see header file for class documentation
18b56222 166 if (fCurrent==fBlockDescList.end()) return AliHLTOUTInvalidIndex;
167 return fCurrent->GetIndex();
5db0e774 168}
169
4de7334f 170int AliHLTOUT::GetDataBuffer(const AliHLTUInt8_t* &pBuffer, AliHLTUInt32_t& size)
171{
172 // see header file for class documentation
173 int iResult=-ENOENT;
174 pBuffer=NULL;
175 size=0;
176 if (fCurrent!=fBlockDescList.end()) {
e94eb049 177 if ((iResult=GetDataBuffer(fCurrent->GetIndex(), pBuffer, size))>=0) {
4de7334f 178 fpBuffer=pBuffer;
179 }
180 }
181 return iResult;
182}
183
184int AliHLTOUT::ReleaseDataBuffer(const AliHLTUInt8_t* pBuffer)
185{
186 // see header file for class documentation
187 int iResult=0;
188 if (pBuffer==fpBuffer) {
189 fpBuffer=NULL;
190 } else {
191 HLTWarning("buffer %p does not match the provided one %p", pBuffer, fpBuffer);
192 }
193 return iResult;
194}
195
c5123824 196AliHLTModuleAgent* AliHLTOUT::GetAgent()
197{
198 // see header file for class documentation
199 AliHLTModuleAgent* pAgent=NULL;
200 pAgent=FindHandlerDesc(GetDataBlockIndex());
201 return pAgent;
202}
203
626bfcc1 204AliHLTOUTHandler* AliHLTOUT::GetHandler()
205{
206 // see header file for class documentation
207 AliHLTOUTHandler* pHandler=NULL;
208 pHandler=FindHandlerDesc(GetDataBlockIndex());
209 return pHandler;
210}
211
c5123824 212int AliHLTOUT::WriteESD(const AliHLTUInt8_t* /*pBuffer*/, AliHLTUInt32_t /*size*/, AliHLTComponentDataType /*dt*/, AliESDEvent* /*tgtesd*/) const
213{
214 // see header file for class documentation
215 HLTWarning("method not implemented in base class");
216 return -ENOSYS;
217}
218
4de7334f 219int AliHLTOUT::AddBlockDescriptor(const AliHLTOUTBlockDescriptor desc)
220{
62bb3cd4 221 // see header file for class documentation
049b43b2 222 if (!CheckStatusFlag(kCollecting)) return -EPERM;
4de7334f 223 int iResult=0;
224 fBlockDescList.push_back(desc);
225 return iResult;
62bb3cd4 226}
049b43b2 227
13398559 228AliHLTOUT::AliHLTOUTByteOrder AliHLTOUT::CheckByteOrder()
049b43b2 229{
5db0e774 230 // see header file for class documentation
049b43b2 231 if (fCurrent!=fBlockDescList.end()) {
232 SetStatusFlag(kByteOrderChecked);
13398559 233 AliHLTOUT::AliHLTOUTByteOrder order=CheckBlockByteOrder((*fCurrent).GetIndex());
049b43b2 234 return order;
235 }
236 return kInvalidByteOrder;
237}
238
13398559 239int AliHLTOUT::CheckAlignment(AliHLTOUT::AliHLTOUTDataType type)
049b43b2 240{
5db0e774 241 // see header file for class documentation
049b43b2 242 if (fCurrent!=fBlockDescList.end()) {
243 SetStatusFlag(kAlignmentChecked);
244 int alignment=CheckBlockAlignment((*fCurrent).GetIndex(), type);
245 return alignment;
246 }
247 return -ENOENT;
248}
5db0e774 249
250int AliHLTOUT::InitHandlers()
251{
252 // see header file for class documentation
253 int iResult=0;
254 AliHLTOUTIndexList remnants;
44dc7683 255 int iCount=0;
a3ef3c1d 256 for (int havedata=SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec); havedata>=0; havedata=SelectNextDataBlock()) {
44dc7683 257 iCount++;
5db0e774 258 remnants.push_back(GetDataBlockIndex());
259 AliHLTComponentDataType dt=kAliHLTVoidDataType;
260 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
e94eb049 261 if (GetDataBlockDescription(dt, spec)<0) break;
f94e8c27 262 bool bHaveHandler=false;
5db0e774 263 for (AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent(); pAgent && iResult>=0; pAgent=AliHLTModuleAgent::GetNextAgent()) {
264 AliHLTModuleAgent::AliHLTOUTHandlerDesc handlerDesc;
626bfcc1 265 if (pAgent->GetHandlerDescription(dt, spec, handlerDesc)>0) {
5db0e774 266 AliHLTOUTHandlerListEntry entry(pAgent->GetOutputHandler(dt, spec), handlerDesc, pAgent, GetDataBlockIndex());
c5123824 267 InsertHandler(fDataHandlers, entry);
5db0e774 268 remnants.pop_back();
f94e8c27 269 bHaveHandler=true;
5db0e774 270 break;
271 }
272 }
f94e8c27 273 if (!bHaveHandler && (dt==kAliHLTDataTypeESDObject || dt==kAliHLTDataTypeESDTree)) {
274 // ESDs are handled by the framework
275 remnants.pop_back();
276 }
5db0e774 277 }
44dc7683 278
279 // warning if some of the data blocks are not selected by the kAliHLTAnyDataType
280 // criterion
281 if (GetNofDataBlocks()>iCount) {
282 HLTWarning("incomplete data type in %d out of %d data block(s)", GetNofDataBlocks()-iCount, iCount);
283 }
284
285 // warning if handler not found
5db0e774 286 if (remnants.size()>0) {
44dc7683 287 HLTWarning("no handlers found for %d data blocks out of %d", remnants.size(), iCount);
13398559 288 AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
5db0e774 289 for (AliHLTOUTIndexList::iterator element=remnants.begin(); element!=remnants.end(); element++) {
290 for (int trials=0; trials<2; trials++) {
291 do {
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();
298 }
299 }
300 assert(block!=fBlockDescList.end());
301 if (block!=fBlockDescList.end()) {
302 HLTDebug(" %s", AliHLTComponent::DataType2Text((AliHLTComponentDataType)*block).c_str());
303 }
304 }
305 }
306 return iResult;
307}
308
c5123824 309int AliHLTOUT::InsertHandler(AliHLTOUTHandlerListEntryVector& list, const AliHLTOUTHandlerListEntry &entry)
5db0e774 310{
311 // see header file for class documentation
312 int iResult=0;
c5123824 313 AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
314 while (element!=list.end()) {
5db0e774 315 if (entry==(*element)) break;
316 element++;
317 }
c5123824 318 if (element==list.end()) {
319 list.push_back(entry);
5db0e774 320 } else {
a3ef3c1d 321 element->AddIndex(const_cast<AliHLTOUTHandlerListEntry&>(entry));
5db0e774 322 }
323 return iResult;
324}
325
44dc7683 326const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::FindHandlerDesc(AliHLTUInt32_t blockIndex)
626bfcc1 327{
328 // see header file for class documentation
13398559 329 AliHLTOUTHandlerListEntryVector::iterator element=fDataHandlers.begin();
626bfcc1 330 while (element!=fDataHandlers.end()) {
331 if (element->HasIndex(blockIndex)) {
332 return *element;
333 }
334 element++;
335 }
44dc7683 336 return const_cast<AliHLTOUT::AliHLTOUTHandlerListEntry&>(AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry);
626bfcc1 337}
338
339AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry()
340 :
341 fpHandler(NULL),
342 fpHandlerDesc(NULL),
343 fpAgent(NULL),
344 fBlocks()
345{
346 // see header file for class documentation
347}
348
5db0e774 349AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(AliHLTOUTHandler* pHandler,
350 AliHLTModuleAgent::AliHLTOUTHandlerDesc& handlerDesc,
351 AliHLTModuleAgent* pAgent,
352 AliHLTUInt32_t index)
353 :
354 fpHandler(pHandler),
626bfcc1 355 fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
5db0e774 356 fpAgent(pAgent),
357 fBlocks()
358{
359 // see header file for class documentation
626bfcc1 360 *fpHandlerDesc=handlerDesc;
5db0e774 361 fBlocks.push_back(index);
362}
363
364AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(const AliHLTOUTHandlerListEntry& src)
365 :
366 fpHandler(src.fpHandler),
626bfcc1 367 fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
5db0e774 368 fpAgent(src.fpAgent),
369 fBlocks()
370{
371 // see header file for class documentation
626bfcc1 372 *fpHandlerDesc=*src.fpHandlerDesc;
5db0e774 373 fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
374}
375
fb24bec7 376AliHLTOUT::AliHLTOUTHandlerListEntry::~AliHLTOUTHandlerListEntry()
377{
378 // see header file for class documentation
626bfcc1 379 if (fpHandlerDesc) delete fpHandlerDesc;
380 fpHandlerDesc=NULL;
fb24bec7 381}
382
5db0e774 383AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::AliHLTOUTHandlerListEntry::operator=(const AliHLTOUTHandlerListEntry& src)
384{
385 // see header file for class documentation
386 fpHandler=src.fpHandler;
44dc7683 387 if (src.fpHandlerDesc)
388 *fpHandlerDesc=*src.fpHandlerDesc;
5db0e774 389 fpAgent=src.fpAgent;
390 fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
391 return *this;
392}
393
18b56222 394AliHLTUInt32_t AliHLTOUT::AliHLTOUTHandlerListEntry::operator[](int i) const
395{
396 // see header file for class documentation
b0914d2e 397 return (int)fBlocks.size()>i?fBlocks[i]:AliHLTOUTInvalidIndex;
5db0e774 398}
399
fb24bec7 400bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTOUTHandlerListEntry& entry) const
401{
18b56222 402 // see header file for class documentation
a3ef3c1d 403 if (entry.fpHandler!=fpHandler || fpHandler==NULL) return false;
404 assert(entry.fpAgent==fpAgent);
405 if (entry.fpAgent!=fpAgent) return false;
406 return true;
407}
408
44dc7683 409bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTModuleAgent::AliHLTOUTHandlerType handlerType) const
410{
411 // see header file for class documentation
412 if (!fpHandlerDesc) return false;
413 return *fpHandlerDesc==handlerType;
414}
415
a3ef3c1d 416void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTOUT::AliHLTOUTHandlerListEntry &desc)
417{
418 // see header file for class documentation
419 AliHLTOUTIndexList::iterator element;
420 for (element=desc.fBlocks.begin(); element!=desc.fBlocks.end(); element++) {
421 AddIndex(*element);
422 }
fb24bec7 423}
424
18b56222 425void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTUInt32_t index)
426{
427 // see header file for class documentation
5db0e774 428 fBlocks.push_back(index);
429}
626bfcc1 430
200853e2 431bool AliHLTOUT::AliHLTOUTHandlerListEntry::HasIndex(AliHLTUInt32_t index)
432{
433 // see header file for class documentation
a3ef3c1d 434 AliHLTOUTIndexList::iterator element;
435 for (element=fBlocks.begin(); element!=fBlocks.end(); element++) {
436 if (*element==index) return true;
437 }
200853e2 438 return false;
439}
440
626bfcc1 441const AliHLTOUT::AliHLTOUTHandlerListEntry AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry;
44dc7683 442
ff3b6fed 443AliHLTUInt64_t AliHLTOUT::ByteSwap64(AliHLTUInt64_t src)
44dc7683 444{
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);
454}
455
ff3b6fed 456AliHLTUInt32_t AliHLTOUT::ByteSwap32(AliHLTUInt32_t src)
44dc7683 457{
458 // see header file for class documentation
459 return ((src & 0xFFULL) << 24) |
460 ((src & 0xFF00ULL) << 8) |
461 ((src & 0xFF0000ULL) >> 8) |
462 ((src & 0xFF000000ULL) >> 24);
463}
c1292031 464
465AliHLTOUT* AliHLTOUT::New(AliRawReader* pRawReader)
466{
467 // see header file for class documentation
468 AliHLTOUT* instance=New("AliHLTOUTRawReader");
469 if (instance) {
470 instance->SetParam(pRawReader);
471 }
472 return instance;
473}
474
475AliHLTOUT* AliHLTOUT::New(TTree* pDigitTree, int event)
476{
477 // see header file for class documentation
478 AliHLTOUT* instance=New("AliHLTOUTDigitReader");
479 if (instance) {
480 instance->SetParam(pDigitTree, event);
481 }
482 return instance;
483}
484
485AliHLTOUT* AliHLTOUT::New(const char* classname)
486{
487 // see header file for class documentation
488 int iLibResult=0;
489 AliHLTOUT* instance=NULL;
490 AliHLTLogging log;
491 TClass* pCl=NULL;
492 ROOT::NewFunc_t pNewFunc=NULL;
493 do {
494 pCl=TClass::GetClass(classname);
495 } while (!pCl && (iLibResult=gSystem->Load("libHLTRec.so"))==0);
496 if (iLibResult>=0) {
497 if (pCl && (pNewFunc=pCl->GetNew())!=NULL) {
498 void* p=(*pNewFunc)(NULL);
499 if (p) {
500 instance=reinterpret_cast<AliHLTOUT*>(p);
501 if (!instance) {
502 log.Logging(kHLTLogError, "AliHLTOUT::New", "HLTOUT handling", "type cast to AliHLTOUT instance failed");
503 }
504 } else {
505 log.Logging(kHLTLogError, "AliHLTOUT::New", "HLTOUT handling", "can not create AliHLTOUT instance from class descriptor");
506 }
507 } else {
508 log.Logging(kHLTLogError, "AliHLTOUT::New", "HLTOUT handling", "can not find AliHLTOUT class descriptor");
509 }
510 } else {
511 log.Logging(kHLTLogError, "AliHLTOUT::New", "HLTOUT handling", "can not load libHLTrec library");
512 }
513 return instance;
514}
515
516void AliHLTOUT::Delete(AliHLTOUT* pInstance)
517{
518 // see header file for class documentation
519 if (!pInstance) return;
520
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) {
526 AliHLTLogging log;
527 log.Logging(kHLTLogError, "AliHLTOUT::Delete", "HLTOUT handling", "potential memory leak: libHLTrec library not available, skipping destruction %p", pInstance);
528 return;
529 }
530
531 delete pInstance;
532}
533
534void AliHLTOUT::SetParam(AliRawReader* /*pRawReader*/)
535{
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.
541 assert(0);
542 HLTFatal("severe internal error: class mismatch");
543}
544
545void AliHLTOUT::SetParam(TTree* /*pDigitTree*/, int /*event*/)
546{
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.
552 assert(0);
553 HLTFatal("severe internal error: class mismatch");
554}