]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/BASE/AliHLTSystem.cxx
implementation of SOR and EOR events (not yet enabled), bugfix in DataBuffer: data...
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTSystem.cxx
index 4c33d4173fc0011b417891f8d825b49ff7664fad..2c7387a4941935d489e2bc96432a413a4128ce2e 100644 (file)
@@ -1,10 +1,11 @@
 // $Id$
 
 /**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
  *                                                                        *
- * Authors: Matthias Richter <Matthias.Richter@ift.uib.no>                *
- *          for The ALICE Off-line Project.                               *
+ * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
+ *                  for The ALICE HLT Project.                            *
  *                                                                        *
  * Permission to use, copy, modify and distribute this software and its   *
  * documentation strictly for non-commercial purposes is hereby granted   *
     @brief  Implementation of HLT module management.
 */
 
+// see header file for class documentation
+// or
+// refer to README to build package
+// or
+// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt   
+
 #if __GNUC__>= 3
 using namespace std;
 #endif
 
+#include <cassert>
 #include "AliHLTStdIncludes.h"
 #include "AliHLTSystem.h"
 #include "AliHLTComponentHandler.h"
@@ -34,10 +42,24 @@ using namespace std;
 #include "AliHLTTask.h"
 #include "AliHLTModuleAgent.h"
 #include "AliHLTOfflineInterface.h"
+#include "AliHLTDataSource.h"
 #include <TObjArray.h>
 #include <TObjString.h>
-#include <TString.h>
 #include <TStopwatch.h>
+//#include <TSystem.h>
+#include <TROOT.h>
+//#include <TInterpreter.h>
+
+/** HLT default component libraries */
+const char* AliHLTSystem::fgkHLTDefaultLibs[]= {
+  "libAliHLTUtil.so", 
+  "libAliHLTTPC.so", 
+  //  "libAliHLTSample.so",
+  //"libAliHLTPHOS.so",
+  //"libAliHLTMUON.so",
+  "libAliHLTTRD.so",
+  NULL
+};
 
 /** ROOT macro for the implementation of ROOT specific class methods */
 ClassImp(AliHLTSystem)
@@ -47,7 +69,11 @@ AliHLTSystem::AliHLTSystem()
   fpComponentHandler(new AliHLTComponentHandler()),
   fpConfigurationHandler(new AliHLTConfigurationHandler()),
   fTaskList(),
-  fState(0)
+  fState(0),
+  fChains(),
+  fStopwatches(new TObjArray),
+  fEventCount(-1),
+  fGoodEvents(-1)
 {
   // see header file for class documentation
   // or
@@ -59,12 +85,15 @@ AliHLTSystem::AliHLTSystem()
     HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
 
   SetGlobalLoggingLevel(kHLTLogDefault);
+  SetFrameworkLog(kHLTLogDefault);
   if (fpComponentHandler) {
     AliHLTComponentEnvironment env;
     memset(&env, 0, sizeof(AliHLTComponentEnvironment));
     env.fAllocMemoryFunc=AliHLTSystem::AllocMemory;
     env.fLoggingFunc=NULL;
     fpComponentHandler->SetEnvironment(&env);
+    InitAliLogFunc(fpComponentHandler);
+    fpComponentHandler->AnnounceVersion();
   } else {
     HLTFatal("can not create Component Handler");
   }
@@ -75,28 +104,6 @@ AliHLTSystem::AliHLTSystem()
   }
 }
 
