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