]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTOUT.cxx
bugfix: correct range of DDL for specified detector
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTOUT.cxx
CommitLineData
62bb3cd4 1// $Id$
2
0f1882a7 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//**************************************************************************
62bb3cd4 18
4c4b4801 19/// @file AliHLTOUT.cxx
20/// @author Matthias Richter
21/// @date
22/// @brief The control class for HLTOUT data.
23///
62bb3cd4 24
4de7334f 25#include <cerrno>
5db0e774 26#include <cassert>
62bb3cd4 27#include "AliHLTOUT.h"
e5701dcf 28#include "AliHLTMessage.h"
466d4e62 29#include "AliHLTMisc.h"
c1292031 30#include "TSystem.h"
31#include "TClass.h"
32#include "TROOT.h"
4c4b4801 33#include <sstream>
34#include <iomanip>
35using namespace std;
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),
0f1882a7 45 fFlags(kSkipProcessed),
4de7334f 46 fBlockDescList(),
0f1882a7 47 fCurrent(0),
5db0e774 48 fpBuffer(NULL),
44dc7683 49 fDataHandlers(),
4c4b4801 50 fbVerbose(false),
b005ef92 51 fLog()
e5701dcf 52 , fpDataObject(NULL)
53 , fpObjectBuffer(NULL)
54 , fObjectBufferSize(0)
c63e8be4 55 , fCurrentEventId(kAliHLTVoidEventID)
4de7334f 56{
dba50a38 57 // constructor
58 //
59 // The control class for HLTOUT data
62bb3cd4 60 // see header file for class documentation
dba50a38 61 // author Matthias Richter
62bb3cd4 62}
63
64AliHLTOUT::~AliHLTOUT()
4de7334f 65{
dba50a38 66 // destructor
0f1882a7 67 if (CheckStatusFlag(kIsSubCollection)) {
b005ef92 68 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "~AliHLTOUT" , __FILE__ , __LINE__ , "severe internal error: collection has not been released, potential crash due to invalid pointer");
0f1882a7 69 }
e5701dcf 70
71 if (fpDataObject) {
72 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "data object has not been released, potential memory leak");
73 }
74 fpDataObject=NULL;
4de7334f 75}
b005ef92 76AliHLTOUT* AliHLTOUT::fgGlobalInstance=NULL;
4de7334f 77
5db0e774 78int AliHLTOUT::Init()
79{
80 // see header file for class documentation
81 int iResult=0;
f3c1d403 82
83 // ignore if already initialized
84 if (fBlockDescList.size()>0) {
f3c1d403 85 return 0;
86 }
87
18b56222 88 SetStatusFlag(kCollecting);
5db0e774 89 if ((iResult=GenerateIndex())>=0) {
90 if ((iResult=InitHandlers())>=0) {
91 }
92 }
18b56222 93 ClearStatusFlag(kCollecting);
5db0e774 94 return iResult;
95}
96
4de7334f 97int AliHLTOUT::GetNofDataBlocks()
98{
dba50a38 99 // get number of data blocks
4de7334f 100 return fBlockDescList.size();
101}
102
5db0e774 103int AliHLTOUT::SelectFirstDataBlock(AliHLTComponentDataType dt, AliHLTUInt32_t spec,
0f1882a7 104 AliHLTModuleAgent::AliHLTOUTHandlerType handlerType,
105 bool skipProcessed)
4de7334f 106{
dba50a38 107 // select the first data block according to data type, specification and
108 // handler type
0f1882a7 109 fCurrent=0;
4de7334f 110 fSearchDataType=dt;
111 fSearchSpecification=spec;
44dc7683 112 fSearchHandlerType=handlerType;
0f1882a7 113 if (skipProcessed) SetStatusFlag(kSkipProcessed);
114 else ClearStatusFlag(kSkipProcessed);
049b43b2 115 return FindAndSelectDataBlock();
4de7334f 116}
117
118int AliHLTOUT::SelectNextDataBlock()
119{
dba50a38 120 // select next data block according to selection criteria specified
121 // for SelectFirstDataBlock
0f1882a7 122 if (fCurrent>=fBlockDescList.size()) return -ENOENT;
049b43b2 123 fCurrent++;
124 return FindAndSelectDataBlock();
125}
126
127int AliHLTOUT::FindAndSelectDataBlock()
128{
dba50a38 129 // Select data block according to data type and specification, internal function
130 // invoked by SelectFirstDataBlock/SelectNextDataBlock
049b43b2 131 if (CheckStatusFlag(kLocked)) return -EPERM;
4de7334f 132 int iResult=-ENOENT;
0f1882a7 133 while (fCurrent<fBlockDescList.size() && iResult==-ENOENT) {
134 if (fBlockDescList[fCurrent]==fSearchDataType &&
135 (fSearchSpecification==kAliHLTVoidDataSpec || fBlockDescList[fCurrent]==fSearchSpecification) &&
512302d3 136 (fSearchHandlerType==AliHLTModuleAgent::kUnknownOutput || FindHandlerDesc(fCurrent)==fSearchHandlerType) &&
0f1882a7 137 (!CheckStatusFlag(kBlockSelection) || fBlockDescList[fCurrent].IsSelected()) &&
138 (!CheckStatusFlag(kSkipProcessed) || !fBlockDescList[fCurrent].IsProcessed())) {
139 iResult=fBlockDescList[fCurrent].GetIndex();
049b43b2 140 // TODO: check the byte order on the current system and the byte order of the
c5123824 141 // data block, print warning when mismatch and user did not check
13398559 142 //AliHLTOUTByteOrder blockBO=CheckByteOrder();
06f53caf 143 CheckByteOrder();
049b43b2 144 /*
145 if (blockBO!=fByteOrder) {
146 SetStatusFlag(kByteOrderWarning);
147
148 }
149 */
150 ClearStatusFlag(kByteOrderChecked);
151
152 // TODO: check the alignment on the current system and the alignment of the
c5123824 153 // data block, print warning when mismatch and user did not check
049b43b2 154 ClearStatusFlag(kAlignmentChecked);
18b56222 155
156 break;
4de7334f 157 }
049b43b2 158 fCurrent++;
4de7334f 159 }
160 return iResult;
161}
162
163int AliHLTOUT::GetDataBlockDescription(AliHLTComponentDataType& dt, AliHLTUInt32_t& spec)
164{
dba50a38 165 // fill data type and specification
4de7334f 166 int iResult=-ENOENT;
0f1882a7 167 if (fCurrent<fBlockDescList.size()) {
4de7334f 168 iResult=0;
0f1882a7 169 dt=fBlockDescList[fCurrent];
170 spec=fBlockDescList[fCurrent];
4de7334f 171 }
172 return iResult;
173}
174
c5123824 175const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::GetDataBlockHandlerDesc()
176{
dba50a38 177 // Get handler descriptor of the selected data block.
512302d3 178 return FindHandlerDesc(fCurrent);
c5123824 179}
180
181AliHLTModuleAgent::AliHLTOUTHandlerType AliHLTOUT::GetDataBlockHandlerType()
182{
dba50a38 183 // Get handler type of the selected data block.
512302d3 184 AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=FindHandlerDesc(fCurrent);
c5123824 185 AliHLTModuleAgent::AliHLTOUTHandlerType type=desc;
186 return type;
187}
188
5db0e774 189AliHLTUInt32_t AliHLTOUT::GetDataBlockIndex()
190{
dba50a38 191 // Get the index of the current data block.
0f1882a7 192 if (fCurrent>=fBlockDescList.size()) return AliHLTOUTInvalidIndex;
193 return fBlockDescList[fCurrent].GetIndex();
5db0e774 194}
195
dba50a38 196int AliHLTOUT::GetDataBuffer(AliHLTComponentBlockData& desc)
197{
198 // fill block data descriptor and select the current data buffer
199 // buffer has to be released using ReleaseDataBuffer
200 int iResult=-ENOENT;
201 if (fCurrent<fBlockDescList.size()) {
202 AliHLTComponent::FillBlockData(desc);
203 if ((iResult=fBlockDescList[fCurrent].GetDataBuffer(fpBuffer, desc.fSize))>=0) {
204 desc.fPtr=const_cast<void*>(reinterpret_cast<const void*>(fpBuffer));
205 desc.fDataType=fBlockDescList[fCurrent];
206 desc.fSpecification=fBlockDescList[fCurrent];
207 }
208 }
209 return iResult;
210}
211
4de7334f 212int AliHLTOUT::GetDataBuffer(const AliHLTUInt8_t* &pBuffer, AliHLTUInt32_t& size)
213{
dba50a38 214 // select and return the current data buffer
215 // buffer has to be released using ReleaseDataBuffer
4de7334f 216 int iResult=-ENOENT;
217 pBuffer=NULL;
218 size=0;
0f1882a7 219 if (fCurrent<fBlockDescList.size()) {
dba50a38 220 if ((iResult=fBlockDescList[fCurrent].GetDataBuffer(fpBuffer, size))>=0) {
221 pBuffer=fpBuffer;
4de7334f 222 }
223 }
224 return iResult;
225}
226
227int AliHLTOUT::ReleaseDataBuffer(const AliHLTUInt8_t* pBuffer)
228{
dba50a38 229 // release data buffer, previously returned by GetDataBuffer
4de7334f 230 int iResult=0;
231 if (pBuffer==fpBuffer) {
232 fpBuffer=NULL;
233 } else {
b005ef92 234 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "ReleaseDataBuffer" , __FILE__ , __LINE__ , "buffer %p does not match the provided one %p", pBuffer, fpBuffer);
4de7334f 235 }
236 return iResult;
237}
238
c5123824 239AliHLTModuleAgent* AliHLTOUT::GetAgent()
240{
dba50a38 241 // get module agent of the selected data block
c5123824 242 AliHLTModuleAgent* pAgent=NULL;
512302d3 243 pAgent=FindHandlerDesc(fCurrent);
c5123824 244 return pAgent;
245}
246
626bfcc1 247AliHLTOUTHandler* AliHLTOUT::GetHandler()
248{
dba50a38 249 // get HLTOUT handler of the selected data block
626bfcc1 250 AliHLTOUTHandler* pHandler=NULL;
512302d3 251 pHandler=FindHandlerDesc(fCurrent);
626bfcc1 252 return pHandler;
253}
254
c5123824 255int AliHLTOUT::WriteESD(const AliHLTUInt8_t* /*pBuffer*/, AliHLTUInt32_t /*size*/, AliHLTComponentDataType /*dt*/, AliESDEvent* /*tgtesd*/) const
256{
dba50a38 257 // default function, child must overload
b005ef92 258 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "WriteESD" , __FILE__ , __LINE__ , "method not implemented in base class");
c5123824 259 return -ENOSYS;
260}
261
4de7334f 262int AliHLTOUT::AddBlockDescriptor(const AliHLTOUTBlockDescriptor desc)
263{
dba50a38 264 // add new block descriptor
049b43b2 265 if (!CheckStatusFlag(kCollecting)) return -EPERM;
4de7334f 266 int iResult=0;
267 fBlockDescList.push_back(desc);
268 return iResult;
62bb3cd4 269}
049b43b2 270
13398559 271AliHLTOUT::AliHLTOUTByteOrder AliHLTOUT::CheckByteOrder()
049b43b2 272{
dba50a38 273 // check the byte order of the current data block
274 // NOTE: this functionality has not been tested and development was hardly finished
0f1882a7 275 if (fCurrent<fBlockDescList.size()) {
049b43b2 276 SetStatusFlag(kByteOrderChecked);
0f1882a7 277 AliHLTOUT::AliHLTOUTByteOrder order=CheckBlockByteOrder(fBlockDescList[fCurrent].GetIndex());
049b43b2 278 return order;
279 }
280 return kInvalidByteOrder;
281}
282
13398559 283int AliHLTOUT::CheckAlignment(AliHLTOUT::AliHLTOUTDataType type)
049b43b2 284{
dba50a38 285 // check alignment of the current data block
286 // NOTE: this functionality has not been tested and development was hardly finished
0f1882a7 287 if (fCurrent<fBlockDescList.size()) {
049b43b2 288 SetStatusFlag(kAlignmentChecked);
0f1882a7 289 int alignment=CheckBlockAlignment(fBlockDescList[fCurrent].GetIndex(), type);
049b43b2 290 return alignment;
291 }
292 return -ENOENT;
293}
5db0e774 294
295int AliHLTOUT::InitHandlers()
296{
dba50a38 297 // init handlers for all registered blocks
5db0e774 298 int iResult=0;
299 AliHLTOUTIndexList remnants;
44dc7683 300 int iCount=0;
a3ef3c1d 301 for (int havedata=SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec); havedata>=0; havedata=SelectNextDataBlock()) {
44dc7683 302 iCount++;
5db0e774 303 remnants.push_back(GetDataBlockIndex());
304 AliHLTComponentDataType dt=kAliHLTVoidDataType;
305 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
e94eb049 306 if (GetDataBlockDescription(dt, spec)<0) break;
f94e8c27 307 bool bHaveHandler=false;
5db0e774 308 for (AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent(); pAgent && iResult>=0; pAgent=AliHLTModuleAgent::GetNextAgent()) {
309 AliHLTModuleAgent::AliHLTOUTHandlerDesc handlerDesc;
626bfcc1 310 if (pAgent->GetHandlerDescription(dt, spec, handlerDesc)>0) {
5db0e774 311 AliHLTOUTHandlerListEntry entry(pAgent->GetOutputHandler(dt, spec), handlerDesc, pAgent, GetDataBlockIndex());
c5123824 312 InsertHandler(fDataHandlers, entry);
5db0e774 313 remnants.pop_back();
f94e8c27 314 bHaveHandler=true;
4c4b4801 315 if (fbVerbose) {
316 stringstream sout;
317 sout << "adding handler for block " << AliHLTComponent::DataType2Text(dt).c_str()
318 << " 0x" << setfill('0') << setw(8) << hex << spec;
319 cout << sout.str() << endl;
320 }
5db0e774 321 break;
322 }
323 }
f94e8c27 324 if (!bHaveHandler && (dt==kAliHLTDataTypeESDObject || dt==kAliHLTDataTypeESDTree)) {
325 // ESDs are handled by the framework
326 remnants.pop_back();
327 }
5db0e774 328 }
44dc7683 329
330 // warning if some of the data blocks are not selected by the kAliHLTAnyDataType
331 // criterion
332 if (GetNofDataBlocks()>iCount) {
b005ef92 333 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "InitHandlers" , __FILE__ , __LINE__ , "incomplete data type in %d out of %d data block(s)", GetNofDataBlocks()-iCount, GetNofDataBlocks());
44dc7683 334 }
335
336 // warning if handler not found
5db0e774 337 if (remnants.size()>0) {
b005ef92 338 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "InitHandlers" , __FILE__ , __LINE__ , "no handlers found for %d data blocks out of %d", remnants.size(), iCount);
13398559 339 AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
8decd484 340 for (AliHLTOUTIndexList::iterator element=remnants.begin();
341 element!=remnants.end() && block!=fBlockDescList.end();
342 element++) {
5db0e774 343 for (int trials=0; trials<2; trials++) {
344 do {
345 // we start searching the index from the current position in the block list
346 if ((*block).GetIndex()==*element) break;
347 } while ((++block)!=fBlockDescList.end());
348 if (block==fBlockDescList.end()) {
349 // rewind and try again
350 block=fBlockDescList.begin();
351 }
352 }
353 assert(block!=fBlockDescList.end());
5db0e774 354 }
355 }
4c4b4801 356
357 if (fbVerbose) Print();
358
5db0e774 359 return iResult;
360}
361
c5123824 362int AliHLTOUT::InsertHandler(AliHLTOUTHandlerListEntryVector& list, const AliHLTOUTHandlerListEntry &entry)
5db0e774 363{
dba50a38 364 // insert handler into list, called from child implementations
5db0e774 365 int iResult=0;
c5123824 366 AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
b005ef92 367 for (; element!=list.end();
368 element++) {
5db0e774 369 if (entry==(*element)) break;
5db0e774 370 }
c5123824 371 if (element==list.end()) {
372 list.push_back(entry);
5db0e774 373 } else {
a3ef3c1d 374 element->AddIndex(const_cast<AliHLTOUTHandlerListEntry&>(entry));
5db0e774 375 }
376 return iResult;
377}
378
b005ef92 379int AliHLTOUT::FillHandlerList(AliHLTOUTHandlerListEntryVector& list, AliHLTModuleAgent::AliHLTOUTHandlerType handlerType)
380{
dba50a38 381 // fill a list according to specified handler type
b005ef92 382 int iResult=0;
383 for (iResult=SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec, handlerType);
384 iResult>=0;
385 iResult=SelectNextDataBlock()) {
386 AliHLTComponentDataType dt=kAliHLTVoidDataType;
387 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
388 GetDataBlockDescription(dt, spec);
389 AliHLTOUTHandler* pHandler=GetHandler();
390 if (!pHandler) {
391 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "FillHandlerList" , __FILE__ , __LINE__ ,
392 "missing HLTOUT handler for block of type kChain: agent %s, data type %s, specification %#x, ... skipping data block",
393 GetAgent()?GetAgent()->GetModuleId():"invalid",
394 AliHLTComponent::DataType2Text(dt).c_str(), spec);
395 } else {
396 InsertHandler(list, GetDataBlockHandlerDesc());
397 }
398 }
399 // TODO: the return value of SelectFirst/NextDataBlock must be
400 // changed in order to avoid this check
401 if (iResult==-ENOENT) iResult=0;
402
403 return iResult;
404}
405
406int AliHLTOUT::RemoveEmptyDuplicateHandlers(AliHLTOUTHandlerListEntryVector& list)
407{
dba50a38 408 // remove empty handlers from list
b005ef92 409 int iResult=0;
410 AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
411 while (element!=list.end()) {
412 if (element->IsEmpty()) {
413 AliHLTOUTHandler* pHandler=*element;
414 AliHLTModuleAgent* pAgent=*element;
415 AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=*element;
416 if (FindHandler(list, desc)>=0) {
417 element=list.erase(element);
418 if (pAgent) {
419 pAgent->DeleteOutputHandler(pHandler);
420 }
421 // we are already at the next element
422 continue;
423 }
424 }
425 element++;
426 }
427 return iResult;
428}
429
430int AliHLTOUT::FindHandler(AliHLTOUTHandlerListEntryVector& list, const AliHLTModuleAgent::AliHLTOUTHandlerDesc desc)
431{
dba50a38 432 // find handler according to descriptor
b005ef92 433 for (int i=0; i<(int)list.size(); i++) {
434 if (list[i]==desc) return i;
435 }
436 return -ENOENT;
437}
438
439int AliHLTOUT::InvalidateBlocks(AliHLTOUTHandlerListEntryVector& list)
440{
dba50a38 441 // invalidate all handlers in a list
b005ef92 442 for (AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
443 element!=list.end();
444 element++) {
445 element->InvalidateBlocks();
446 }
447 return 0;
448}
449
44dc7683 450const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::FindHandlerDesc(AliHLTUInt32_t blockIndex)
626bfcc1 451{
dba50a38 452 // get handler description
f3c1d403 453 if (blockIndex<fBlockDescList.size()) {
454 return fBlockDescList[blockIndex].GetHandlerDesc();
626bfcc1 455 }
44dc7683 456 return const_cast<AliHLTOUT::AliHLTOUTHandlerListEntry&>(AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry);
626bfcc1 457}
458
459AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry()
460 :
461 fpHandler(NULL),
462 fpHandlerDesc(NULL),
463 fpAgent(NULL),
464 fBlocks()
465{
dba50a38 466 // default constructor
626bfcc1 467}
468
5db0e774 469AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(AliHLTOUTHandler* pHandler,
470 AliHLTModuleAgent::AliHLTOUTHandlerDesc& handlerDesc,
471 AliHLTModuleAgent* pAgent,
472 AliHLTUInt32_t index)
473 :
474 fpHandler(pHandler),
626bfcc1 475 fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
5db0e774 476 fpAgent(pAgent),
477 fBlocks()
478{
dba50a38 479 // constructor
626bfcc1 480 *fpHandlerDesc=handlerDesc;
5db0e774 481 fBlocks.push_back(index);
482}
483
484AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(const AliHLTOUTHandlerListEntry& src)
485 :
486 fpHandler(src.fpHandler),
626bfcc1 487 fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
5db0e774 488 fpAgent(src.fpAgent),
489 fBlocks()
490{
dba50a38 491 // copy constructor
626bfcc1 492 *fpHandlerDesc=*src.fpHandlerDesc;
5db0e774 493 fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
494}
495
fb24bec7 496AliHLTOUT::AliHLTOUTHandlerListEntry::~AliHLTOUTHandlerListEntry()
497{
dba50a38 498 // destructor
626bfcc1 499 if (fpHandlerDesc) delete fpHandlerDesc;
500 fpHandlerDesc=NULL;
fb24bec7 501}
502
5db0e774 503AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::AliHLTOUTHandlerListEntry::operator=(const AliHLTOUTHandlerListEntry& src)
504{
dba50a38 505 // assignment operator
b5ccc144 506 if (this==&src) return *this;
5db0e774 507 fpHandler=src.fpHandler;
44dc7683 508 if (src.fpHandlerDesc)
509 *fpHandlerDesc=*src.fpHandlerDesc;
5db0e774 510 fpAgent=src.fpAgent;
511 fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
512 return *this;
513}
514
18b56222 515AliHLTUInt32_t AliHLTOUT::AliHLTOUTHandlerListEntry::operator[](int i) const
516{
dba50a38 517 // access operator
b0914d2e 518 return (int)fBlocks.size()>i?fBlocks[i]:AliHLTOUTInvalidIndex;
5db0e774 519}
520
fb24bec7 521bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTOUTHandlerListEntry& entry) const
522{
dba50a38 523 // comparison operator
a3ef3c1d 524 if (entry.fpHandler!=fpHandler || fpHandler==NULL) return false;
525 assert(entry.fpAgent==fpAgent);
526 if (entry.fpAgent!=fpAgent) return false;
527 return true;
528}
529
44dc7683 530bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTModuleAgent::AliHLTOUTHandlerType handlerType) const
531{
dba50a38 532 // comparison operator
44dc7683 533 if (!fpHandlerDesc) return false;
534 return *fpHandlerDesc==handlerType;
535}
536
b005ef92 537bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTModuleAgent::AliHLTOUTHandlerDesc desc) const
538{
dba50a38 539 // comparison operator
b005ef92 540 if (!fpHandlerDesc) return false;
541 return *fpHandlerDesc==desc;
542}
543
a3ef3c1d 544void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTOUT::AliHLTOUTHandlerListEntry &desc)
545{
dba50a38 546 // add block index, a handler can serve multiple blocks
a3ef3c1d 547 AliHLTOUTIndexList::iterator element;
548 for (element=desc.fBlocks.begin(); element!=desc.fBlocks.end(); element++) {
549 AddIndex(*element);
550 }
fb24bec7 551}
552
18b56222 553void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTUInt32_t index)
554{
dba50a38 555 // add block index, a handler can serve multiple blocks
5db0e774 556 fBlocks.push_back(index);
557}
626bfcc1 558
0f1882a7 559bool AliHLTOUT::AliHLTOUTHandlerListEntry::HasIndex(AliHLTUInt32_t index) const
200853e2 560{
dba50a38 561 // check if handler serves the specified block
a3ef3c1d 562 AliHLTOUTIndexList::iterator element;
0f1882a7 563 for (unsigned int i=0; i<fBlocks.size(); i++) {
564 if (fBlocks[i]==index) return true;
a3ef3c1d 565 }
200853e2 566 return false;
567}
568
626bfcc1 569const AliHLTOUT::AliHLTOUTHandlerListEntry AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry;
44dc7683 570
ff3b6fed 571AliHLTUInt64_t AliHLTOUT::ByteSwap64(AliHLTUInt64_t src)
44dc7683 572{
dba50a38 573 // swap a 64 bit number
44dc7683 574 return ((src & 0xFFULL) << 56) |
575 ((src & 0xFF00ULL) << 40) |
576 ((src & 0xFF0000ULL) << 24) |
577 ((src & 0xFF000000ULL) << 8) |
578 ((src & 0xFF00000000ULL) >> 8) |
579 ((src & 0xFF0000000000ULL) >> 24) |
580 ((src & 0xFF000000000000ULL) >> 40) |
581 ((src & 0xFF00000000000000ULL) >> 56);
582}
583
ff3b6fed 584AliHLTUInt32_t AliHLTOUT::ByteSwap32(AliHLTUInt32_t src)
44dc7683 585{
dba50a38 586 // swap a 32 bit number
44dc7683 587 return ((src & 0xFFULL) << 24) |
588 ((src & 0xFF00ULL) << 8) |
589 ((src & 0xFF0000ULL) >> 8) |
590 ((src & 0xFF000000ULL) >> 24);
591}
c1292031 592
593AliHLTOUT* AliHLTOUT::New(AliRawReader* pRawReader)
594{
dba50a38 595 // transparently create HLTOUT implementation for AliRawReader
466d4e62 596 AliHLTOUT* instance=AliHLTMisc::LoadInstance((AliHLTOUT*)0, "AliHLTOUTRawReader", "libHLTrec.so");
c1292031 597 if (instance) {
598 instance->SetParam(pRawReader);
599 }
600 return instance;
601}
602
603AliHLTOUT* AliHLTOUT::New(TTree* pDigitTree, int event)
604{
dba50a38 605 // transparently create HLTOUT implementation for digit tree
466d4e62 606 AliHLTOUT* instance=AliHLTMisc::LoadInstance((AliHLTOUT*)0, "AliHLTOUTDigitReader", "libHLTrec.so");
c1292031 607 if (instance) {
608 instance->SetParam(pDigitTree, event);
609 }
610 return instance;
611}
612
466d4e62 613AliHLTOUT* AliHLTOUT::New(const char* filename, int event)
614{
dba50a38 615 // transparently create HLTOUT implementation for raw file
466d4e62 616 AliHLTOUT* instance=AliHLTMisc::LoadInstance((AliHLTOUT*)0, "AliHLTOUTDigitReader", "libHLTrec.so");
617 if (instance) {
618 instance->SetParam(filename, event);
c1292031 619 }
620 return instance;
621}
622
623void AliHLTOUT::Delete(AliHLTOUT* pInstance)
624{
dba50a38 625 // delete the HLTOUT instance
626 // check if the library is still there in order to have the
627 // destructor available
628
c1292031 629 if (!pInstance) return;
b005ef92 630 if (pInstance==fgGlobalInstance) return;
c1292031 631
c1292031 632 TClass* pCl1=TClass::GetClass("AliHLTOUTRawReader");
633 TClass* pCl2=TClass::GetClass("AliHLTOUTDigitReader");
634 if (!pCl1 && !pCl2) {
635 AliHLTLogging log;
636 log.Logging(kHLTLogError, "AliHLTOUT::Delete", "HLTOUT handling", "potential memory leak: libHLTrec library not available, skipping destruction %p", pInstance);
637 return;
638 }
639
640 delete pInstance;
641}
642
643void AliHLTOUT::SetParam(AliRawReader* /*pRawReader*/)
644{
645 // see header file for class documentation
646 // default implementation, we should never get here
647 // this function can only be called from the class itsself and
648 // is intended to be used with the New functions. If we get into
649 // the default implementation there is a class mismatch.
650 assert(0);
b005ef92 651 fLog.LoggingVarargs(kHLTLogFatal, "AliHLTOUT", "SetParam" , __FILE__ , __LINE__ , "severe internal error: class mismatch");
c1292031 652}
653
654void AliHLTOUT::SetParam(TTree* /*pDigitTree*/, int /*event*/)
655{
656 // see header file for class documentation
657 // default implementation, we should never get here
658 // this function can only be called from the class itsself and
659 // is intended to be used with the New functions. If we get into
660 // the default implementation there is a class mismatch.
661 assert(0);
b005ef92 662 fLog.LoggingVarargs(kHLTLogFatal, "AliHLTOUT", "SetParam" , __FILE__ , __LINE__ , "severe internal error: class mismatch");
c1292031 663}
0f1882a7 664
466d4e62 665void AliHLTOUT::SetParam(const char* /*filename*/, int /*event*/)
666{
667 // see header file for class documentation
668 // default implementation, we should never get here
669 // this function can only be called from the class itsself and
670 // is intended to be used with the New functions. If we get into
671 // the default implementation there is a class mismatch.
672 assert(0);
673 fLog.LoggingVarargs(kHLTLogFatal, "AliHLTOUT", "SetParam" , __FILE__ , __LINE__ , "severe internal error: class mismatch");
674}
675
0f1882a7 676int AliHLTOUT::SelectDataBlock()
677{
dba50a38 678 // mark the current data block for processing
0f1882a7 679 int iResult=0;
680 if (fCurrent>=fBlockDescList.size()) return 0;
681 fBlockDescList[fCurrent].Select(true);
682 EnableBlockSelection();
683 return iResult;
684}
685
e13512e4 686int AliHLTOUT::SelectDataBlocks(const AliHLTOUTHandlerListEntry* pHandlerEntry)
0f1882a7 687{
dba50a38 688 // mark all data blocks served by specified handler for processing
0f1882a7 689 int iResult=0;
e13512e4 690 if (!pHandlerEntry) return 0;
0f1882a7 691
e13512e4 692 AliHLTModuleAgent* pAgent=*pHandlerEntry;
693 AliHLTLogging log;
694 log.Logging(kHLTLogDebug, "AliHLTOUT::SelectDataBlocks", "HLTOUT handling", "selecting blocks for handler %s", pAgent->GetModuleId());
0f1882a7 695 AliHLTOUTBlockDescriptorVector::iterator element;
696 for (AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
697 block!=fBlockDescList.end();
698 block++) {
e13512e4 699 if (block->GetHandlerDesc()==*pHandlerEntry && pHandlerEntry->HasIndex(block->GetIndex())) {
0f1882a7 700 block->Select(true);
e13512e4 701 log.Logging(kHLTLogDebug, "AliHLTOUT::SelectDataBlocks", "HLTOUT handling", " select block %s", AliHLTComponent::DataType2Text(*block).c_str());
702 } else {
703 log.Logging(kHLTLogDebug, "AliHLTOUT::SelectDataBlocks", "HLTOUT handling", " skip block %s", AliHLTComponent::DataType2Text(*block).c_str());
0f1882a7 704 block->Select(false);
e13512e4 705 }
0f1882a7 706 }
707 EnableBlockSelection();
e13512e4 708
709 // Matthias 2009-07-03 bugfix: the fCurrent position was not reset at that
710 // place. Also I think the data type and specification must be set in order
711 // to make SelectFirst/NextDataBlock working on the selected collection
712 // of data blocks
713 AliHLTModuleAgent::AliHLTOUTHandlerDesc pHandlerDesc=*pHandlerEntry;
714 fSearchDataType=pHandlerDesc;
715 fSearchSpecification=kAliHLTVoidDataSpec;
716 fSearchHandlerType=pHandlerDesc;
717 fCurrent=0;
0f1882a7 718
719 return iResult;
720}
721
722int AliHLTOUT::EnableBlockSelection()
723{
dba50a38 724 // enable block selection, in this mode only the blocks marked for
725 // processing can be accessed
0f1882a7 726 SetStatusFlag(kBlockSelection);
727 return 0;
728}
729
730int AliHLTOUT::DisableBlockSelection()
731{
dba50a38 732 // disable block selection
0f1882a7 733 ClearStatusFlag(kBlockSelection);
734 return 0;
735}
736
737int AliHLTOUT::ResetBlockSelection()
738{
dba50a38 739 // reset the 'selected' flag for all blocks
0f1882a7 740 for (AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
741 block!=fBlockDescList.end();
742 block++) {
743 block->Select(false);
744 }
745 return 0;
746}
747
748int AliHLTOUT::MarkDataBlockProcessed()
749{
dba50a38 750 // mark the current data block as 'processed'
0f1882a7 751 int iResult=0;
752 if (fCurrent>=fBlockDescList.size()) return 0;
753 fBlockDescList[fCurrent].MarkProcessed();
754 return iResult;
755}
756
757int AliHLTOUT::MarkDataBlocksProcessed(const AliHLTOUTHandlerListEntry* pHandlerDesc)
758{
dba50a38 759 // mark all data blocks served by handler as processed
0f1882a7 760 int iResult=0;
761 if (!pHandlerDesc) return 0;
762
763 AliHLTOUTBlockDescriptorVector::iterator element;
764 for (AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
765 block!=fBlockDescList.end();
766 block++) {
f3c1d403 767 if (block->GetHandlerDesc()==*pHandlerDesc && pHandlerDesc->HasIndex(block->GetIndex()))
0f1882a7 768 block->MarkProcessed();
769 }
770
771 return iResult;
772}
773
774int AliHLTOUT::AddSubCollection(AliHLTOUT* pCollection)
775{
dba50a38 776 // add a sub-collection to the HLTOUT instance
777 // all blocks of the sub-collection are accessed transparently through the master instance
0f1882a7 778 int iResult=0;
779 if (!pCollection) return 0;
780
d4a18597 781 SetStatusFlag(kCollecting);
0f1882a7 782 int index=-1;
783 for (index=pCollection->SelectFirstDataBlock();
784 index>=0;
785 index=pCollection->SelectNextDataBlock()) {
786 AliHLTComponentDataType dt=kAliHLTVoidDataType;
787 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
788 pCollection->GetDataBlockDescription(dt, spec);
789 AliHLTOUTBlockDescriptor desc(dt, spec, index, pCollection);
790 AddBlockDescriptor(desc);
791 iResult++;
792 }
793 if (iResult>0) {
4562bf66 794 if (CheckStatusFlag(kIsSubCollection)) {
795 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "AddSubCollection" , __FILE__ , __LINE__ , "HLTOUT object %p has already been added as sub-collection", pCollection);
796 } else {
797 pCollection->SetStatusFlag(kIsSubCollection);
798 }
0f1882a7 799 }
d4a18597 800 ClearStatusFlag(kCollecting);
0f1882a7 801
802 return iResult;
803}
804
805int AliHLTOUT::ReleaseSubCollection(AliHLTOUT* pCollection)
806{
dba50a38 807 // release a sub-collection
0f1882a7 808 int iResult=0;
809 if (!pCollection) return 0;
810
b005ef92 811 AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
812 while (block!=fBlockDescList.end()) {
0f1882a7 813 if ((*block)==pCollection) {
b005ef92 814 block=fBlockDescList.erase(block);
815 continue;
0f1882a7 816 }
b005ef92 817 block++;
0f1882a7 818 }
4562bf66 819 pCollection->ClearStatusFlag(kIsSubCollection);
0f1882a7 820
821 return iResult;
822}
b005ef92 823
824int AliHLTOUT::Reset()
825{
dba50a38 826 // reset HLTOUT instance
827 // clears all blocks and handler descriptions
b005ef92 828 int iResult=0;
829 AliHLTOUTPVector subCollections;
830 AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
831 while (block!=fBlockDescList.end()) {
d4a18597 832 if (!((*block)==this)) {
b005ef92 833 AliHLTOUTPVector::iterator collection=subCollections.begin();
834 for (; collection!=subCollections.end(); collection++)
835 if((*block)==*collection) break;
836 if (collection==subCollections.end())
837 subCollections.push_back(block->GetCollection());
838 }
839 block=fBlockDescList.erase(block);
840 }
841
842 for (AliHLTOUTPVector::iterator collection=subCollections.begin();
4562bf66 843 collection!=subCollections.end(); collection++) {
b005ef92 844 (*collection)->Reset();
4562bf66 845 (*collection)->ClearStatusFlag(kIsSubCollection);
846 }
b005ef92 847
848 ResetInput();
c63e8be4 849 fCurrentEventId=kAliHLTVoidEventID;
b005ef92 850
851 return iResult;
852}
853
854int AliHLTOUT::ResetInput()
855{
856 // default implementation, nothing to do
857 return 0;
858}
f3c1d403 859
860const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::AliHLTOUTBlockDescriptor::GetHandlerDesc()
861{
862 // see header file for class documentation
863 if (fpCollection) {
864 AliHLTOUTHandlerListEntryVector::iterator element=fpCollection->fDataHandlers.begin();
865 while (element!=fpCollection->fDataHandlers.end()) {
866 if (element->HasIndex(GetIndex())) {
867 return *element;
868 }
869 element++;
870 }
871 }
872 return const_cast<AliHLTOUT::AliHLTOUTHandlerListEntry&>(AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry);
873}
e5701dcf 874
875TObject* AliHLTOUT::GetDataObject()
876{
dba50a38 877 // check if the current block encodes a ROOT object and expand it
e5701dcf 878 if (fpDataObject) {
879 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "data object has not been released, potential memory leak");
880 ReleaseDataBuffer(fpObjectBuffer);
881 }
882 fpObjectBuffer=NULL;
883 fObjectBufferSize=0;
884 fpDataObject=NULL;
885
886 if (GetDataBuffer(fpObjectBuffer, fObjectBufferSize)>=0) {
887 fpDataObject=AliHLTMessage::Extract(fpObjectBuffer, fObjectBufferSize);
888 } else {
889 fLog.LoggingVarargs(kHLTLogError, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "can not fetch data buffer");
890 }
891
892 return fpDataObject;
893}
894
895int AliHLTOUT::ReleaseDataObject(TObject* pObject)
896{
dba50a38 897 // release a ROOT object previously expanded from the currentr data block
e5701dcf 898 if (!pObject) return -EINVAL;
899 if (pObject!=fpDataObject) {
900 fLog.LoggingVarargs(kHLTLogError, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "attempt to release wrong data object %p, expected %p", pObject, fpDataObject);
901 return -EINVAL;
902 }
903
904 delete fpDataObject;
905 fpDataObject=NULL;
906 ReleaseDataBuffer(fpObjectBuffer);
907 fpObjectBuffer=NULL;
908 fObjectBufferSize=0;
909
910 return 0;
911}
c63e8be4 912
913void AliHLTOUT::SetEventId(AliHLTUInt64_t id)
914{
dba50a38 915 // set event id
c63e8be4 916 if (fCurrentEventId!=kAliHLTVoidEventID && fCurrentEventId!=id) {
917 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "SetEventId" , __FILE__ , __LINE__ , "event id was already set to 0x%llx, setting now to 0x%llx", fCurrentEventId, id);
918 }
919 fCurrentEventId=id;
920}
4c4b4801 921
922void AliHLTOUT::Print(const char* option) const
923{
924 // print info
925 {
926 for (AliHLTOUTBlockDescriptorVector::const_iterator i=fBlockDescList.begin();
927 i!=fBlockDescList.end(); i++)
928 i->Print(option);
929 }
930 {
931 for (AliHLTOUTHandlerListEntryVector::const_iterator i=fDataHandlers.begin();
932 i!=fDataHandlers.end(); i++)
933 i->Print(option);
934 }
935}
936
937void AliHLTOUT::AliHLTOUTBlockDescriptor::Print(const char* /*option*/) const
938{
939 // print info
940 stringstream sout;
941 sout << "AliHLTOUTBlockDescriptor index 0x" << setfill('0') << setw(8) << hex << right << fIndex
942 << ": " << AliHLTComponent::DataType2Text(fDataType).c_str()
943 << " 0x" << setfill('0') << setw(8) << hex << fSpecification
944 << " processed " << dec << fProcessed;
945 cout << sout.str() << endl;
946}
947
948void AliHLTOUT::AliHLTOUTHandlerListEntry::Print(const char* /*option*/) const
949{
950 // print info
951 stringstream sout;
952 AliHLTModuleAgent::AliHLTOUTHandlerType type=AliHLTModuleAgent::kUnknownOutput;
953 AliHLTComponentDataType dt=kAliHLTVoidDataType;
954 if (this->fpHandlerDesc) {
955 type=*(this->fpHandlerDesc);
956 dt=*(this->fpHandlerDesc);
957 }
958 const char* stype="";
959 switch(type) {
960 case AliHLTModuleAgent::kEsd: stype="ESD"; break;
961 case AliHLTModuleAgent::kRawReader: stype="RawReader"; break;
962 case AliHLTModuleAgent::kRawStream: stype="RawStream"; break;
963 case AliHLTModuleAgent::kChain: stype="Chain"; break;
964 case AliHLTModuleAgent::kProprietary: stype="Proprietary"; break;
965 default: stype="unknown";
966 }
967 sout << "HLTOUT handler: "
968 << " " << type << " (" << stype << ")"
969 << " " << AliHLTComponent::DataType2Text(dt).c_str();
970 cout << sout.str() << endl;
971}