-AliHLTSystem::AliHLTSystem(const AliHLTSystem&)
-  :
-  AliHLTLogging(),
-  fpComponentHandler(NULL),
-  fpConfigurationHandler(NULL),
-  fTaskList(),
-  fState(0)
-{
-  // see header file for class documentation
-  if (fgNofInstances++>0)
-    HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
-
-  HLTFatal("copy constructor untested");
-}
-
-AliHLTSystem& AliHLTSystem::operator=(const AliHLTSystem&)
-{ 
-  // see header file for class documentation
-  HLTFatal("assignment operator untested");
-  return *this;
-}
-
 AliHLTSystem::~AliHLTSystem()
 {
   // see header file for class documentation
@@ -119,8 +126,11 @@ int AliHLTSystem::fgNofInstances=0;
 int AliHLTSystem::AddConfiguration(AliHLTConfiguration* pConf)
 {
   // see header file for class documentation
+  HLTLogKeyword("configuration handling");
   int iResult=0;
   if (pConf) {
+    HLTError("function not yet implemented");
+    iResult=-ENOSYS;
   } else {
     iResult=-EINVAL;
   }
@@ -130,10 +140,13 @@ int AliHLTSystem::AddConfiguration(AliHLTConfiguration* pConf)
 int AliHLTSystem::InsertConfiguration(AliHLTConfiguration* pConf, AliHLTConfiguration* pPrec)
 {
   // see header file for class documentation
+  HLTLogKeyword("configuration handling");
   int iResult=0;
   if (pConf) {
     if (pPrec) {
       // find the position
+      HLTError("function not yet implemented");
+      iResult=-ENOSYS;
     }
   } else {
     iResult=-EINVAL;
@@ -144,8 +157,33 @@ int AliHLTSystem::InsertConfiguration(AliHLTConfiguration* pConf, AliHLTConfigur
 int AliHLTSystem::DeleteConfiguration(AliHLTConfiguration* pConf)
 {
   // see header file for class documentation
+  HLTLogKeyword("configuration handling");
   int iResult=0;
   if (pConf) {
+    HLTError("function not yet implemented");
+    iResult=-ENOSYS;
+  } else {
+    iResult=-EINVAL;
+  }
+  return iResult;
+}
+
+int AliHLTSystem::BuildTaskList(const char* id)
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (id) {
+    if (fpConfigurationHandler) {
+      AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(id);
+      if (pConf) {
+       iResult=BuildTaskList(pConf);
+      } else {
+       HLTError("unknown configuration \"%s\"", id);
+       iResult=-EEXIST;
+      }
+    } else {
+      iResult=-EFAULT;
+    }
   } else {
     iResult=-EINVAL;
   }
@@ -162,8 +200,9 @@ int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
       if (pTask->GetConf()!=pConf) {
        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);
        iResult=-EEXIST;
-       pTask=NULL;
       }
+      // task for this configuration exists, terminate
+      pTask=NULL;
     } else if (pConf->SourcesResolved(1)!=1) {
        HLTError("configuration \"%s\" has unresolved sources, aborting ...", pConf->GetName());
        iResult=-ENOLINK;
@@ -171,9 +210,12 @@ int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
       pTask=new AliHLTTask(pConf);
       if (pTask==NULL) {
        iResult=-ENOMEM;
+      } else {
+       pTask->SetLocalLoggingLevel(GetLocalLoggingLevel());
       }
     }
-    if (pTask) {
+    static int iterationLevel=0;
+    if (pTask && iResult>=0) {
       // check for circular dependencies
       if ((iResult=pConf->FollowDependency(pConf->GetName()))>0) {
        HLTError("detected circular dependency for configuration \"%s\"", pTask->GetName());
@@ -192,8 +234,12 @@ int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
        fTaskList.Add(pTask);
        AliHLTConfiguration* pDep=pConf->GetFirstSource();
        while (pDep!=NULL && iResult>=0) {
+         HLTDebug("iteration %d: checking dependency %s (%p)", iterationLevel, pDep->GetName(), pDep);
          if (FindTask(pDep->GetName())==NULL) {
+           HLTDebug("iteration %d: building task list for configuration %s (%p)", iterationLevel, pDep->GetName(), pDep);
+           iterationLevel++;
            iResult=BuildTaskList(pDep);
+           iterationLevel--;
          }
          pDep=pConf->GetNextSource();
        }
@@ -202,6 +248,7 @@ int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
 
        // insert the task and set the cross-links
        if (iResult>=0) {
+         HLTDebug("iteration %d: inserting task %s (%p)", iterationLevel, pTask->GetName(), pTask);
          iResult=InsertTask(pTask);
        }
       } else {
@@ -220,9 +267,9 @@ int AliHLTSystem::CleanTaskList()
   // see header file for class documentation
   int iResult=0;
   TObjLink* lnk=NULL;
-  while ((lnk=fTaskList.FirstLink())!=NULL) {
-    fTaskList.Remove(lnk);
+  while ((lnk=fTaskList.LastLink())!=NULL) {
     delete (lnk->GetObject());
+    fTaskList.Remove(lnk);
   }
   return iResult;
 }
@@ -257,7 +304,7 @@ int AliHLTSystem::InsertTask(AliHLTTask* pTask)
       } else {
        fTaskList.AddFirst(pTask);
       }
-      HLTDebug("task \"%s\" inserted", pTask->GetName());
+      HLTDebug("task \"%s\" (%p) inserted (size %d)", pTask->GetName(), pTask, sizeof(AliHLTTask));
   } else if (iResult>0) {
     HLTError("can not resolve dependencies for configuration \"%s\" (%d unresolved)", pTask->GetName(), iResult);
     iResult=-ENOLINK;
@@ -270,7 +317,7 @@ AliHLTTask* AliHLTSystem::FindTask(const char* id)
   // see header file for class documentation
   AliHLTTask* pTask=NULL;
   if (id) {
-    pTask=(AliHLTTask*)fTaskList.FindObject(id); 
+    pTask=dynamic_cast<AliHLTTask*>(fTaskList.FindObject(id)); 
   }
   return pTask;
 }
@@ -294,56 +341,40 @@ void AliHLTSystem::PrintTaskList()
   }
 }
 
-int AliHLTSystem::Run(Int_t iNofEvents
+int AliHLTSystem::Run(Int_t iNofEvents, int bStop)
 {
   // see header file for class documentation
   int iResult=0;
   int iCount=0;
   SetStatusFlags(kRunning);
-  TStopwatch StopwatchBase; StopwatchBase.Reset();
-  TStopwatch StopwatchDA; StopwatchDA.Reset();
-  TStopwatch StopwatchInput; StopwatchInput.Reset();
-  TStopwatch StopwatchOutput; StopwatchOutput.Reset();
-  TObjArray Stopwatches;
-  Stopwatches.AddAt(&StopwatchBase, (int)AliHLTComponent::kSWBase);
-  Stopwatches.AddAt(&StopwatchDA, (int)AliHLTComponent::kSWDA);
-  Stopwatches.AddAt(&StopwatchInput, (int)AliHLTComponent::kSWInput);
-  Stopwatches.AddAt(&StopwatchOutput, (int)AliHLTComponent::kSWOutput);
-  if ((iResult=InitTasks())>=0 && (iResult=InitBenchmarking(&Stopwatches))>=0) {
-    if ((iResult=StartTasks())>=0) {
-      for (int i=0; i<iNofEvents && iResult>=0; i++) {
-       iResult=ProcessTasks(i);
-       if (iResult>=0) {
-         HLTInfo("Event %d successfully finished (%d)", i, iResult);
-         iResult=0;
+  if (fEventCount>=0 || (iResult=InitTasks())>=0) {
+    if (fEventCount>=0 || (iResult=StartTasks())>=0) {
+      if (fEventCount==0) {
+       InitBenchmarking(fStopwatches);
+      } else {
+       //ResumeBenchmarking(fStopwatches);    
+      }
+      for (int i=fEventCount; i<fEventCount+iNofEvents && iResult>=0; i++) {
+       if ((iResult=ProcessTasks(i))>=0) {
+         fGoodEvents++;
          iCount++;
        } else {
-         HLTError("Processing of event %d failed (%d)", i, iResult);
          // TODO: define different running modes to either ignore errors in
          // event processing or not
          // currently ignored 
-         //iResult=0;
+         iResult=0;
        }
       }
-      StopTasks();
-    } else {
-      HLTError("can not start task list");
+      fEventCount+=iNofEvents;
+      if (bStop) StopTasks();
+      //else PauseBenchmarking(fStopwatches);
     }
-    DeinitTasks();
-  } else if (iResult!=-ENOENT) {
-    HLTError("can not initialize task list");
+    if (bStop) DeinitTasks();
   }
   if (iResult>=0) {
     iResult=iCount;
-    HLTInfo("HLT statistics:\n"
-           "    base:              R:%.3fs C:%.3fs\n"
-           "    input:             R:%.3fs C:%.3fs\n"
-           "    output:            R:%.3fs C:%.3fs\n"
-           "    event processing : R:%.3fs C:%.3fs"
-           , StopwatchBase.RealTime(),StopwatchBase.CpuTime()
-           , StopwatchInput.RealTime(),StopwatchInput.CpuTime()
-           , StopwatchOutput.RealTime(),StopwatchOutput.CpuTime()
-           , StopwatchDA.RealTime(),StopwatchDA.CpuTime());
+  } else  if (iResult==-126 /*ENOKEY*/) {
+    iResult=0; // do not propagate the error
   }
   ClearStatusFlags(kRunning);
   return iResult;
@@ -354,30 +385,47 @@ int AliHLTSystem::InitTasks()
   // see header file for class documentation
   int iResult=0;
   TObjLink *lnk=fTaskList.FirstLink();
+
   if (lnk==NULL) {
     HLTWarning("Task list is empty, aborting ...");
-    return -ENOENT;
+    return -126 /*ENOKEY*/;
   }
   while (lnk && iResult>=0) {
     TObject* obj=lnk->GetObject();
     if (obj) {
       AliHLTTask* pTask=(AliHLTTask*)obj;
       iResult=pTask->Init(NULL, fpComponentHandler);
+//       ProcInfo_t ProcInfo;
+//       gSystem->GetProcInfo(&ProcInfo);
+//       HLTInfo("task %s initialized (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
     } else {
     }
     lnk = lnk->Next();
   }
   if (iResult<0) {
+    HLTError("can not initialize task list, error %d", iResult);
   }
+
   return iResult;
 }
 
 int AliHLTSystem::InitBenchmarking(TObjArray* pStopwatches)
 {
   // see header file for class documentation
-  if (pStopwatches==NULL) return -EINVAL;
-
   int iResult=0;
+  if (pStopwatches==NULL) return 0;
+
+  for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
+    TStopwatch* pStopwatch= new TStopwatch;
+    if (pStopwatch) {
+      pStopwatch->Reset();
+      pStopwatches->AddAt(pStopwatch, i);
+    } else {
+      iResult=-ENOMEM;
+      break;
+    }
+  }
+
   TObjLink *lnk=fTaskList.FirstLink();
   while (lnk && iResult>=0) {
     TObject* obj=lnk->GetObject();
@@ -422,6 +470,45 @@ int AliHLTSystem::InitBenchmarking(TObjArray* pStopwatches)
   return iResult;
 }
 
+int AliHLTSystem::PrintBenchmarking(TObjArray* pStopwatches, int bClean)
+{
+  // see header file for class documentation
+  int iInitialized=1;
+  if (pStopwatches==NULL) return 0;
+
+  for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
+    if (!dynamic_cast<TStopwatch*>(pStopwatches->At(i))) {
+      iInitialized=0;
+      break;
+    }
+  }
+
+  if (iInitialized!=0) {
+    HLTInfo("HLT statistics:\n"
+           "    base:              R:%.3fs C:%.3fs\n"
+           "    input:             R:%.3fs C:%.3fs\n"
+           "    output:            R:%.3fs C:%.3fs\n"
+           "    event processing : R:%.3fs C:%.3fs"
+           , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWBase))->RealTime()
+           , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWBase))->CpuTime()
+           , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWInput))->RealTime()
+           , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWInput))->CpuTime()
+           , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWOutput))->RealTime()
+           , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWOutput))->CpuTime()
+           , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWDA))->RealTime()
+           , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWDA))->CpuTime()
+           );
+  }
+
+  if (bClean) {
+    for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
+      TObject* pObj=pStopwatches->RemoveAt(i);
+      if (pObj) delete pObj;
+    }
+  }
+  return 0;
+}
+
 int AliHLTSystem::StartTasks()
 {
   // see header file for class documentation
@@ -432,11 +519,21 @@ int AliHLTSystem::StartTasks()
     if (obj) {
       AliHLTTask* pTask=(AliHLTTask*)obj;
       iResult=pTask->StartRun();
+//       ProcInfo_t ProcInfo;
+//       gSystem->GetProcInfo(&ProcInfo);
+//       HLTInfo("task %s started (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
     } else {
     }
     lnk = lnk->Next();
   }
   if (iResult<0) {
+    HLTError("can not start task list, error %d", iResult);
+  } else {
+    fEventCount=0;
+    fGoodEvents=0;
+    if ((iResult=SendControlEvent(kAliHLTDataTypeSOR))<0) {
+      HLTError("can not send SOR event");
+    }
   }
   return iResult;
 }
