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