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