@@ -452,11 +549,21 @@ int AliHLTSystem::ProcessTasks(Int_t eventNo)
     if (obj) {
       AliHLTTask* pTask=(AliHLTTask*)obj;
       iResult=pTask->ProcessTask(eventNo);
-      HLTDebug("task %s finnished (%d)", pTask->GetName(), iResult);
+//       ProcInfo_t ProcInfo;
+//       gSystem->GetProcInfo(&ProcInfo);
+//       HLTInfo("task %s processed (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
     } else {
     }
     lnk = lnk->Next();
   }
+
+  if (iResult>=0) {
+    HLTInfo("Event %d successfully finished (%d)", eventNo, iResult);
+    iResult=0;
+  } else {
+    HLTError("Processing of event %d failed (%d)", eventNo, iResult);
+  }
+
   return iResult;
 }
 
@@ -464,16 +571,51 @@ int AliHLTSystem::StopTasks()
 {
   // see header file for class documentation
   int iResult=0;
+  if ((iResult=SendControlEvent(kAliHLTDataTypeEOR))<0) {
+    HLTError("can not send EOR event");
+  }
+  TObjLink *lnk=fTaskList.FirstLink();
+  while (lnk) {
+    TObject* obj=lnk->GetObject();
+    if (obj) {
+      AliHLTTask* pTask=(AliHLTTask*)obj;
+      int locResult=pTask->EndRun();
+      if (iResult>=0 && locResult<0) iResult=locResult;
+//       ProcInfo_t ProcInfo;
+//       gSystem->GetProcInfo(&ProcInfo);
+//       HLTInfo("task %s stopped (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
+    } else {
+    }
+    lnk = lnk->Next();
+  }
+  PrintBenchmarking(fStopwatches, 1 /*clean*/);
+  return iResult;
+}
+
+int AliHLTSystem::SendControlEvent(AliHLTComponentDataType dt)
+{
+  // see header file for class documentation
+
+  // disabled for the moment
+  return 0;
+
+  int iResult=0;
+  AliHLTRunDesc runDesc;
+  memset(&runDesc, 0, sizeof(AliHLTRunDesc));
+  runDesc.fStructSize=sizeof(AliHLTRunDesc);
+  AliHLTDataSource::AliSpecialEventGuard g(&runDesc, dt, kAliHLTVoidDataSpec);
+  HLTDebug("sending event %s, run descriptor %p", AliHLTComponent::DataType2Text(dt).c_str(), &runDesc);
   TObjLink *lnk=fTaskList.FirstLink();
   while (lnk && iResult>=0) {
     TObject* obj=lnk->GetObject();
     if (obj) {
       AliHLTTask* pTask=(AliHLTTask*)obj;
-      iResult=pTask->EndRun();
+      iResult=pTask->ProcessTask(-1);
     } else {
     }
     lnk = lnk->Next();
   }
+  HLTDebug("event %s done (%d)", AliHLTComponent::DataType2Text(dt).c_str(), iResult);
   return iResult;
 }
 
