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