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