@@ -487,20 +629,31 @@ int AliHLTSystem::DeinitTasks()
     if (obj) {
       AliHLTTask* pTask=(AliHLTTask*)obj;
       iResult=pTask->Deinit();
+//       ProcInfo_t ProcInfo;
+//       gSystem->GetProcInfo(&ProcInfo);
+//       HLTInfo("task %s cleaned (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
     } else {
     }
     lnk = lnk->Next();
   }
+  fEventCount=-1;
+  fGoodEvents=-1;
+
   return iResult;
 }
 
-void* AliHLTSystem::AllocMemory( void* param, unsigned long size )
+void* AliHLTSystem::AllocMemory( void* /*param*/, unsigned long size )
 {
   // see header file for class documentation
-  if (param==NULL) {
-    // get rid of 'unused parameter' warning
+  void* p=NULL;
+  try {
+    p=(void*)new char[size];
   }
-  return (void*)new char[size];
+  catch (...) {
+    AliHLTLogging log;
+    log.LoggingVarargs(kHLTLogError, "AliHLTSystem" , "AllocMemory" , __FILE__ , __LINE__ , "exeption during memory allocation" );
+  }
+  return p;
 }
 
 int AliHLTSystem::Reconstruct(int nofEvents, AliRunLoader* runLoader, 
@@ -508,27 +661,37 @@ int AliHLTSystem::Reconstruct(int nofEvents, AliRunLoader* runLoader,
 {
   // see header file for class documentation
   int iResult=0;
-  if (runLoader) {
-    HLTInfo("Run Loader %p, Raw Reader %p , %d events", runLoader, rawReader, nofEvents);
+  if (runLoader || rawReader || nofEvents==0) {
+    if (nofEvents>0) {HLTInfo("Run Loader %p, Raw Reader %p , %d event(s)", runLoader, rawReader, nofEvents);}
     if (CheckStatus(kReady)) {
+      if (nofEvents==0) {
+       // special case to close the reconstruction
+       if (!CheckStatus(kError)) {
+       StopTasks();
+       DeinitTasks();
+       }
+      } else {
       if ((iResult=AliHLTOfflineInterface::SetParamsToComponents(runLoader, rawReader))>=0) {
-       iResult=Run(nofEvents);
+       // the system always remains started after event processing, a specific
+       // call with nofEvents==0 is needed to execute the stop sequence
+       if ((iResult=Run(nofEvents, 0))<0) SetStatusFlags(kError);
+      }
       }
     } else {
       HLTError("wrong state %#x, required flags %#x", GetStatusFlags(), kReady);
     }
   } else {
-    HLTError("missing run loader instance");
+    HLTError("missing RunLoader (%p)/RawReader (%p) instance", runLoader, rawReader);
     iResult=-EINVAL;
   }
   return iResult;
 }
 
-int AliHLTSystem::FillESD(int eventNo, AliRunLoader* runLoader, AliESD* esd)
+int AliHLTSystem::FillESD(int eventNo, AliRunLoader* runLoader, AliESDEvent* esd)
 {
   // see header file for class documentation
   int iResult=0;
-  if (runLoader) {
+  if (runLoader || esd) {
     HLTInfo("Event %d: Run Loader %p, ESD %p", eventNo, runLoader, esd);
     iResult=AliHLTOfflineInterface::FillComponentESDs(eventNo, runLoader, esd);
   } else {
@@ -571,6 +734,12 @@ int AliHLTSystem::LoadComponentLibraries(const char* libraries)
 }
 
 int AliHLTSystem::Configure(AliRunLoader* runloader)
+{
+  // see header file for class documentation
+  return Configure(NULL, runloader);
+}
+
+int AliHLTSystem::Configure(AliRawReader* rawReader, AliRunLoader* runloader)
 {
   // see header file for class documentation
   int iResult=0;
@@ -578,13 +747,22 @@ int AliHLTSystem::Configure(AliRunLoader* runloader)
     HLTError("HLT system in running state, can not configure");
     return -EBUSY;
   }
+  ClearStatusFlags(kTaskListCreated);
   if (CheckFilter(kHLTLogDebug))
     AliHLTModuleAgent::PrintStatus();
-  ClearStatusFlags(kConfigurationLoaded|kTaskListCreated);
-  iResult=LoadConfigurations(runloader);
+  if (CheckStatus(kConfigurationLoaded)==0) {
+    iResult=LoadConfigurations(rawReader, runloader);
+  } else {
+    if (fChains.Length()==0) {
+      HLTError("custom configuration(s) specified, but no configuration to run in local reconstruction, use \'localrec=<conf>\' option");
+      iResult=-ENOENT;
+    }
+  }
   if (iResult>=0) {
     SetStatusFlags(kConfigurationLoaded);
-    iResult=BuildTaskListsFromTopConfigurations(runloader);
+    if (CheckFilter(kHLTLogDebug))
+      fpConfigurationHandler->PrintConfigurations();
+    iResult=BuildTaskListsFromReconstructionChains(rawReader, runloader);
     if (iResult>=0) {
       SetStatusFlags(kTaskListCreated);
     }
@@ -594,6 +772,98 @@ int AliHLTSystem::Configure(AliRunLoader* runloader)
   return iResult;
 }
 
+int AliHLTSystem::ScanOptions(const char* options)
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (options) {
+    //AliHLTComponentHandler::TLibraryMode libMode=AliHLTComponentHandler::kDynamic;
+    TString libs("");
+    TString alloptions(options);
+    TObjArray* pTokens=alloptions.Tokenize(" ");
+    if (pTokens) {
+      int iEntries=pTokens->GetEntries();
+      for (int i=0; i<iEntries; i++) {
+       TString token=(((TObjString*)pTokens->At(i))->GetString());
+       if (token.Contains("loglevel=")) {
+         TString param=token.ReplaceAll("loglevel=", "");
+         if (param.IsDigit()) {
+           SetGlobalLoggingLevel((AliHLTComponentLogSeverity)param.Atoi());
+         } else if (param.BeginsWith("0x") &&
+                    param.Replace(0,2,"",0).IsHex()) {
+           int severity=0;
+           sscanf(param.Data(),"%x", &severity);
+           SetGlobalLoggingLevel((AliHLTComponentLogSeverity)severity);
+         } else {
+           HLTWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
+         }
+       } else if (token.Contains("frameworklog=")) {
+         TString param=token.ReplaceAll("frameworklog=", "");
+         if (param.IsDigit()) {
+           SetFrameworkLog((AliHLTComponentLogSeverity)param.Atoi());
+         } else if (param.BeginsWith("0x") &&
+                    param.Replace(0,2,"",0).IsHex()) {
+           int severity=0;
+           sscanf(param.Data(),"%x", &severity);
+           SetFrameworkLog((AliHLTComponentLogSeverity)severity);
+         } else {
+           HLTWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
+         }
+       } else if (token.Contains("alilog=off")) {
+         SwitchAliLog(0);
+       } else if (token.Contains("config=")) {
+         TString param=token.ReplaceAll("config=", "");
+         Int_t error=0;
+         gROOT->Macro(param.Data(), &error);
+         if (error==0) {
+           SetStatusFlags(kConfigurationLoaded);
+         } else {
+           HLTError("can not execute macro \'%s\'", param.Data());
+           iResult=-EBADF;
+         }
+       } else if (token.Contains("chains=")) {
+         TString param=token.ReplaceAll("chains=", "");
+         fChains=param.ReplaceAll(",", " ");
+       } else if (token.Contains("libmode=")) {
+         TString param=token.ReplaceAll("libmode=", "");
+         param.ReplaceAll(",", " ");
+         if (fpComponentHandler) {
+           if (param.CompareTo("static")==0) {
+             fpComponentHandler->SetLibraryMode(AliHLTComponentHandler::kStatic);
+           } else if (param.CompareTo("dynamic")==0) {
+             fpComponentHandler->SetLibraryMode(AliHLTComponentHandler::kDynamic);
+           } else {
+             HLTWarning("wrong argument for option \'libmode=\', use \'static\' or \'dynamic\'");
+           }
+         }
+       } else if (token.BeginsWith("lib") && token.EndsWith(".so")) {
+         libs+=token;
+         libs+=" ";
+       } else {
+         HLTWarning("unknown option \'%s\'", token.Data());
+       }
+      }
+      delete pTokens;
+    }
+
+    if (iResult>=0) {
+      if (libs.IsNull()) {
+       const char** deflib=fgkHLTDefaultLibs;
+       while (*deflib) {
+         libs+=*deflib++;
+         libs+=" ";
+       }
+      }
+      if ((!CheckStatus(AliHLTSystem::kLibrariesLoaded)) &&
+         (LoadComponentLibraries(libs.Data())<0)) {
+       HLTError("error while loading HLT libraries");
+       iResult=-EFAULT;
+      }
+    }
+  }
+  return iResult;
+}
+
 int AliHLTSystem::Reset(int bForce)
 {
   // see header file for class documentation
@@ -607,7 +877,7 @@ int AliHLTSystem::Reset(int bForce)
   return iResult;
 }
 
-int AliHLTSystem::LoadConfigurations(AliRunLoader* runloader)
+int AliHLTSystem::LoadConfigurations(AliRawReader* rawReader, AliRunLoader* runloader)
 {
   // see header file for class documentation
   if (CheckStatus(kRunning)) {
@@ -624,14 +894,14 @@ int AliHLTSystem::LoadConfigurations(AliRunLoader* runloader)
     }
     if (iResult>=0) {
       HLTDebug("load configurations for agent %s (%p)", pAgent->GetName(), pAgent);
-      pAgent->CreateConfigurations(fpConfigurationHandler, runloader);
+      pAgent->CreateConfigurations(fpConfigurationHandler, rawReader, runloader);
       pAgent=AliHLTModuleAgent::GetNextAgent();
     }
   }
   return iResult;
 }
 
-int AliHLTSystem::BuildTaskListsFromTopConfigurations(AliRunLoader* runloader)
+int AliHLTSystem::BuildTaskListsFromReconstructionChains(AliRawReader* rawReader, AliRunLoader* runloader)
 {
   // see header file for class documentation
   if (CheckStatus(kRunning)) {
@@ -644,27 +914,72 @@ int AliHLTSystem::BuildTaskListsFromTopConfigurations(AliRunLoader* runloader)
   }
 
   int iResult=0;
-  AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
-  while (pAgent && iResult>=0) {
-    TString tops=pAgent->GetLocalRecConfigurations(runloader);
-    HLTDebug("top configurations for agent %s (%p): %s", pAgent->GetName(), pAgent, tops.Data());
-    TObjArray* pTokens=tops.Tokenize(" ");
-    if (pTokens) {
-      int iEntries=pTokens->GetEntries();
-      for (int i=0; i<iEntries && iResult>=0; i++) {
-       const char* pCID=((TObjString*)pTokens->At(i))->GetString().Data();
-       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(pCID);
-       if (pConf) {
-         iResult=BuildTaskList(pConf);
-       } else {
-         HLTWarning("can not find top configuration %s", pCID);
+  int bHaveOutput=0;
+
+  // query chains
+  TString chains;
+  if (fChains.Length()>0) {
+    chains=fChains;
+    HLTInfo("custom reconstruction chain: %s", chains.Data());
+  } else {
+    AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
+    while ((pAgent || fChains.Length()>0) && iResult>=0) {
+      const char* agentchains=pAgent->GetReconstructionChains(rawReader, runloader);
+      if (agentchains) {
+       if (!chains.IsNull()) chains+="";
+       chains+=agentchains;
+       HLTInfo("reconstruction chains for agent %s (%p): %s", pAgent->GetName(), pAgent, agentchains);
+      }
+      pAgent=AliHLTModuleAgent::GetNextAgent();
+    }
+  }
+
+  // build task list for chains
+  TObjArray* pTokens=chains.Tokenize(" ");
+  if (pTokens) {
+    int iEntries=pTokens->GetEntries();
+    for (int i=0; i<iEntries && iResult>=0; i++) {
+      const char* pCID=((TObjString*)pTokens->At(i))->GetString().Data();
+      AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(pCID);
+      if (pConf) {
+       iResult=BuildTaskList(pConf);
+       if (runloader) {
+         assert(fpComponentHandler!=NULL);
+         TString cid=pConf->GetComponentID();
+         if (cid.CompareTo("HLTOUT")==0) {
+           // remove from the input of a global HLTOUT configuration
+           chains.ReplaceAll(pCID, "");
+         } else if (bHaveOutput==0) {
+           // check whether this configuration produces data output
+           if ((bHaveOutput=fpComponentHandler->HasOutputData(cid.Data()))<0) {
+             bHaveOutput=0;
+             chains.ReplaceAll(pCID, "");
+           }
+         }
        }
+      } else {
+       HLTWarning("can not find configuration %s", pCID);
       }
-      delete pTokens;
     }
-    
-    pAgent=AliHLTModuleAgent::GetNextAgent();
+    delete pTokens;
   }
+
+  // build HLTOUT for simulation
+  if (iResult>=0 && runloader) {
+    if (bHaveOutput) {
+      // there are components in the chain which produce data which need to be
+      // piped to an HLTOUT
+      if (fpComponentHandler->FindComponentIndex("HLTOUT")>=0 ||
+         LoadComponentLibraries("libHLTsim.so")>=0) {
+       AliHLTConfiguration globalout("_globalout_", "HLTOUT", chains.Data(), NULL);
+       iResult=BuildTaskList("_globalout_");
+      } else {
+       HLTError("can not load libHLTsim.so and HLTOUT component");
+       iResult=-EFAULT;
+      }
+    }
+  }
+
   if (iResult>=0) SetStatusFlags(kTaskListCreated);
 
   return iResult;
@@ -700,6 +1015,15 @@ int AliHLTSystem::ClearStatusFlags(int flags)
 
 void* AliHLTSystem::FindDynamicSymbol(const char* library, const char* symbol)
 {
+  // see header file for class documentation
   if (fpComponentHandler==NULL) return NULL;
   return fpComponentHandler->FindSymbol(library, symbol);
 }
+
+void AliHLTSystem::SetFrameworkLog(AliHLTComponentLogSeverity level) 
+{
+  // see header file for class documentation
+  SetLocalLoggingLevel(level);
+  if (fpComponentHandler) fpComponentHandler->SetLocalLoggingLevel(level);
+  if (fpConfigurationHandler) fpConfigurationHandler->SetLocalLoggingLevel(level);
+}