]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTComponent.cxx
6e8796a2fc77240dc623b71ec694bf8530ad6d26
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTComponent.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 //*                  Timm Steinbeck <timm@kip.uni-heidelberg.de>           *
9 //*                  for The ALICE HLT Project.                            *
10 //*                                                                        *
11 //* Permission to use, copy, modify and distribute this software and its   *
12 //* documentation strictly for non-commercial purposes is hereby granted   *
13 //* without fee, provided that the above copyright notice appears in all   *
14 //* copies and that both the copyright notice and this permission notice   *
15 //* appear in the supporting documentation. The authors make no claims     *
16 //* about the suitability of this software for any purpose. It is          *
17 //* provided "as is" without express or implied warranty.                  *
18 //**************************************************************************
19
20 /** @file   AliHLTComponent.cxx
21     @author Matthias Richter, Timm Steinbeck
22     @date   
23     @brief  Base class implementation for HLT components. */
24
25 #if __GNUC__>= 3
26 using namespace std;
27 #endif
28
29 //#include "AliHLTStdIncludes.h"
30 #include "AliHLTComponent.h"
31 #include "AliHLTComponentHandler.h"
32 #include "AliHLTMessage.h"
33 #include "TString.h"
34 #include "TMath.h"
35 #include "TObjArray.h"
36 #include "TObjectTable.h"
37 #include "TClass.h"
38 #include "TStopwatch.h"
39 #include "AliHLTMemoryFile.h"
40 #include "AliHLTMisc.h"
41 #include <cassert>
42
43 /** ROOT macro for the implementation of ROOT specific class methods */
44 ClassImp(AliHLTComponent);
45
46 /** stopwatch macro using the stopwatch guard */
47 #define ALIHLTCOMPONENT_STOPWATCH(type) AliHLTStopwatchGuard swguard(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)type)):NULL)
48 //#define ALIHLTCOMPONENT_STOPWATCH(type) 
49
50 /** stopwatch macro for operations of the base class */
51 #define ALIHLTCOMPONENT_BASE_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWBase)
52 /** stopwatch macro for operations of the detector algorithm (DA) */
53 #define ALIHLTCOMPONENT_DA_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWDA)
54
55 AliHLTComponent::AliHLTComponent()
56   :
57   fEnvironment(),
58   fCurrentEvent(0),
59   fEventCount(-1),
60   fFailedEvents(0),
61   fCurrentEventData(),
62   fpInputBlocks(NULL),
63   fCurrentInputBlock(-1),
64   fSearchDataType(kAliHLTVoidDataType),
65   fClassName(),
66   fpInputObjects(NULL),
67   fpOutputBuffer(NULL),
68   fOutputBufferSize(0),
69   fOutputBufferFilled(0),
70   fOutputBlocks(),
71   fpStopwatches(new TObjArray(kSWTypeCount)),
72   fMemFiles(),
73   fpRunDesc(NULL),
74   fpDDLList(NULL),
75   fCDBSetRunNoFunc(false),
76   fChainId()
77 {
78   // see header file for class documentation
79   // or
80   // refer to README to build package
81   // or
82   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
83   memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
84   if (fgpComponentHandler)
85     fgpComponentHandler->ScheduleRegister(this);
86   //SetLocalLoggingLevel(kHLTLogDefault);
87 }
88
89 AliHLTComponent::~AliHLTComponent()
90 {
91   // see header file for function documentation
92   CleanupInputObjects();
93   if (fpStopwatches!=NULL) delete fpStopwatches;
94   fpStopwatches=NULL;
95   AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
96   while (element!=fMemFiles.end()) {
97     if (*element) {
98       if ((*element)->IsClosed()==0) {
99         HLTWarning("memory file has not been closed, possible data loss or incomplete buffer");
100         // close but do not flush as we dont know whether the buffer is still valid
101         (*element)->CloseMemoryFile(0);
102       }
103       delete *element;
104       *element=NULL;
105     }
106     element++;
107   }
108   if (fpRunDesc) {
109     delete fpRunDesc;
110     fpRunDesc=NULL;
111   }
112 }
113
114 AliHLTComponentHandler* AliHLTComponent::fgpComponentHandler=NULL;
115
116 int AliHLTComponent::SetGlobalComponentHandler(AliHLTComponentHandler* pCH, int bOverwrite) 
117 {
118   // see header file for function documentation
119   int iResult=0;
120   if (fgpComponentHandler==NULL || bOverwrite!=0)
121     fgpComponentHandler=pCH;
122   else
123     iResult=-EPERM;
124   return iResult;
125 }
126
127 int AliHLTComponent::UnsetGlobalComponentHandler() 
128 {
129   // see header file for function documentation
130   return SetGlobalComponentHandler(NULL,1);
131 }
132
133 int AliHLTComponent::Init( AliHLTComponentEnvironment* comenv, void* environParam, int argc, const char** argv )
134 {
135   // see header file for function documentation
136   HLTLogKeyword(GetComponentID());
137   int iResult=0;
138   if (comenv) {
139     memcpy(&fEnvironment, comenv, sizeof(AliHLTComponentEnvironment));
140     fEnvironment.fParam=environParam;
141   }
142   const char** pArguments=NULL;
143   int iNofChildArgs=0;
144   TString argument="";
145   int bMissingParam=0;
146   if (argc>0) {
147     pArguments=new const char*[argc];
148     if (pArguments) {
149       for (int i=0; i<argc && iResult>=0; i++) {
150         argument=argv[i];
151         if (argument.IsNull()) continue;
152
153         // benchmark
154         if (argument.CompareTo("benchmark")==0) {
155
156           // loglevel
157         } else if (argument.CompareTo("loglevel")==0) {
158           if ((bMissingParam=(++i>=argc))) break;
159           TString parameter(argv[i]);
160           parameter.Remove(TString::kLeading, ' '); // remove all blanks
161           if (parameter.BeginsWith("0x") &&
162               parameter.Replace(0,2,"",0).IsHex()) {
163             AliHLTComponentLogSeverity loglevel=kHLTLogNone;
164             sscanf(parameter.Data(),"%x", (unsigned int*)&loglevel);
165             SetLocalLoggingLevel(loglevel);
166           } else {
167             HLTError("wrong parameter for argument %s, hex number expected", argument.Data());
168             iResult=-EINVAL;
169           }
170         } else {
171           pArguments[iNofChildArgs++]=argv[i];
172         }
173       }
174     } else {
175       iResult=-ENOMEM;
176     }
177   }
178   if (bMissingParam) {
179     HLTError("missing parameter for argument %s", argument.Data());
180     iResult=-EINVAL;
181   }
182   if (iResult>=0) {
183     iResult=DoInit(iNofChildArgs, pArguments);
184   }
185   if (iResult>=0) fEventCount=0;
186   if (pArguments) delete [] pArguments;
187   return iResult;
188 }
189
190 int AliHLTComponent::Deinit()
191 {
192   // see header file for function documentation
193   HLTLogKeyword(GetComponentID());
194   int iResult=0;
195   iResult=DoDeinit();
196   if (fpRunDesc) {
197     HLTWarning("did not receive EOR for run %d", fpRunDesc->fRunNo);
198     AliHLTRunDesc* pRunDesc=fpRunDesc;
199     fpRunDesc=NULL;
200     delete pRunDesc;
201   }
202   fEventCount=0;
203   return iResult;
204 }
205
206 int AliHLTComponent::InitCDB(const char* cdbPath, AliHLTComponentHandler* pHandler)
207 {
208   // see header file for function documentation
209   int iResult=0;
210   if (pHandler) {
211   // I have to think about separating the library handling from the
212   // component handler. Requiring the component hanlder here is not
213   // the cleanest solution.
214   // We presume the library already to be loaded
215   // find the symbol
216   AliHLTMiscInitCDB_t pFunc=(AliHLTMiscInitCDB_t)pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_INIT_CDB);
217   if (pFunc) {
218     TString path;
219     if (cdbPath && cdbPath[0]!=0) {
220       path=cdbPath;
221       // very temporary fix, have to check for other formats
222       if (!path.BeginsWith("local://")) {
223         path="local://";
224         path+=cdbPath;
225       }
226     }
227     if ((iResult=(*pFunc)(path.Data()))>=0) {
228       if (!(fCDBSetRunNoFunc=pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_SET_CDB_RUNNO))) {
229         Message(NULL, kHLTLogWarning, "AliHLTComponent::InitCDB", "init CDB",
230                 "can not find function to set CDB run no");
231       }
232     }
233   } else {
234     Message(NULL, kHLTLogError, "AliHLTComponent::InitCDB", "init CDB",
235             "can not find initialization function");
236     iResult=-ENOSYS;
237   }
238   } else {
239     iResult=-EINVAL;
240   }
241   return iResult;
242 }
243
244 int AliHLTComponent::SetCDBRunNo(int runNo)
245 {
246   // see header file for function documentation
247   if (!fCDBSetRunNoFunc) return 0;
248   return (*((AliHLTMiscSetCDBRunNo_t)fCDBSetRunNoFunc))(runNo);
249 }
250
251 int AliHLTComponent::SetRunDescription(const AliHLTRunDesc* desc, const char* /*runType*/)
252 {
253   // see header file for function documentation
254   if (!desc) return -EINVAL;
255   if (desc->fStructSize!=sizeof(AliHLTRunDesc)) {
256     HLTError("invalid size of RunDesc struct (%ul)", desc->fStructSize);
257     return -EINVAL;
258   }
259
260   if (!fpRunDesc) {
261     fpRunDesc=new AliHLTRunDesc;
262     if (!fpRunDesc) return -ENOMEM;
263     *fpRunDesc=kAliHLTVoidRunDesc;
264   }
265
266   if (fpRunDesc->fRunNo!=kAliHLTVoidRunNo && fpRunDesc->fRunNo!=desc->fRunNo) {
267     HLTWarning("Run description has already been set");
268   }
269   *fpRunDesc=*desc;
270   SetCDBRunNo(fpRunDesc->fRunNo);
271   // TODO: we have to decide about the runType
272   return 0;
273 }
274
275 int AliHLTComponent::DoInit( int /*argc*/, const char** /*argv*/)
276 {
277   // default implementation, childs can overload
278   HLTLogKeyword("dummy");
279   return 0;
280 }
281
282 int AliHLTComponent::DoDeinit()
283 {
284   // default implementation, childs can overload
285   HLTLogKeyword("dummy");
286   return 0;
287 }
288
289 int AliHLTComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/)
290 {
291   // default implementation, childs can overload
292   HLTLogKeyword("dummy");
293   return 0;
294 }
295
296 int AliHLTComponent::ReadPreprocessorValues(const char* /*modules*/)
297 {
298   // default implementation, childs can overload
299   HLTLogKeyword("dummy");
300   return 0;
301 }
302
303 int AliHLTComponent::StartOfRun()
304 {
305   // default implementation, childs can overload
306   HLTLogKeyword("dummy");
307   return 0;
308 }
309
310 int AliHLTComponent::EndOfRun()
311 {
312   // default implementation, childs can overload
313   HLTLogKeyword("dummy");
314   return 0;
315 }
316
317
318 int AliHLTComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& /*tgtList*/)
319 {
320   // default implementation, childs can overload
321   HLTLogKeyword("dummy");
322   return 0;
323 }
324
325 void AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, char output[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2] ) const
326 {
327   // see header file for function documentation
328   memset( output, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
329   strncat( output, type.fOrigin, kAliHLTComponentDataTypefOriginSize );
330   strcat( output, ":" );
331   strncat( output, type.fID, kAliHLTComponentDataTypefIDsize );
332 }
333
334 string AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, int mode)
335 {
336   // see header file for function documentation
337   string out("");
338
339   if (mode==2) {
340     int i=0;
341     char tmp[8];
342     for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
343       sprintf(tmp, "'%d", type.fOrigin[i]);
344       out+=tmp;
345     }
346     out+="':'";
347     for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
348       sprintf(tmp, "%d'", type.fID[i]);
349       out+=tmp;
350     }
351     return out;
352   }
353
354   if (mode==1) {
355     int i=0;
356     char tmp[8];
357     for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
358       unsigned char* puc=(unsigned char*)type.fOrigin;
359       if ((puc[i])<32)
360         sprintf(tmp, "'\\%x", type.fOrigin[i]);
361       else
362         sprintf(tmp, "'%c", type.fOrigin[i]);
363       out+=tmp;
364     }
365     out+="':'";
366     for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
367       unsigned char* puc=(unsigned char*)type.fID;
368       if (puc[i]<32)
369         sprintf(tmp, "\\%x'", type.fID[i]);
370       else
371         sprintf(tmp, "%c'", type.fID[i]);
372       out+=tmp;
373     }
374     return out;
375   }
376
377   if (type==kAliHLTVoidDataType) {
378     out="VOID:VOID";
379   } else {
380     // some gymnastics in order to avoid a '0' which is part of either or both
381     // ID and origin terminating the whole string. Unfortunately, string doesn't
382     // stop appending at the '0' if the number of elements to append was 
383     // explicitely specified
384     string tmp("");
385     tmp.append(type.fOrigin, kAliHLTComponentDataTypefOriginSize);
386     out.append(tmp.c_str());
387     out.append(":");
388     tmp="";
389     tmp.append(type.fID, kAliHLTComponentDataTypefIDsize);
390     out.append(tmp.c_str());
391   }
392   return out;
393 }
394
395
396 void* AliHLTComponent::AllocMemory( unsigned long size ) 
397 {
398   // see header file for function documentation
399   if (fEnvironment.fAllocMemoryFunc)
400     return (*fEnvironment.fAllocMemoryFunc)(fEnvironment.fParam, size );
401   HLTFatal("no memory allocation handler registered");
402   return NULL;
403 }
404
405 int AliHLTComponent::MakeOutputDataBlockList( const AliHLTComponentBlockDataList& blocks, AliHLTUInt32_t* blockCount,
406                                               AliHLTComponentBlockData** outputBlocks ) 
407 {
408   // see header file for function documentation
409     if ( blockCount==NULL || outputBlocks==NULL )
410         return -EFAULT;
411     AliHLTUInt32_t count = blocks.size();
412     if ( !count )
413         {
414         *blockCount = 0;
415         *outputBlocks = NULL;
416         return 0;
417         }
418     *outputBlocks = reinterpret_cast<AliHLTComponentBlockData*>( AllocMemory( sizeof(AliHLTComponentBlockData)*count ) );
419     if ( !*outputBlocks )
420         return -ENOMEM;
421     for ( unsigned long i = 0; i < count; i++ ) {
422         (*outputBlocks)[i] = blocks[i];
423         if (MatchExactly(blocks[i].fDataType, kAliHLTAnyDataType)) {
424           (*outputBlocks)[i].fDataType=GetOutputDataType();
425           /* data type was set to the output data type by the PubSub AliRoot
426              Wrapper component, if data type of the block was ********:****.
427              Now handled by the component base class in order to have same
428              behavior when running embedded in AliRoot
429           memset((*outputBlocks)[i].fDataType.fID, '*', kAliHLTComponentDataTypefIDsize);
430           memset((*outputBlocks)[i].fDataType.fOrigin, '*', kAliHLTComponentDataTypefOriginSize);
431           */
432         }
433     }
434     *blockCount = count;
435     return 0;
436
437 }
438
439 int AliHLTComponent::GetEventDoneData( unsigned long size, AliHLTComponentEventDoneData** edd ) 
440 {
441   // see header file for function documentation
442   if (fEnvironment.fGetEventDoneDataFunc)
443     return (*fEnvironment.fGetEventDoneDataFunc)(fEnvironment.fParam, fCurrentEvent, size, edd );
444   return -ENOSYS;
445 }
446
447 int AliHLTComponent::FindMatchingDataTypes(AliHLTComponent* pConsumer, AliHLTComponentDataTypeList* tgtList) 
448 {
449   // see header file for function documentation
450   int iResult=0;
451   if (pConsumer) {
452     AliHLTComponentDataTypeList itypes;
453     AliHLTComponentDataTypeList otypes;
454     otypes.push_back(GetOutputDataType());
455     if (otypes[0]==kAliHLTMultipleDataType) {
456       otypes.clear();
457       int count=0;
458       if ((count=GetOutputDataTypes(otypes))>0) {
459       } else if (GetComponentType()!=kSink) {
460         HLTWarning("component %s indicates multiple output data types but GetOutputDataTypes returns %d", GetComponentID(), count);
461       }
462     }
463     ((AliHLTComponent*)pConsumer)->GetInputDataTypes(itypes);
464     AliHLTComponentDataTypeList::iterator itype=itypes.begin();
465     while (itype!=itypes.end()) {
466       //PrintDataTypeContent((*itype), "consumer \'%s\'");
467       AliHLTComponentDataTypeList::iterator otype=otypes.begin();
468       while (otype!=otypes.end() && (*itype)!=(*otype)) otype++;
469       //if (otype!=otypes.end()) PrintDataTypeContent(*otype, "publisher \'%s\'");
470       if (otype!=otypes.end()) {
471         if (tgtList) tgtList->push_back(*itype);
472         iResult++;
473       }
474       itype++;
475     }
476   } else {
477     iResult=-EINVAL;
478   }
479   return iResult;
480 }
481
482 void AliHLTComponent::PrintDataTypeContent(AliHLTComponentDataType& dt, const char* format)
483 {
484   // see header file for function documentation
485   const char* fmt="\'%s\'";
486   if (format) fmt=format;
487   AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, Form(fmt, (DataType2Text(dt)).c_str()));
488   AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, 
489                          Form("%x %x %x %x %x %x %x %x : %x %x %x %x", 
490                               dt.fID[0],
491                               dt.fID[1],
492                               dt.fID[2],
493                               dt.fID[3],
494                               dt.fID[4],
495                               dt.fID[5],
496                               dt.fID[6],
497                               dt.fID[7],
498                               dt.fOrigin[0],
499                               dt.fOrigin[1],
500                               dt.fOrigin[2],
501                               dt.fOrigin[3]));
502 }
503
504 void AliHLTComponent::FillBlockData( AliHLTComponentBlockData& blockData )
505 {
506   // see header file for function documentation
507   blockData.fStructSize = sizeof(blockData);
508   FillShmData( blockData.fShmKey );
509   blockData.fOffset = ~(AliHLTUInt32_t)0;
510   blockData.fPtr = NULL;
511   blockData.fSize = 0;
512   FillDataType( blockData.fDataType );
513   blockData.fSpecification = kAliHLTVoidDataSpec;
514 }
515
516 void AliHLTComponent::FillShmData( AliHLTComponentShmData& shmData )
517 {
518   // see header file for function documentation
519   shmData.fStructSize = sizeof(shmData);
520   shmData.fShmType = gkAliHLTComponentInvalidShmType;
521   shmData.fShmID = gkAliHLTComponentInvalidShmID;
522 }
523
524 void AliHLTComponent::FillDataType( AliHLTComponentDataType& dataType )
525 {
526   // see header file for function documentation
527   dataType=kAliHLTAnyDataType;
528 }
529
530 void AliHLTComponent::CopyDataType(AliHLTComponentDataType& tgtdt, const AliHLTComponentDataType& srcdt) 
531 {
532   // see header file for function documentation
533   memcpy(&tgtdt.fID[0], &srcdt.fID[0], kAliHLTComponentDataTypefIDsize);
534   memcpy(&tgtdt.fOrigin[0], &srcdt.fOrigin[0], kAliHLTComponentDataTypefOriginSize);
535 }
536
537 void AliHLTComponent::SetDataType(AliHLTComponentDataType& tgtdt, const char* id, const char* origin) 
538 {
539   // see header file for function documentation
540   tgtdt.fStructSize=sizeof(AliHLTComponentDataType);
541   if (id) {
542     memset(&tgtdt.fID[0], 0, kAliHLTComponentDataTypefIDsize);
543     strncpy(&tgtdt.fID[0], id, strlen(id)<(size_t)kAliHLTComponentDataTypefIDsize?strlen(id):kAliHLTComponentDataTypefIDsize);
544   }
545   if (origin) {
546     memset(&tgtdt.fOrigin[0], 0, kAliHLTComponentDataTypefOriginSize);
547     strncpy(&tgtdt.fOrigin[0], origin, strlen(origin)<(size_t)kAliHLTComponentDataTypefOriginSize?strlen(origin):kAliHLTComponentDataTypefOriginSize);
548   }
549 }
550
551 void AliHLTComponent::SetDataType(AliHLTComponentDataType& dt, AliHLTUInt64_t id, AliHLTUInt32_t origin)
552 {
553   // see header file for function documentation
554   dt.fStructSize=sizeof(AliHLTComponentDataType);
555   assert(kAliHLTComponentDataTypefIDsize==sizeof(id));
556   assert(kAliHLTComponentDataTypefOriginSize==sizeof(origin));
557   memcpy(&dt.fID, &id, kAliHLTComponentDataTypefIDsize);
558   memcpy(&dt.fOrigin, &origin, kAliHLTComponentDataTypefOriginSize);
559 }
560
561 void AliHLTComponent::FillEventData(AliHLTComponentEventData& evtData)
562 {
563   // see header file for function documentation
564   memset(&evtData, 0, sizeof(AliHLTComponentEventData));
565   evtData.fStructSize=sizeof(AliHLTComponentEventData);
566 }
567
568 void AliHLTComponent::PrintComponentDataTypeInfo(const AliHLTComponentDataType& dt) 
569 {
570   // see header file for function documentation
571   TString msg;
572   msg.Form("AliHLTComponentDataType(%d): ID=\"", dt.fStructSize);
573   for ( int i = 0; i < kAliHLTComponentDataTypefIDsize; i++ ) {
574    if (dt.fID[i]!=0) msg+=dt.fID[i];
575    else msg+="\\0";
576   }
577   msg+="\" Origin=\"";
578   for ( int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++ ) {
579    if (dt.fOrigin[i]!=0) msg+=dt.fOrigin[i];
580    else msg+="\\0";
581   }
582   msg+="\"";
583   AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, msg.Data());
584 }
585
586 int AliHLTComponent::GetEventCount() const
587 {
588   // see header file for function documentation
589   return fEventCount;
590 }
591
592 int AliHLTComponent::IncrementEventCounter()
593 {
594   // see header file for function documentation
595   if (fEventCount>=0) fEventCount++;
596   return fEventCount;
597 }
598
599 int AliHLTComponent::GetNumberOfInputBlocks() const
600 {
601   // see header file for function documentation
602   if (fpInputBlocks!=NULL) {
603     return fCurrentEventData.fBlockCnt;
604   }
605   return 0;
606 }
607
608 const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataType& dt,
609                                                     const char* classname,
610                                                     int bForce)
611 {
612   // see header file for function documentation
613   ALIHLTCOMPONENT_BASE_STOPWATCH();
614   fSearchDataType=dt;
615   if (classname) fClassName=classname;
616   else fClassName.clear();
617   int idx=FindInputBlock(fSearchDataType, 0, 1);
618   TObject* pObj=NULL;
619   if (idx>=0) {
620     HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str());
621     if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
622       fCurrentInputBlock=idx;
623     } else {
624     }
625   }
626   return pObj;
627 }
628
629 const TObject* AliHLTComponent::GetFirstInputObject(const char* dtID, 
630                                                     const char* dtOrigin,
631                                                     const char* classname,
632                                                     int         bForce)
633 {
634   // see header file for function documentation
635   ALIHLTCOMPONENT_BASE_STOPWATCH();
636   AliHLTComponentDataType dt;
637   SetDataType(dt, dtID, dtOrigin);
638   return GetFirstInputObject(dt, classname, bForce);
639 }
640
641 const TObject* AliHLTComponent::GetNextInputObject(int bForce)
642 {
643   // see header file for function documentation
644   ALIHLTCOMPONENT_BASE_STOPWATCH();
645   int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1, 1);
646   //HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(fSearchDataType).c_str());
647   TObject* pObj=NULL;
648   if (idx>=0) {
649     if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
650       fCurrentInputBlock=idx;
651     }
652   }
653   return pObj;
654 }
655
656 int AliHLTComponent::FindInputBlock(const AliHLTComponentDataType& dt, int startIdx, int bObject) const
657 {
658   // see header file for function documentation
659   int iResult=-ENOENT;
660   if (fpInputBlocks!=NULL) {
661     int idx=startIdx<0?0:startIdx;
662     for ( ; (UInt_t)idx<fCurrentEventData.fBlockCnt && iResult==-ENOENT; idx++) {
663       if (dt!=fpInputBlocks[idx].fDataType) continue;
664
665       if (bObject!=0) {
666         if (fpInputBlocks[idx].fPtr==NULL) continue;
667         AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
668         if (firstWord!=fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) continue;
669       }
670       iResult=idx;
671     }
672   }
673   return iResult;
674 }
675
676 TObject* AliHLTComponent::CreateInputObject(int idx, int bForce)
677 {
678   // see header file for function documentation
679   TObject* pObj=NULL;
680   if (fpInputBlocks!=NULL) {
681     if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
682       if (fpInputBlocks[idx].fPtr) {
683         AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
684         if (firstWord==fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) {
685           HLTDebug("create object from block %d size %d", idx, fpInputBlocks[idx].fSize);
686           AliHLTMessage msg(fpInputBlocks[idx].fPtr, fpInputBlocks[idx].fSize);
687           TClass* objclass=msg.GetClass();
688           pObj=msg.ReadObject(objclass);
689           if (pObj && objclass) {
690             HLTDebug("object %p type %s created", pObj, objclass->GetName());
691           } else {
692           }
693           //} else {
694         } else if (bForce!=0) {
695           HLTError("size mismatch: block size %d, indicated %d", fpInputBlocks[idx].fSize, firstWord+sizeof(AliHLTUInt32_t));
696         }
697       } else {
698         HLTFatal("block descriptor empty");
699       }
700     } else {
701       HLTError("index %d out of range %d", idx, fCurrentEventData.fBlockCnt);
702     }
703   } else {
704     HLTError("no input blocks available");
705   }
706   
707   return pObj;
708 }
709
710 TObject* AliHLTComponent::GetInputObject(int idx, const char* /*classname*/, int bForce)
711 {
712   // see header file for function documentation
713   if (fpInputObjects==NULL) {
714     fpInputObjects=new TObjArray(fCurrentEventData.fBlockCnt);
715   }
716   TObject* pObj=NULL;
717   if (fpInputObjects) {
718     pObj=fpInputObjects->At(idx);
719     if (pObj==NULL) {
720       pObj=CreateInputObject(idx, bForce);
721       if (pObj) {
722         fpInputObjects->AddAt(pObj, idx);
723       }
724     }
725   } else {
726     HLTFatal("memory allocation failed: TObjArray of size %d", fCurrentEventData.fBlockCnt);
727   }
728   return pObj;
729 }
730
731 int AliHLTComponent::CleanupInputObjects()
732 {
733   // see header file for function documentation
734   if (!fpInputObjects) return 0;
735   TObjArray* array=fpInputObjects;
736   fpInputObjects=NULL;
737   for (int i=0; i<array->GetEntries(); i++) {
738     TObject* pObj=array->At(i);
739     // grrr, garbage collection strikes back: When read via AliHLTMessage
740     // (CreateInputObject), and written to a TFile afterwards, the
741     // TFile::Close calls ROOOT's garbage collection. No clue why the
742     // object ended up in the key list and needs to be deleted
743     if (pObj && gObjectTable->PtrIsValid(pObj)) delete pObj;
744   }
745   delete array;
746   return 0;
747 }
748
749 AliHLTComponentDataType AliHLTComponent::GetDataType(const TObject* pObject)
750 {
751   // see header file for function documentation
752   ALIHLTCOMPONENT_BASE_STOPWATCH();
753   AliHLTComponentDataType dt=kAliHLTVoidDataType;
754   int idx=fCurrentInputBlock;
755   if (pObject) {
756     if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
757     } else {
758       HLTError("unknown object %p", pObject);
759     }
760   }
761   if (idx>=0) {
762     if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
763       dt=fpInputBlocks[idx].fDataType;
764     } else {
765       HLTFatal("severe internal error, index out of range");
766     }
767   }
768   return dt;
769 }
770
771 AliHLTUInt32_t AliHLTComponent::GetSpecification(const TObject* pObject)
772 {
773   // see header file for function documentation
774   ALIHLTCOMPONENT_BASE_STOPWATCH();
775   AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
776   int idx=fCurrentInputBlock;
777   if (pObject) {
778     if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
779     } else {
780       HLTError("unknown object %p", pObject);
781     }
782   }
783   if (idx>=0) {
784     if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
785       iSpec=fpInputBlocks[idx].fSpecification;
786     } else {
787       HLTFatal("severe internal error, index out of range");
788     }
789   }
790   return iSpec;
791 }
792
793 int AliHLTComponent::Forward(const TObject* pObject)
794 {
795   // see header file for function documentation
796   int iResult=0;
797   int idx=fCurrentInputBlock;
798   if (pObject) {
799     if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
800     } else {
801       HLTError("unknown object %p", pObject);
802       iResult=-ENOENT;
803     }
804   }
805   if (idx>=0) {
806     fOutputBlocks.push_back(fpInputBlocks[idx]);
807   }
808   return iResult;
809 }
810
811 int AliHLTComponent::Forward(const AliHLTComponentBlockData* pBlock)
812 {
813   // see header file for function documentation
814   int iResult=0;
815   int idx=fCurrentInputBlock;
816   if (pBlock) {
817     if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
818     } else {
819       HLTError("unknown Block %p", pBlock);
820       iResult=-ENOENT;      
821     }
822   }
823   if (idx>=0) {
824     // check for fpInputBlocks pointer done in FindInputBlock
825     fOutputBlocks.push_back(fpInputBlocks[idx]);
826   }
827   return iResult;
828 }
829
830 const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const AliHLTComponentDataType& dt)
831 {
832   // see header file for function documentation
833   ALIHLTCOMPONENT_BASE_STOPWATCH();
834   fSearchDataType=dt;
835   fClassName.clear();
836   int idx=FindInputBlock(fSearchDataType, 0);
837   const AliHLTComponentBlockData* pBlock=NULL;
838   if (idx>=0) {
839     // check for fpInputBlocks pointer done in FindInputBlock
840     pBlock=&fpInputBlocks[idx];
841     fCurrentInputBlock=idx;
842   }
843   return pBlock;
844 }
845
846 const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const char* dtID, 
847                                                                     const char* dtOrigin)
848 {
849   // see header file for function documentation
850   ALIHLTCOMPONENT_BASE_STOPWATCH();
851   AliHLTComponentDataType dt;
852   SetDataType(dt, dtID, dtOrigin);
853   return GetFirstInputBlock(dt);
854 }
855
856 const AliHLTComponentBlockData* AliHLTComponent::GetInputBlock(int index)
857 {
858   // see header file for function documentation
859   ALIHLTCOMPONENT_BASE_STOPWATCH();
860   assert( 0 <= index and index < (int)fCurrentEventData.fBlockCnt );
861   return &fpInputBlocks[index];
862 }
863
864 const AliHLTComponentBlockData* AliHLTComponent::GetNextInputBlock()
865 {
866   // see header file for function documentation
867   ALIHLTCOMPONENT_BASE_STOPWATCH();
868   int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1);
869   const AliHLTComponentBlockData* pBlock=NULL;
870   if (idx>=0) {
871     // check for fpInputBlocks pointer done in FindInputBlock
872     pBlock=&fpInputBlocks[idx];
873     fCurrentInputBlock=idx;
874   }
875   return pBlock;
876 }
877
878 int AliHLTComponent::FindInputBlock(const AliHLTComponentBlockData* pBlock) const
879 {
880   // see header file for function documentation
881   int iResult=-ENOENT;
882   if (fpInputBlocks!=NULL) {
883     if (pBlock) {
884       if (pBlock>=fpInputBlocks && pBlock<fpInputBlocks+fCurrentEventData.fBlockCnt) {
885         iResult=(int)(pBlock-fpInputBlocks);
886       }
887     } else {
888       iResult=-EINVAL;
889     }
890   }
891   return iResult;
892 }
893
894 AliHLTUInt32_t AliHLTComponent::GetSpecification(const AliHLTComponentBlockData* pBlock)
895 {
896   // see header file for function documentation
897   ALIHLTCOMPONENT_BASE_STOPWATCH();
898   AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
899   int idx=fCurrentInputBlock;
900   if (pBlock) {
901     if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
902     } else {
903       HLTError("unknown Block %p", pBlock);
904     }
905   }
906   if (idx>=0) {
907     // check for fpInputBlocks pointer done in FindInputBlock
908     iSpec=fpInputBlocks[idx].fSpecification;
909   }
910   return iSpec;
911 }
912
913 int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec, 
914                               void* pHeader, int headerSize)
915 {
916   // see header file for function documentation
917   ALIHLTCOMPONENT_BASE_STOPWATCH();
918   int iResult=0;
919   if (pObject) {
920     AliHLTMessage msg(kMESS_OBJECT);
921     msg.WriteObject(pObject);
922     Int_t iMsgLength=msg.Length();
923     if (iMsgLength>0) {
924       msg.SetLength(); // sets the length to the first (reserved) word
925       iResult=InsertOutputBlock(msg.Buffer(), iMsgLength, dt, spec, pHeader, headerSize);
926       if (iResult>=0) {
927         HLTDebug("object %s (%p) size %d inserted to output", pObject->ClassName(), pObject, iMsgLength);
928       }
929     } else {
930       HLTError("object serialization failed for object %p", pObject);
931       iResult=-ENOMSG;
932     }
933   } else {
934     iResult=-EINVAL;
935   }
936   return iResult;
937 }
938
939 int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
940                               void* pHeader, int headerSize)
941 {
942   // see header file for function documentation
943   ALIHLTCOMPONENT_BASE_STOPWATCH();
944   AliHLTComponentDataType dt;
945   SetDataType(dt, dtID, dtOrigin);
946   return PushBack(pObject, dt, spec, pHeader, headerSize);
947 }
948
949 int AliHLTComponent::PushBack(void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
950                               void* pHeader, int headerSize)
951 {
952   // see header file for function documentation
953   ALIHLTCOMPONENT_BASE_STOPWATCH();
954   return InsertOutputBlock(pBuffer, iSize, dt, spec, pHeader, headerSize);
955 }
956
957 int AliHLTComponent::PushBack(void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
958                               void* pHeader, int headerSize)
959 {
960   // see header file for function documentation
961   ALIHLTCOMPONENT_BASE_STOPWATCH();
962   AliHLTComponentDataType dt;
963   SetDataType(dt, dtID, dtOrigin);
964   return PushBack(pBuffer, iSize, dt, spec, pHeader, headerSize);
965 }
966
967 int AliHLTComponent::InsertOutputBlock(void* pBuffer, int iBufferSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
968                               void* pHeader, int iHeaderSize)
969 {
970   // see header file for function documentation
971   int iResult=0;
972   int iBlkSize = iBufferSize + iHeaderSize;
973   if (pBuffer) {
974     if (fpOutputBuffer && iBlkSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) {
975       AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
976       AliHLTComponentBlockData bd;
977       FillBlockData( bd );
978       bd.fOffset        = fOutputBufferFilled;
979       bd.fSize          = iBlkSize;
980       bd.fDataType      = dt;
981       bd.fSpecification = spec;
982       if (pHeader!=NULL && pHeader!=pTgt) {
983         memcpy(pTgt, pHeader, iHeaderSize);
984       }
985
986       pTgt += (AliHLTUInt8_t) iHeaderSize;
987
988       if (pBuffer!=NULL && pBuffer!=pTgt) {
989         memcpy(pTgt, pBuffer, iBufferSize);
990         
991         //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer); 
992         //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iBufferSize, pBuffer, pTgt, firstWord);
993       }
994       fOutputBufferFilled+=bd.fSize;
995       fOutputBlocks.push_back( bd );
996       //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iBlkSize, DataType2Text(dt).c_str(), spec);
997     } else {
998       if (fpOutputBuffer) {
999         HLTError("too little space in output buffer: %d, required %d", fOutputBufferSize-fOutputBufferFilled, iBlkSize);
1000       } else {
1001         HLTError("output buffer not available");
1002       }
1003       iResult=-ENOSPC;
1004     }
1005   } else {
1006     iResult=-EINVAL;
1007   }
1008   return iResult;
1009 }
1010
1011 int AliHLTComponent::EstimateObjectSize(TObject* pObject) const
1012 {
1013   // see header file for function documentation
1014   if (!pObject) return -EINVAL;
1015     AliHLTMessage msg(kMESS_OBJECT);
1016     msg.WriteObject(pObject);
1017     return msg.Length();  
1018 }
1019
1020 AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity, const char* dtID,
1021                                                     const char* dtOrigin,
1022                                                     AliHLTUInt32_t spec)
1023 {
1024   // see header file for function documentation
1025   ALIHLTCOMPONENT_BASE_STOPWATCH();
1026   AliHLTComponentDataType dt;
1027   SetDataType(dt, dtID, dtOrigin);
1028   return CreateMemoryFile(capacity, dt, spec);
1029 }
1030
1031 AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity,
1032                                                     const AliHLTComponentDataType& dt,
1033                                                     AliHLTUInt32_t spec)
1034 {
1035   // see header file for function documentation
1036   ALIHLTCOMPONENT_BASE_STOPWATCH();
1037   AliHLTMemoryFile* pFile=NULL;
1038   if (capacity>=0 && static_cast<unsigned int>(capacity)<=fOutputBufferSize-fOutputBufferFilled){
1039     AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
1040     pFile=new AliHLTMemoryFile((char*)pTgt, capacity);
1041     if (pFile) {
1042       unsigned int nofBlocks=fOutputBlocks.size();
1043       if (nofBlocks+1>fMemFiles.size()) {
1044         fMemFiles.resize(nofBlocks+1, NULL);
1045       }
1046       if (nofBlocks<fMemFiles.size()) {
1047         fMemFiles[nofBlocks]=pFile;
1048         AliHLTComponentBlockData bd;
1049         FillBlockData( bd );
1050         bd.fOffset        = fOutputBufferFilled;
1051         bd.fSize          = capacity;
1052         bd.fDataType      = dt;
1053         bd.fSpecification = spec;
1054         fOutputBufferFilled+=bd.fSize;
1055         fOutputBlocks.push_back( bd );
1056       } else {
1057         HLTError("can not allocate/grow object array");
1058         pFile->CloseMemoryFile(0);
1059         delete pFile;
1060         pFile=NULL;
1061       }
1062     }
1063   } else {
1064     HLTError("can not create memory file of size %d (%d available)", capacity, fOutputBufferSize-fOutputBufferFilled);
1065   }
1066   return pFile;
1067 }
1068
1069 AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const char* dtID,
1070                                                     const char* dtOrigin,
1071                                                     AliHLTUInt32_t spec,
1072                                                     float capacity)
1073 {
1074   // see header file for function documentation
1075   ALIHLTCOMPONENT_BASE_STOPWATCH();
1076   AliHLTComponentDataType dt;
1077   SetDataType(dt, dtID, dtOrigin);
1078   int size=fOutputBufferSize-fOutputBufferFilled;
1079   if (capacity<0 || capacity>1.0) {
1080     HLTError("invalid parameter: capacity %f", capacity);
1081     return NULL;
1082   }
1083   size=(int)(size*capacity);
1084   return CreateMemoryFile(size, dt, spec);
1085 }
1086
1087 AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const AliHLTComponentDataType& dt,
1088                                                     AliHLTUInt32_t spec,
1089                                                     float capacity)
1090 {
1091   // see header file for function documentation
1092   ALIHLTCOMPONENT_BASE_STOPWATCH();
1093   int size=fOutputBufferSize-fOutputBufferFilled;
1094   if (capacity<0 || capacity>1.0) {
1095     HLTError("invalid parameter: capacity %f", capacity);
1096     return NULL;
1097   }
1098   size=(int)(size*capacity);
1099   return CreateMemoryFile(size, dt, spec);
1100 }
1101
1102 int AliHLTComponent::Write(AliHLTMemoryFile* pFile, const TObject* pObject,
1103                            const char* key, int option)
1104 {
1105   // see header file for function documentation
1106   int iResult=0;
1107   if (pFile && pObject) {
1108     pFile->cd();
1109     iResult=pObject->Write(key, option);
1110     if (iResult>0) {
1111       // success
1112     } else {
1113       iResult=-pFile->GetErrno();
1114       if (iResult==-ENOSPC) {
1115         HLTError("error writing memory file, buffer too small");
1116       }
1117     }
1118   } else {
1119     iResult=-EINVAL;
1120   }
1121   return iResult;
1122 }
1123
1124 int AliHLTComponent::CloseMemoryFile(AliHLTMemoryFile* pFile)
1125 {
1126   // see header file for function documentation
1127   int iResult=0;
1128   if (pFile) {
1129     AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
1130     int i=0;
1131     while (element!=fMemFiles.end() && iResult>=0) {
1132       if (*element && *element==pFile) {
1133         iResult=pFile->CloseMemoryFile();
1134         
1135         // sync memory files and descriptors
1136         if (iResult>=0) {
1137           fOutputBlocks[i].fSize=(*element)->GetSize()+(*element)->GetHeaderSize();
1138         }
1139         delete *element;
1140         *element=NULL;
1141         return iResult;
1142       }
1143       element++; i++;
1144     }
1145     HLTError("can not find memory file %p", pFile);
1146     iResult=-ENOENT;
1147   } else {
1148     iResult=-EINVAL;
1149   }
1150   return iResult;
1151 }
1152
1153 int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData /*edd*/)
1154 {
1155   // see header file for function documentation
1156   int iResult=-ENOSYS;
1157   //#warning  function not yet implemented
1158   HLTWarning("function not yet implemented");
1159   return iResult;
1160 }
1161
1162 int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
1163                                    const AliHLTComponentBlockData* blocks, 
1164                                    AliHLTComponentTriggerData& trigData,
1165                                    AliHLTUInt8_t* outputPtr, 
1166                                    AliHLTUInt32_t& size,
1167                                    AliHLTUInt32_t& outputBlockCnt, 
1168                                    AliHLTComponentBlockData*& outputBlocks,
1169                                    AliHLTComponentEventDoneData*& edd )
1170 {
1171   // see header file for function documentation
1172   HLTLogKeyword(GetComponentID());
1173   ALIHLTCOMPONENT_BASE_STOPWATCH();
1174   int iResult=0;
1175   fCurrentEvent=evtData.fEventID;
1176   fCurrentEventData=evtData;
1177   fpInputBlocks=blocks;
1178   fCurrentInputBlock=-1;
1179   fSearchDataType=kAliHLTAnyDataType;
1180   fpOutputBuffer=outputPtr;
1181   fOutputBufferSize=size;
1182   fOutputBufferFilled=0;
1183   fOutputBlocks.clear();
1184   outputBlockCnt=0;
1185   outputBlocks=NULL;
1186
1187   // data processing is skipped if there are only steering events
1188   // in the block list. It is not skipped if there is no block list
1189   // at all for the sake of data source components. Data processing
1190   // is always skipped if the event is of type
1191   // - gkAliEventTypeConfiguration
1192   // - gkAliEventTypeReadPreprocessor
1193   const unsigned int skipModeDefault=0x1;
1194   const unsigned int skipModeForce=0x2;
1195   unsigned int bSkipDataProcessing=skipModeDefault;
1196
1197   // find special events
1198   if (fpInputBlocks && evtData.fBlockCnt>0) {
1199     // first look for all special events and execute in the appropriate
1200     // sequence afterwords
1201     AliHLTUInt32_t eventType=gkAliEventTypeUnknown;
1202     int indexComConfEvent=-1;
1203     int indexUpdtDCSEvent=-1;
1204     int indexSOREvent=-1;
1205     int indexEOREvent=-1;
1206     for (unsigned int i=0; i<evtData.fBlockCnt && iResult>=0; i++) {
1207       if (fpInputBlocks[i].fDataType==kAliHLTDataTypeSOR) {
1208         indexSOREvent=i;
1209         // the AliHLTCalibrationProcessor relies on the SOR and EOR events
1210         bSkipDataProcessing&=~skipModeDefault;
1211       } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeRunType) {
1212         // run type string
1213         // handling is not clear yet
1214         if (fpInputBlocks[i].fPtr) {
1215           HLTDebug("got run type \"%s\"\n", fpInputBlocks[i].fPtr);
1216         }
1217       } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEOR) {
1218         indexEOREvent=i;
1219         // the calibration processor relies on the SOR and EOR events
1220         bSkipDataProcessing&=~skipModeDefault;
1221       } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeDDL) {
1222         // DDL list
1223         // this event is most likely deprecated
1224       } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComConf) {
1225         indexComConfEvent=i;
1226       } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeUpdtDCS) {
1227         indexUpdtDCSEvent=i;
1228       } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) {
1229         eventType=fpInputBlocks[i].fSpecification;
1230         if (fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration) bSkipDataProcessing|=skipModeForce;
1231         if (fpInputBlocks[i].fSpecification==gkAliEventTypeReadPreprocessor) bSkipDataProcessing|=skipModeForce;
1232       } else {
1233         // the processing function is called if there is at least one
1234         // non-steering data block. Steering blocks are not filtered out
1235         // for sake of performance 
1236         bSkipDataProcessing&=~skipModeDefault;
1237       }
1238     }
1239
1240     if (indexSOREvent>=0) {
1241       // start of run
1242       if (fpRunDesc==NULL) {
1243         fpRunDesc=new AliHLTRunDesc;
1244       }
1245       if (fpRunDesc) {
1246         AliHLTRunDesc rundesc;
1247         if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexSOREvent, "AliHLTRunDesc", "SOR"))>0) {
1248           if (fpRunDesc->fRunNo==kAliHLTVoidRunNo) {
1249             *fpRunDesc=rundesc;
1250             HLTDebug("set run decriptor, run no %d", fpRunDesc->fRunNo);
1251             SetCDBRunNo(fpRunDesc->fRunNo);
1252           } else if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
1253             HLTWarning("already set run properties run no %d, ignoring SOR with run no %d", fpRunDesc->fRunNo, rundesc.fRunNo);
1254           }
1255         }
1256       } else {
1257         iResult=-ENOMEM;
1258       }
1259     }
1260     if (indexEOREvent>=0) {
1261       if (fpRunDesc!=NULL) {
1262         if (fpRunDesc) {
1263           AliHLTRunDesc rundesc;
1264           if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexEOREvent, "AliHLTRunDesc", "SOR"))>0) {
1265             if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
1266               HLTWarning("run no mismatch: SOR %d, EOR %d", fpRunDesc->fRunNo, rundesc.fRunNo);
1267             } else {
1268               HLTDebug("EOR run no %d", fpRunDesc->fRunNo);
1269             }
1270           }
1271           AliHLTRunDesc* pRunDesc=fpRunDesc;
1272           fpRunDesc=NULL;
1273           delete pRunDesc;
1274         }
1275       } else {
1276         HLTWarning("did not receive SOR, ignoring EOR");
1277       }
1278     }
1279     if (indexComConfEvent>=0 || eventType==gkAliEventTypeConfiguration) {
1280       TString cdbEntry;
1281       if (indexComConfEvent>=0 && fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) {
1282         cdbEntry.Append(reinterpret_cast<const char*>(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize);
1283       }
1284       HLTDebug("received component configuration command: entry %s", cdbEntry.IsNull()?"none":cdbEntry.Data());
1285       int tmpResult=Reconfigure(cdbEntry[0]==0?NULL:cdbEntry.Data(), fChainId.c_str());
1286       if (tmpResult<0) {
1287         HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
1288       }
1289     }
1290     if (indexUpdtDCSEvent>=0 || eventType==gkAliEventTypeReadPreprocessor) {
1291       TString modules;
1292       if (fpInputBlocks[indexUpdtDCSEvent].fPtr!=NULL && fpInputBlocks[indexUpdtDCSEvent].fSize>0) {
1293         modules.Append(reinterpret_cast<const char*>(fpInputBlocks[indexUpdtDCSEvent].fPtr), fpInputBlocks[indexUpdtDCSEvent].fSize);
1294       }
1295       HLTDebug("received preprocessor update command: detectors %s", modules.IsNull()?"ALL":modules.Data());
1296       int tmpResult=ReadPreprocessorValues(modules[0]==0?"ALL":modules.Data());
1297       if (tmpResult<0) {
1298         HLTWarning("preprocessor update of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
1299       }
1300     }
1301   } else {
1302     // processing function needs to be called if there are no input data
1303     // blocks in order to make data source components working.
1304     bSkipDataProcessing&=~skipModeDefault;
1305   }
1306   
1307   AliHLTComponentBlockDataList blockData;
1308   if (iResult>=0 && !bSkipDataProcessing)
1309   { // dont delete, sets the scope for the stopwatch guard
1310     // do not use ALIHLTCOMPONENT_DA_STOPWATCH(); macro
1311     // in order to avoid 'shadowed variable' warning
1312     AliHLTStopwatchGuard swguard2(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)kSWDA)):NULL);
1313     iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
1314   } // end of the scope of the stopwatch guard
1315   if (iResult>=0 && !bSkipDataProcessing) {
1316     if (fOutputBlocks.size()>0) {
1317       // High Level interface
1318
1319       //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());      
1320       // sync memory files and descriptors
1321       AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
1322       int i=0;
1323       while (element!=fMemFiles.end() && iResult>=0) {
1324         if (*element) {
1325           if ((*element)->IsClosed()==0) {
1326             HLTWarning("memory file has not been closed, force flush");
1327             iResult=CloseMemoryFile(*element);
1328           }
1329         }
1330         element++; i++;
1331       }
1332
1333       if (iResult>=0) {
1334         // create the descriptor list
1335         if (blockData.size()>0) {
1336           HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
1337           iResult=-EFAULT;
1338         } else {
1339           iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
1340           size=fOutputBufferFilled;
1341         }
1342       }
1343     } else {
1344       // Low Level interface
1345       iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
1346     }
1347     if (iResult<0) {
1348       HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
1349     }
1350   }
1351   if (iResult<0 || bSkipDataProcessing) {
1352     outputBlockCnt=0;
1353     outputBlocks=NULL;
1354   }
1355   CleanupInputObjects();
1356   if (iResult>=0 && !bSkipDataProcessing) {
1357     IncrementEventCounter();
1358   }
1359   if (outputBlockCnt==0) {
1360     // no output blocks, set size to 0
1361     size=0;
1362   }
1363   return iResult;
1364 }
1365
1366 AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
1367   :
1368   fpStopwatch(NULL),
1369   fpPrec(NULL)
1370 {
1371   // standard constructor (not for use)
1372 }
1373
1374 AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
1375   :
1376   fpStopwatch(pStopwatch),
1377   fpPrec(NULL)
1378 {
1379   // constructor
1380
1381   // check for already existing guard
1382   if (fgpCurrent) fpPrec=fgpCurrent;
1383   fgpCurrent=this;
1384
1385   // stop the preceeding guard if it controls a different stopwatch
1386   int bStart=1;
1387   if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
1388
1389   // start the stopwatch if the current guard controls a different one
1390   if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
1391 }
1392
1393 AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(const AliHLTStopwatchGuard&)
1394   :
1395   fpStopwatch(NULL),
1396   fpPrec(NULL)
1397 {
1398   //
1399   // copy constructor not for use
1400   //
1401 }
1402
1403 AliHLTComponent::AliHLTStopwatchGuard& AliHLTComponent::AliHLTStopwatchGuard::operator=(const AliHLTStopwatchGuard&)
1404 {
1405   //
1406   // assignment operator not for use
1407   //
1408   fpStopwatch=NULL;
1409   fpPrec=NULL;
1410   return *this;
1411 }
1412
1413 AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
1414
1415 AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
1416 {
1417   // destructor
1418
1419   // resume the preceeding guard if it controls a different stopwatch
1420   int bStop=1;
1421   if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
1422
1423   // stop the stopwatch if the current guard controls a different one
1424   if (fpStopwatch && bStop==1) fpStopwatch->Stop();
1425
1426   // resume to the preceeding guard
1427   fgpCurrent=fpPrec;
1428 }
1429
1430 int AliHLTComponent::AliHLTStopwatchGuard::Hold(TStopwatch* pSucc)
1431 {
1432   // see header file for function documentation
1433   if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
1434   return fpStopwatch!=pSucc?1:0;
1435 }
1436
1437 int AliHLTComponent::AliHLTStopwatchGuard::Resume(TStopwatch* pSucc)
1438 {
1439   // see header file for function documentation
1440   if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
1441   return fpStopwatch!=pSucc?1:0;
1442 }
1443
1444 int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type) 
1445 {
1446   // see header file for function documentation
1447   int iResult=0;
1448   if (pSW!=NULL && type<kSWTypeCount) {
1449     if (fpStopwatches) {
1450       TObject* pObj=fpStopwatches->At((int)type);
1451       if (pSW==NULL        // explicit reset
1452           || pObj==NULL) { // explicit set
1453         fpStopwatches->AddAt(pSW, (int)type);
1454       } else if (pObj!=pSW) {
1455         HLTWarning("stopwatch %d already set, reset first", (int)type);
1456         iResult=-EBUSY;
1457       }
1458     }
1459   } else {
1460     iResult=-EINVAL;
1461   }
1462   return iResult;
1463 }
1464
1465 int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
1466 {
1467   // see header file for function documentation
1468   if (pStopwatches==NULL) return -EINVAL;
1469
1470   int iResult=0;
1471   for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntries(); i++)
1472     SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
1473   return iResult;
1474 }
1475
1476 AliHLTUInt32_t AliHLTComponent::GetRunNo() const
1477 {
1478   // see header file for function documentation
1479   if (fpRunDesc==NULL) return kAliHLTVoidRunNo;
1480   return fpRunDesc->fRunNo;
1481 }
1482
1483 AliHLTUInt32_t AliHLTComponent::GetRunType() const
1484 {
1485   // see header file for function documentation
1486   if (fpRunDesc==NULL) return kAliHLTVoidRunType;
1487   return fpRunDesc->fRunType;
1488 }
1489
1490 int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
1491                                 const char* structname, const char* eventname)
1492 {
1493   // see header file for function documentation
1494   int iResult=0;
1495   if (pStruct!=NULL && iStructSize>sizeof(AliHLTUInt32_t)) {
1496     if (fpInputBlocks!=NULL && iBlockNo<fCurrentEventData.fBlockCnt) {
1497       AliHLTUInt32_t* pTgt=(AliHLTUInt32_t*)pStruct;
1498       if (fpInputBlocks[iBlockNo].fPtr && fpInputBlocks[iBlockNo].fSize) {
1499         AliHLTUInt32_t copy=*((AliHLTUInt32_t*)fpInputBlocks[iBlockNo].fPtr);
1500         if (fpInputBlocks[iBlockNo].fSize!=copy) {
1501           HLTWarning("%s event: mismatch of block size (%d) and structure size (%d)", eventname, fpInputBlocks[iBlockNo].fSize, copy);
1502           if (copy>fpInputBlocks[iBlockNo].fSize) copy=fpInputBlocks[iBlockNo].fSize;
1503         }
1504         if (copy!=iStructSize) {
1505           HLTWarning("%s event: mismatch in %s version (data type version %d)", eventname, structname, ALIHLT_DATA_TYPES_VERSION);
1506           if (copy>iStructSize) {
1507             copy=iStructSize;
1508           } else {
1509             memset(pTgt, 0, iStructSize);
1510           }
1511         }
1512         memcpy(pTgt, fpInputBlocks[iBlockNo].fPtr, copy);
1513         *pTgt=iStructSize;
1514         iResult=copy;
1515       } else {
1516         HLTWarning("%s event: missing data block", eventname);
1517       }
1518     } else {
1519       iResult=-ENODATA;
1520     }
1521   } else {
1522     HLTError("invalid struct");
1523     iResult=-EINVAL;
1524   }
1525   return iResult;
1526 }
1527
1528 void AliHLTComponent::SetDDLBit(AliHLTEventDDL &list, Int_t ddlId, Bool_t state ) const
1529 {
1530   // see header file for function documentation
1531   
1532   // -- Detector offset
1533   Int_t ddlIdBase =  TMath::FloorNint( (Double_t) ddlId / 256.0 );
1534   
1535   // -- Word Base = 1. word of detector ( TPC has 8 words, TOF 3 ) 
1536   Int_t wordBase = 0;
1537
1538   if ( ddlIdBase <= 3 )
1539     wordBase = ddlIdBase;
1540   else if ( ddlIdBase > 3 && ddlIdBase < 5 )
1541     wordBase = ddlIdBase + 7;
1542   else 
1543     wordBase = ddlIdBase + 9;
1544
1545   // -- Bit index in Word
1546   Int_t bitIdx = ddlId % 32;
1547
1548   // -- Index of word
1549   Int_t wordIdx = wordBase;
1550
1551   // -- if TPC (3) or TOD (5) add word idx
1552   if ( ( ddlIdBase == 3 ) || ( ddlIdBase == 5 ) ) {
1553     wordIdx += TMath::FloorNint( (Double_t) ( ddlId - ( ddlIdBase * 256 ) ) / 32.0 );
1554   }
1555
1556   // -- Set -- 'OR' word with bit mask;
1557   if ( state )
1558     list.fList[wordIdx] |= ( 0x00000001 << bitIdx );
1559   // -- Unset -- 'AND' word with bit mask;
1560   else
1561     list.fList[wordIdx] &= ( 0xFFFFFFFF ^ ( 0x00000001 << bitIdx ) );
1562 }
1563
1564 Int_t AliHLTComponent::GetFirstUsedDDLWord(AliHLTEventDDL &list) const
1565 {
1566   // see header file for function documentation
1567
1568   Int_t iResult = -1;
1569
1570   for ( Int_t wordNdx = 0 ; wordNdx < gkAliHLTDDLListSize ; wordNdx++ ) {
1571
1572     if ( list.fList[wordNdx] != 0 && iResult == -1 ) {
1573       // check for special cases TPC and TOF
1574       if ( wordNdx > 3 && wordNdx <= 10 ) {
1575         wordNdx = 10;
1576         iResult = 3;
1577       }
1578       else if ( wordNdx > 12 && wordNdx <= 14 ) {
1579         wordNdx = 14;
1580         iResult = 12;
1581       }
1582       else
1583         iResult = wordNdx;
1584     }
1585     else if ( list.fList[wordNdx] != 0 && iResult >= 0 ) {
1586       HLTError( "DDLIDs for minimum of TWO detectors ( %d, %d ) set, this function works only for ONE detector.", iResult, wordNdx );
1587       iResult = -1;
1588       break;
1589     }
1590   }
1591
1592   return iResult;
1593 }