]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTSystem.cxx
823e502a02f65a07c7b8a372207a44ba70e3928a
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTSystem.cxx
1 // $Id$
2
3 /**************************************************************************
4  * This file is property of and copyright by the ALICE HLT Project        * 
5  * ALICE Experiment at CERN, All rights reserved.                         *
6  *                                                                        *
7  * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8  *                  for The ALICE HLT Project.                            *
9  *                                                                        *
10  * Permission to use, copy, modify and distribute this software and its   *
11  * documentation strictly for non-commercial purposes is hereby granted   *
12  * without fee, provided that the above copyright notice appears in all   *
13  * copies and that both the copyright notice and this permission notice   *
14  * appear in the supporting documentation. The authors make no claims     *
15  * about the suitability of this software for any purpose. It is          *
16  * provided "as is" without express or implied warranty.                  *
17  **************************************************************************/
18
19 /** @file   AliHLTSystem.cxx
20     @author Matthias Richter
21     @date   
22     @brief  Implementation of HLT module management.
23 */
24
25 #if __GNUC__>= 3
26 using namespace std;
27 #endif
28
29 #include <cassert>
30 #include "AliHLTStdIncludes.h"
31 #include "AliHLTSystem.h"
32 #include "AliHLTComponentHandler.h"
33 #include "AliHLTComponent.h"
34 #include "AliHLTConfiguration.h"
35 #include "AliHLTConfigurationHandler.h"
36 #include "AliHLTTask.h"
37 #include "AliHLTModuleAgent.h"
38 #include "AliHLTOfflineInterface.h"
39 #include <TObjArray.h>
40 #include <TObjString.h>
41 #include <TStopwatch.h>
42 #include <TROOT.h>
43 #include <TInterpreter.h>
44
45 /** HLT default component libraries */
46 const char* kHLTDefaultLibs[]= {
47   "libAliHLTUtil.so", 
48   "libAliHLTTPC.so", 
49   //  "libAliHLTSample.so",
50   "libAliHLTPHOS.so",
51   //"libAliHLTMUON.so",
52   "libAliHLTTRD.so",
53   NULL
54 };
55
56 /** ROOT macro for the implementation of ROOT specific class methods */
57 ClassImp(AliHLTSystem)
58
59 AliHLTSystem::AliHLTSystem()
60   :
61   fpComponentHandler(new AliHLTComponentHandler()),
62   fpConfigurationHandler(new AliHLTConfigurationHandler()),
63   fTaskList(),
64   fState(0),
65   fChains(),
66   fStopwatches(new TObjArray),
67   fEventCount(-1),
68   fGoodEvents(-1)
69 {
70   // see header file for class documentation
71   // or
72   // refer to README to build package
73   // or
74   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
75
76   if (fgNofInstances++>0)
77     HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
78
79   SetGlobalLoggingLevel(kHLTLogDefault);
80   if (fpComponentHandler) {
81     AliHLTComponentEnvironment env;
82     memset(&env, 0, sizeof(AliHLTComponentEnvironment));
83     env.fAllocMemoryFunc=AliHLTSystem::AllocMemory;
84     env.fLoggingFunc=NULL;
85     AliHLTComponentLogSeverity loglevel=fpComponentHandler->GetLocalLoggingLevel();
86     fpComponentHandler->SetLocalLoggingLevel(kHLTLogError);
87     fpComponentHandler->SetEnvironment(&env);
88     fpComponentHandler->LoadLibrary("libAliHLTUtil.so", 0/* do not activate agents */);
89     fgAliLoggingFunc=(AliHLTLogging::AliHLTDynamicMessage)fpComponentHandler->FindSymbol("libAliHLTUtil.so", "AliDynamicMessage");
90     fpComponentHandler->SetLocalLoggingLevel(loglevel);
91     if (fgAliLoggingFunc==NULL) {
92       HLTError("symbol lookp failure: can not find AliDynamicMessage, switching to HLT logging system");
93     }
94     fpComponentHandler->AnnounceVersion();
95   } else {
96     HLTFatal("can not create Component Handler");
97   }
98   if (fpConfigurationHandler) {
99     AliHLTConfiguration::GlobalInit(fpConfigurationHandler);
100   } else {
101     HLTFatal("can not create Configuration Handler");
102   }
103 }
104
105 AliHLTSystem::~AliHLTSystem()
106 {
107   // see header file for class documentation
108   fgNofInstances--;
109   CleanTaskList();
110   AliHLTConfiguration::GlobalDeinit(fpConfigurationHandler);
111   if (fpConfigurationHandler) {
112     delete fpConfigurationHandler;
113   }
114   fpConfigurationHandler=NULL;
115   
116   if (fpComponentHandler) {
117     delete fpComponentHandler;
118   }
119   fpComponentHandler=NULL;
120 }
121
122 int AliHLTSystem::fgNofInstances=0;
123
124 int AliHLTSystem::AddConfiguration(AliHLTConfiguration* pConf)
125 {
126   // see header file for class documentation
127   int iResult=0;
128   if (pConf) {
129   } else {
130     iResult=-EINVAL;
131   }
132   return iResult;
133 }
134
135 int AliHLTSystem::InsertConfiguration(AliHLTConfiguration* pConf, AliHLTConfiguration* pPrec)
136 {
137   // see header file for class documentation
138   int iResult=0;
139   if (pConf) {
140     if (pPrec) {
141       // find the position
142     }
143   } else {
144     iResult=-EINVAL;
145   }
146   return iResult;
147 }
148
149 int AliHLTSystem::DeleteConfiguration(AliHLTConfiguration* pConf)
150 {
151   // see header file for class documentation
152   int iResult=0;
153   if (pConf) {
154   } else {
155     iResult=-EINVAL;
156   }
157   return iResult;
158 }
159
160 int AliHLTSystem::BuildTaskList(const char* id)
161 {
162   // see header file for class documentation
163   int iResult=0;
164   if (id) {
165     if (fpConfigurationHandler) {
166       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(id);
167       if (pConf) {
168         iResult=BuildTaskList(pConf);
169       } else {
170         HLTError("unknown configuration \"%s\"", id);
171         iResult=-EEXIST;
172       }
173     } else {
174       iResult=-EFAULT;
175     }
176   } else {
177     iResult=-EINVAL;
178   }
179   return iResult;
180 }
181
182 int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
183 {
184   // see header file for class documentation
185   int iResult=0;
186   if (pConf) {
187     AliHLTTask* pTask=NULL;
188     if ((pTask=FindTask(pConf->GetName()))!=NULL) {
189       if (pTask->GetConf()!=pConf) {
190         HLTError("configuration missmatch, there is already a task with configuration name \"%s\", but it is different. Most likely configuration %p is not registered properly", pConf->GetName(), pConf);
191         iResult=-EEXIST;
192       }
193       // task for this configuration exists, terminate
194       pTask=NULL;
195     } else if (pConf->SourcesResolved(1)!=1) {
196         HLTError("configuration \"%s\" has unresolved sources, aborting ...", pConf->GetName());
197         iResult=-ENOLINK;
198     } else {
199       pTask=new AliHLTTask(pConf);
200       if (pTask==NULL) {
201         iResult=-ENOMEM;
202       }
203     }
204     static int iterationLevel=0;
205     if (pTask && iResult>=0) {
206       // check for circular dependencies
207       if ((iResult=pConf->FollowDependency(pConf->GetName()))>0) {
208         HLTError("detected circular dependency for configuration \"%s\"", pTask->GetName());
209         pTask->PrintDependencyTree(pTask->GetName(), 1/*use the configuration list*/);
210         HLTError("aborted ...");
211         iResult=-ELOOP;
212       }
213       if (iResult>=0) {
214         // check whether all dependencies are already in the task list
215         // create the missing ones
216         // this step is an iterative process which calls this function again for the missing
217         // configurations, in order to avoid the currently processed task to be created
218         // again it is added to the list temporarily and removed afterwards
219         // This is of high importance to preserve the order of the tasks. Furthermore, the
220         // InsertTask method has to be used in order to set all the cross links right 
221         fTaskList.Add(pTask);
222         AliHLTConfiguration* pDep=pConf->GetFirstSource();
223         while (pDep!=NULL && iResult>=0) {
224           HLTDebug("iteration %d: checking dependency %s (%p)", iterationLevel, pDep->GetName(), pDep);
225           if (FindTask(pDep->GetName())==NULL) {
226             HLTDebug("iteration %d: building task list for configuration %s (%p)", iterationLevel, pDep->GetName(), pDep);
227             iterationLevel++;
228             iResult=BuildTaskList(pDep);
229             iterationLevel--;
230           }
231           pDep=pConf->GetNextSource();
232         }
233         // remove the temporarily added task
234         fTaskList.Remove(pTask);
235
236         // insert the task and set the cross-links
237         if (iResult>=0) {
238           HLTDebug("iteration %d: inserting task %s (%p)", iterationLevel, pTask->GetName(), pTask);
239           iResult=InsertTask(pTask);
240         }
241       } else {
242         delete pTask;
243         pTask=NULL;
244       }
245     }
246   } else {
247     iResult=-EINVAL;
248   }
249   return iResult;
250 }
251
252 int AliHLTSystem::CleanTaskList()
253 {
254   // see header file for class documentation
255   int iResult=0;
256   TObjLink* lnk=NULL;
257   while ((lnk=fTaskList.LastLink())!=NULL) {
258     delete (lnk->GetObject());
259     fTaskList.Remove(lnk);
260   }
261   return iResult;
262 }
263
264 int AliHLTSystem::InsertTask(AliHLTTask* pTask)
265 {
266   // see header file for class documentation
267   int iResult=0;
268   TObjLink *lnk = NULL;
269   if ((iResult=pTask->CheckDependencies())>0)
270     lnk=fTaskList.FirstLink();
271   while (lnk && iResult>0) {
272     AliHLTTask* pCurr = (AliHLTTask*)lnk->GetObject();
273     //HLTDebug("checking  \"%s\"", pCurr->GetName());
274     iResult=pTask->Depends(pCurr);
275     if (iResult>0) {
276       iResult=pTask->SetDependency(pCurr);
277       pCurr->SetTarget(pTask);
278       HLTDebug("set dependency  \"%s\" for configuration \"%s\"", pCurr->GetName(), pTask->GetName());
279     }
280     if (pCurr->Depends(pTask)) {
281       // circular dependency
282       HLTError("circular dependency: can not resolve dependencies for configuration \"%s\"", pTask->GetName());
283       iResult=-ELOOP;
284     } else if ((iResult=pTask->CheckDependencies())>0) {
285       lnk = lnk->Next();
286     }
287   }
288   if (iResult==0) {
289       if (lnk) {
290         fTaskList.AddAfter(lnk, pTask);
291       } else {
292         fTaskList.AddFirst(pTask);
293       }
294       HLTDebug("task \"%s\" (%p) inserted (size %d)", pTask->GetName(), pTask, sizeof(AliHLTTask));
295   } else if (iResult>0) {
296     HLTError("can not resolve dependencies for configuration \"%s\" (%d unresolved)", pTask->GetName(), iResult);
297     iResult=-ENOLINK;
298   }
299   return iResult;
300 }
301
302 AliHLTTask* AliHLTSystem::FindTask(const char* id)
303 {
304   // see header file for class documentation
305   AliHLTTask* pTask=NULL;
306   if (id) {
307     pTask=dynamic_cast<AliHLTTask*>(fTaskList.FindObject(id)); 
308   }
309   return pTask;
310 }
311
312 void AliHLTSystem::PrintTaskList()
313 {
314   // see header file for class documentation
315   HLTLogKeyword("task list");
316   TObjLink *lnk = NULL;
317   HLTMessage("Task List");
318   lnk=fTaskList.FirstLink();
319   while (lnk) {
320     TObject* obj=lnk->GetObject();
321     if (obj) {
322       HLTMessage("  %s - status:", obj->GetName());
323       AliHLTTask* pTask=(AliHLTTask*)obj;
324       pTask->PrintStatus();
325     } else {
326     }
327     lnk = lnk->Next();
328   }
329 }
330
331 int AliHLTSystem::Run(Int_t iNofEvents, int bStop)
332 {
333   // see header file for class documentation
334   int iResult=0;
335   int iCount=0;
336   SetStatusFlags(kRunning);
337   if (fEventCount>=0 || (iResult=InitTasks())>=0) {
338     if (fEventCount>=0 || (iResult=StartTasks())>=0) {
339       if (fEventCount==0) {
340         InitBenchmarking(fStopwatches);
341       } else {
342         //ResumeBenchmarking(fStopwatches);    
343       }
344       for (int i=fEventCount; i<fEventCount+iNofEvents && iResult>=0; i++) {
345         if ((iResult=ProcessTasks(i))>=0) {
346           fGoodEvents++;
347           iCount++;
348         } else {
349           // TODO: define different running modes to either ignore errors in
350           // event processing or not
351           // currently ignored 
352           iResult=0;
353         }
354       }
355       fEventCount+=iNofEvents;
356       if (bStop) StopTasks();
357       //else PauseBenchmarking(fStopwatches);
358     }
359     if (bStop) DeinitTasks();
360   }
361   if (iResult>=0) {
362     iResult=iCount;
363   } else  if (iResult==-ENOKEY) {
364     iResult=0; // do not propagate the error
365   }
366   ClearStatusFlags(kRunning);
367   return iResult;
368 }
369
370 int AliHLTSystem::InitTasks()
371 {
372   // see header file for class documentation
373   int iResult=0;
374   TObjLink *lnk=fTaskList.FirstLink();
375
376   if (lnk==NULL) {
377     HLTWarning("Task list is empty, aborting ...");
378     return -ENOKEY;
379   }
380   while (lnk && iResult>=0) {
381     TObject* obj=lnk->GetObject();
382     if (obj) {
383       AliHLTTask* pTask=(AliHLTTask*)obj;
384       iResult=pTask->Init(NULL, fpComponentHandler);
385     } else {
386     }
387     lnk = lnk->Next();
388   }
389   if (iResult<0) {
390     HLTError("can not initialize task list, error %d", iResult);
391   }
392
393   return iResult;
394 }
395
396 int AliHLTSystem::InitBenchmarking(TObjArray* pStopwatches)
397 {
398   // see header file for class documentation
399   int iResult=0;
400   if (pStopwatches==NULL) return 0;
401
402   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
403     TStopwatch* pStopwatch= new TStopwatch;
404     if (pStopwatch) {
405       pStopwatch->Reset();
406       pStopwatches->AddAt(pStopwatch, i);
407     } else {
408       iResult=-ENOMEM;
409       break;
410     }
411   }
412
413   TObjLink *lnk=fTaskList.FirstLink();
414   while (lnk && iResult>=0) {
415     TObject* obj=lnk->GetObject();
416     if (obj) {
417       AliHLTTask* pTask=(AliHLTTask*)obj;
418       AliHLTComponent* pComp=NULL;
419       if (iResult>=0 && (pComp=pTask->GetComponent())!=NULL) {
420         switch (pComp->GetComponentType()) {
421         case AliHLTComponent::kProcessor:
422           pComp->SetStopwatches(pStopwatches);
423           break;
424         case AliHLTComponent::kSource:
425           {
426             // this switch determines whether the time consumption of the
427             // AliHLTComponent base methods should be counted to the input
428             // stopwatch or base stopwatch.
429             //int inputBase=(int)AliHLTComponent::kSWBase;
430             int inputBase=(int)AliHLTComponent::kSWInput;
431             pComp->SetStopwatch(pStopwatches->At(inputBase), AliHLTComponent::kSWBase);
432             pComp->SetStopwatch(pStopwatches->At((int)AliHLTComponent::kSWInput), AliHLTComponent::kSWDA);
433           }
434           break;
435         case AliHLTComponent::kSink:
436           {
437             // this switch determines whether the time consumption of the
438             // AliHLTComponent base methods should be counted to the output
439             // stopwatch or base stopwatch.
440             //int outputBase=(int)AliHLTComponent::kSWBase;
441             int outputBase=(int)AliHLTComponent::kSWOutput;
442             pComp->SetStopwatch(pStopwatches->At(outputBase), AliHLTComponent::kSWBase);
443             pComp->SetStopwatch(pStopwatches->At((int)AliHLTComponent::kSWOutput), AliHLTComponent::kSWDA);
444           }
445           break;
446         default:
447           HLTWarning("unknown component type %d", (int)pComp->GetComponentType());
448         }
449       }
450     } else {
451     }
452     lnk = lnk->Next();
453   }
454   return iResult;
455 }
456
457 int AliHLTSystem::PrintBenchmarking(TObjArray* pStopwatches, int bClean)
458 {
459   // see header file for class documentation
460   int iInitialized=1;
461   if (pStopwatches==NULL) return 0;
462
463   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
464     if (!dynamic_cast<TStopwatch*>(pStopwatches->At(i))) {
465       iInitialized=0;
466       break;
467     }
468   }
469
470   if (iInitialized!=0) {
471     HLTInfo("HLT statistics:\n"
472             "    base:              R:%.3fs C:%.3fs\n"
473             "    input:             R:%.3fs C:%.3fs\n"
474             "    output:            R:%.3fs C:%.3fs\n"
475             "    event processing : R:%.3fs C:%.3fs"
476             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWBase))->RealTime()
477             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWBase))->CpuTime()
478             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWInput))->RealTime()
479             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWInput))->CpuTime()
480             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWOutput))->RealTime()
481             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWOutput))->CpuTime()
482             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWDA))->RealTime()
483             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWDA))->CpuTime()
484             );
485   }
486
487   if (bClean) {
488     for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
489       TObject* pObj=pStopwatches->RemoveAt(i);
490       if (pObj) delete pObj;
491     }
492   }
493   return 0;
494 }
495
496 int AliHLTSystem::StartTasks()
497 {
498   // see header file for class documentation
499   int iResult=0;
500   TObjLink *lnk=fTaskList.FirstLink();
501   while (lnk && iResult>=0) {
502     TObject* obj=lnk->GetObject();
503     if (obj) {
504       AliHLTTask* pTask=(AliHLTTask*)obj;
505       iResult=pTask->StartRun();
506     } else {
507     }
508     lnk = lnk->Next();
509   }
510   if (iResult<0) {
511     HLTError("can not start task list, error %d", iResult);
512   } else {
513     fEventCount=0;
514     fGoodEvents=0;
515   }
516   return iResult;
517 }
518
519 int AliHLTSystem::ProcessTasks(Int_t eventNo)
520 {
521   // see header file for class documentation
522   int iResult=0;
523   HLTDebug("processing event no %d", eventNo);
524   TObjLink *lnk=fTaskList.FirstLink();
525   while (lnk && iResult>=0) {
526     TObject* obj=lnk->GetObject();
527     if (obj) {
528       AliHLTTask* pTask=(AliHLTTask*)obj;
529       iResult=pTask->ProcessTask(eventNo);
530       HLTDebug("task %s finnished (%d)", pTask->GetName(), iResult);
531     } else {
532     }
533     lnk = lnk->Next();
534   }
535
536   if (iResult>=0) {
537     HLTInfo("Event %d successfully finished (%d)", eventNo, iResult);
538     iResult=0;
539   } else {
540     HLTError("Processing of event %d failed (%d)", eventNo, iResult);
541   }
542
543   return iResult;
544 }
545
546 int AliHLTSystem::StopTasks()
547 {
548   // see header file for class documentation
549   int iResult=0;
550   TObjLink *lnk=fTaskList.FirstLink();
551   while (lnk && iResult>=0) {
552     TObject* obj=lnk->GetObject();
553     if (obj) {
554       AliHLTTask* pTask=(AliHLTTask*)obj;
555       iResult=pTask->EndRun();
556     } else {
557     }
558     lnk = lnk->Next();
559   }
560   PrintBenchmarking(fStopwatches, 1 /*clean*/);
561   return iResult;
562 }
563
564 int AliHLTSystem::DeinitTasks()
565 {
566   // see header file for class documentation
567   int iResult=0;
568   TObjLink *lnk=fTaskList.FirstLink();
569   while (lnk && iResult>=0) {
570     TObject* obj=lnk->GetObject();
571     if (obj) {
572       AliHLTTask* pTask=(AliHLTTask*)obj;
573       iResult=pTask->Deinit();
574     } else {
575     }
576     lnk = lnk->Next();
577   }
578   fEventCount=-1;
579   fGoodEvents=-1;
580
581   return iResult;
582 }
583
584 void* AliHLTSystem::AllocMemory( void* /*param*/, unsigned long size )
585 {
586   // see header file for class documentation
587   void* p=NULL;
588   try {
589     p=(void*)new char[size];
590   }
591   catch (...) {
592     AliHLTLogging log;
593     log.LoggingVarargs(kHLTLogError, "AliHLTSystem" , "AllocMemory" , __FILE__ , __LINE__ , "exeption during memory allocation" );
594   }
595   return p;
596 }
597
598 int AliHLTSystem::Reconstruct(int nofEvents, AliRunLoader* runLoader, 
599                               AliRawReader* rawReader)
600 {
601   // see header file for class documentation
602   int iResult=0;
603   if (runLoader || rawReader || nofEvents==0) {
604     if (nofEvents>0) {HLTInfo("Run Loader %p, Raw Reader %p , %d event(s)", runLoader, rawReader, nofEvents);}
605     if (CheckStatus(kReady)) {
606       if (nofEvents==0) {
607         // special case to close the reconstruction
608         if (!CheckStatus(kError)) {
609         StopTasks();
610         DeinitTasks();
611         }
612       } else {
613       if ((iResult=AliHLTOfflineInterface::SetParamsToComponents(runLoader, rawReader))>=0) {
614         // the system always remains started after event processing, a specific
615         // call with nofEvents==0 is needed to execute the stop sequence
616         if ((iResult=Run(nofEvents, 0))<0) SetStatusFlags(kError);
617       }
618       }
619     } else {
620       HLTError("wrong state %#x, required flags %#x", GetStatusFlags(), kReady);
621     }
622   } else {
623     HLTError("missing RunLoader (%p)/RawReader (%p) instance", runLoader, rawReader);
624     iResult=-EINVAL;
625   }
626   return iResult;
627 }
628
629 int AliHLTSystem::FillESD(int eventNo, AliRunLoader* runLoader, AliESDEvent* esd)
630 {
631   // see header file for class documentation
632   int iResult=0;
633   if (runLoader || esd) {
634     HLTInfo("Event %d: Run Loader %p, ESD %p", eventNo, runLoader, esd);
635     iResult=AliHLTOfflineInterface::FillComponentESDs(eventNo, runLoader, esd);
636   } else {
637     HLTError("missing run loader/ESD instance(s)");
638     iResult=-EINVAL;
639   }
640   return iResult;
641 }
642
643 int AliHLTSystem::LoadComponentLibraries(const char* libraries)
644 {
645   // see header file for class documentation
646   int iResult=0;
647   if (libraries) {
648     if (fpComponentHandler) {
649       TString libs(libraries);
650       TObjArray* pTokens=libs.Tokenize(" ");
651       if (pTokens) {
652         int iEntries=pTokens->GetEntries();
653         for (int i=0; i<iEntries && iResult>=0; i++) {
654           iResult=fpComponentHandler->LoadLibrary((((TObjString*)pTokens->At(i))->GetString()).Data());
655         }
656         delete pTokens;
657       }
658       if (iResult>=0) {
659         SetStatusFlags(kLibrariesLoaded);
660       } else {
661         // lets see if we need this, probably not
662         //fpComponentHandler->UnloadLibraries();
663         ClearStatusFlags(kLibrariesLoaded);
664       }
665     } else {
666       iResult=-EFAULT;
667       HLTFatal("no component handler available");
668     }
669   } else {
670     iResult=-EINVAL;
671   }
672   return iResult;
673 }
674
675 int AliHLTSystem::Configure(AliRunLoader* runloader)
676 {
677   // see header file for class documentation
678   return Configure(NULL, runloader);
679 }
680
681 int AliHLTSystem::Configure(AliRawReader* rawReader, AliRunLoader* runloader)
682 {
683   // see header file for class documentation
684   int iResult=0;
685   if (CheckStatus(kRunning)) {
686     HLTError("HLT system in running state, can not configure");
687     return -EBUSY;
688   }
689   ClearStatusFlags(kConfigurationLoaded|kTaskListCreated);
690   if (CheckFilter(kHLTLogDebug))
691     AliHLTModuleAgent::PrintStatus();
692   if (CheckStatus(kConfigurationLoaded)==0) {
693     iResult=LoadConfigurations(rawReader, runloader);
694   } else {
695     if (fChains.Length()==0) {
696       HLTError("custom configuration(s) specified, but no configuration to run in local reconstruction, use \'localrec=<conf>\' option");
697       iResult=-ENOENT;
698     }
699   }
700   if (iResult>=0) {
701     SetStatusFlags(kConfigurationLoaded);
702     if (CheckFilter(kHLTLogDebug))
703       fpConfigurationHandler->PrintConfigurations();
704     iResult=BuildTaskListsFromReconstructionChains(rawReader, runloader);
705     if (iResult>=0) {
706       SetStatusFlags(kTaskListCreated);
707     }
708   }
709   if (iResult<0) SetStatusFlags(kError);
710   
711   return iResult;
712 }
713
714 int AliHLTSystem::ScanOptions(const char* options)
715 {
716   // see header file for class documentation
717   int iResult=0;
718   if (options) {
719     TString libs("");
720     TString alloptions(options);
721     TObjArray* pTokens=alloptions.Tokenize(" ");
722     if (pTokens) {
723       int iEntries=pTokens->GetEntries();
724       for (int i=0; i<iEntries; i++) {
725         TString token=(((TObjString*)pTokens->At(i))->GetString());
726         if (token.Contains("loglevel=")) {
727           TString param=token.ReplaceAll("loglevel=", "");
728           if (param.IsDigit()) {
729             SetGlobalLoggingLevel((AliHLTComponentLogSeverity)param.Atoi());
730           } else if (param.BeginsWith("0x") &&
731                      param.Replace(0,2,"",0).IsHex()) {
732             int severity=0;
733             sscanf(param.Data(),"%x", &severity);
734             SetGlobalLoggingLevel((AliHLTComponentLogSeverity)severity);
735           } else {
736             HLTWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
737           }
738         } else if (token.Contains("alilog=off")) {
739           SwitchAliLog(0);
740         } else if (token.Contains("config=")) {
741           TString param=token.ReplaceAll("config=", "");
742           Int_t error=0;
743           gROOT->Macro(param.Data(), &error);
744           if (error==0) {
745             SetStatusFlags(kConfigurationLoaded);
746           } else {
747             HLTError("can not execute macro \'%s\'", param.Data());
748             iResult=-EBADF;
749           }
750         } else if (token.Contains("chains=")) {
751           TString param=token.ReplaceAll("chains=", "");
752           fChains=param.ReplaceAll(",", " ");
753         } else if (token.BeginsWith("lib") && token.EndsWith(".so")) {
754           libs+=token;
755           libs+=" ";
756         } else {
757           HLTWarning("unknown option \'%s\'", token.Data());
758         }
759       }
760       delete pTokens;
761     }
762
763     if (iResult>=0) {
764       if (libs.IsNull()) {
765         const char** deflib=kHLTDefaultLibs;
766         while (*deflib) {
767           libs+=*deflib++;
768           libs+=" ";
769         }
770       }
771       if ((!CheckStatus(AliHLTSystem::kLibrariesLoaded)) &&
772           (LoadComponentLibraries(libs.Data())<0)) {
773         HLTError("error while loading HLT libraries");
774         iResult=-EFAULT;
775       }
776     }
777   }
778   return iResult;
779 }
780
781 int AliHLTSystem::Reset(int bForce)
782 {
783   // see header file for class documentation
784   int iResult=0;
785   if (!bForce && CheckStatus(kRunning)) {
786     HLTError("HLT system in running state, can not configure");
787     return -EBUSY;
788   }
789   CleanTaskList();
790   ClearStatusFlags(~kUninitialized);
791   return iResult;
792 }
793
794 int AliHLTSystem::LoadConfigurations(AliRawReader* rawReader, AliRunLoader* runloader)
795 {
796   // see header file for class documentation
797   if (CheckStatus(kRunning)) {
798     HLTError("HLT system in running state, can not configure");
799     return -EBUSY;
800   }
801   int iResult=0;
802   AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
803   while (pAgent && iResult>=0) {
804     const char* deplibs=pAgent->GetRequiredComponentLibraries();
805     if (deplibs) {
806       HLTDebug("load libraries \'%s\' for agent %s (%p)", deplibs, pAgent->GetName(), pAgent);
807       iResult=LoadComponentLibraries(deplibs);
808     }
809     if (iResult>=0) {
810       HLTDebug("load configurations for agent %s (%p)", pAgent->GetName(), pAgent);
811       pAgent->CreateConfigurations(fpConfigurationHandler, rawReader, runloader);
812       pAgent=AliHLTModuleAgent::GetNextAgent();
813     }
814   }
815   return iResult;
816 }
817
818 int AliHLTSystem::BuildTaskListsFromReconstructionChains(AliRawReader* rawReader, AliRunLoader* runloader)
819 {
820   // see header file for class documentation
821   if (CheckStatus(kRunning)) {
822     HLTError("HLT system in running state, can not configure");
823     return -EBUSY;
824   }
825   if (!CheckStatus(kConfigurationLoaded)) {
826     HLTWarning("configurations not yet loaded");
827     return 0;
828   }
829
830   int iResult=0;
831   int bHaveOutput=0;
832
833   // query chains
834   TString chains;
835   if (fChains.Length()>0) {
836     chains=fChains;
837     HLTInfo("custom reconstruction chain: %s", chains.Data());
838   } else {
839     AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
840     while ((pAgent || fChains.Length()>0) && iResult>=0) {
841       const char* agentchains=pAgent->GetReconstructionChains(rawReader, runloader);
842       if (agentchains) {
843         if (!chains.IsNull()) chains+="";
844         chains+=agentchains;
845         HLTInfo("reconstruction chains for agent %s (%p): %s", pAgent->GetName(), pAgent, agentchains);
846       }
847       pAgent=AliHLTModuleAgent::GetNextAgent();
848     }
849   }
850
851   // build task list for chains
852   TObjArray* pTokens=chains.Tokenize(" ");
853   if (pTokens) {
854     int iEntries=pTokens->GetEntries();
855     for (int i=0; i<iEntries && iResult>=0; i++) {
856       const char* pCID=((TObjString*)pTokens->At(i))->GetString().Data();
857       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(pCID);
858       if (pConf) {
859         iResult=BuildTaskList(pConf);
860         if (runloader) {
861           assert(fpComponentHandler!=NULL);
862           TString cid=pConf->GetComponentID();
863           if (cid.CompareTo("HLTOUT")==0) {
864             // remove from the input of a global HLTOUT configuration
865             chains.ReplaceAll(pCID, "");
866           } else if (bHaveOutput==0) {
867             // check whether this configuration produces data output
868             if ((bHaveOutput=fpComponentHandler->HasOutputData(cid.Data()))<0) {
869               bHaveOutput=0;
870               chains.ReplaceAll(pCID, "");
871             }
872           }
873         }
874       } else {
875         HLTWarning("can not find configuration %s", pCID);
876       }
877     }
878     delete pTokens;
879   }
880
881   // build HLTOUT for simulation
882   if (iResult>=0 && runloader) {
883     if (bHaveOutput) {
884       // there are components in the chain which produce data which need to be
885       // piped to an HLTOUT
886       if (fpComponentHandler->FindComponentIndex("HLTOUT")>=0 ||
887           LoadComponentLibraries("libHLTsim.so")>=0) {
888         AliHLTConfiguration globalout("_globalout_", "HLTOUT", chains.Data(), NULL);
889         iResult=BuildTaskList("_globalout_");
890       } else {
891         HLTError("can not load libHLTsim.so and HLTOUT component");
892         iResult=-EFAULT;
893       }
894     }
895   }
896
897   if (iResult>=0) SetStatusFlags(kTaskListCreated);
898
899   return iResult;
900 }
901
902 int AliHLTSystem::CheckStatus(int flag)
903 {
904   // see header file for class documentation
905   if (flag==kUninitialized && flag==fState) return 1;
906   if ((fState&flag)==flag) return 1;
907   return 0;
908 }
909
910 int AliHLTSystem::GetStatusFlags()
911 {
912   // see header file for class documentation
913   return fState;
914 }
915
916 int AliHLTSystem::SetStatusFlags(int flags)
917 {
918   // see header file for class documentation
919   fState|=flags;
920   return fState;
921 }
922
923 int AliHLTSystem::ClearStatusFlags(int flags)
924 {
925   // see header file for class documentation
926   fState&=~flags;
927   return fState;
928 }
929
930 void* AliHLTSystem::FindDynamicSymbol(const char* library, const char* symbol)
931 {
932   // see header file for class documentation
933   if (fpComponentHandler==NULL) return NULL;
934   return fpComponentHandler->FindSymbol(library, symbol);
935 }