]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/rec/AliHLTReconstructor.cxx
Update master to aliroot
[u/mrichter/AliRoot.git] / HLT / rec / AliHLTReconstructor.cxx
index a6937f950d32852107278e06ea6c6331a9826d43..7fdab9b0316b38dcbc244db92d128dd30ced95d0 100644 (file)
@@ -1,11 +1,10 @@
 // $Id$
 
 //**************************************************************************
-//* This file is property of and copyright by the ALICE HLT Project        * 
+//* This file is property of and copyright by the                          * 
 //* ALICE Experiment at CERN, All rights reserved.                         *
 //*                                                                        *
 //* 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   *
 //* provided "as is" without express or implied warranty.                  *
 //**************************************************************************
 
-/** @file   AliHLTReconstructor.cxx
-    @author Matthias Richter
-    @date   
-    @brief  Binding class for HLT reconstruction in AliRoot. */
+//  @file   AliHLTReconstructor.cxx
+//  @author Matthias Richter
+//  @date   
+//  @brief  Binding class for HLT reconstruction in AliRoot
+//          Implements bot the interface to run HLT chains embedded into
+//          AliReconstruction and the unpacking and treatment of HLTOUT
 
 #include <TSystem.h>
 #include <TObjString.h>
 #include "AliCDBManager.h"
 #include "AliCDBEntry.h"
 #include "AliHLTMessage.h"
+#include "AliCentralTrigger.h"
+#include "AliTriggerConfiguration.h"
+#include "AliTriggerClass.h"
+#include "AliTriggerCluster.h"
+#include "AliDAQ.h"
+#include "AliRunLoader.h"
+#include "AliRunInfo.h"
 
 class AliCDBEntry;
 
+/** ROOT macro for the implementation of ROOT specific class methods */
 ClassImp(AliHLTReconstructor)
 
 AliHLTReconstructor::AliHLTReconstructor()
-  : 
-  AliReconstructor(),
-  fFctProcessHLTOUT(NULL),
-  fpEsdManager(NULL),
-  fpPluginBase(new AliHLTPluginBase)
+  : AliReconstructor()
+  , fpEsdManager(NULL)
+  , fpPluginBase(new AliHLTPluginBase)
   , fFlags(0)
+  , fProcessingStep(kProcessingStepUndefined)
 { 
   //constructor
 }
 
 AliHLTReconstructor::AliHLTReconstructor(const char* options)
-  : 
-  AliReconstructor(),
-  fFctProcessHLTOUT(NULL),
-  fpEsdManager(NULL),
-  fpPluginBase(new AliHLTPluginBase)
+  : AliReconstructor()
+  , fpEsdManager(NULL)
+  , fpPluginBase(new AliHLTPluginBase)
   , fFlags(0)
+  , fProcessingStep(kProcessingStepUndefined)
 { 
   //constructor
   if (options) Init(options);
@@ -74,6 +81,9 @@ AliHLTReconstructor::~AliHLTReconstructor()
 { 
   //destructor
 
+  if (fpEsdManager) AliHLTEsdManager::Delete(fpEsdManager);
+  fpEsdManager=NULL;
+
   if (fpPluginBase) {
   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
   if (pSystem) {
@@ -87,8 +97,6 @@ AliHLTReconstructor::~AliHLTReconstructor()
   }
   fpPluginBase=NULL;
 
-  if (fpEsdManager) AliHLTEsdManager::Delete(fpEsdManager);
-  fpEsdManager=NULL;
 }
 
 void AliHLTReconstructor::Init(const char* options)
@@ -121,7 +129,6 @@ void AliHLTReconstructor::Init()
   // the options scan has been moved to AliHLTSystem, the old code
   // here is kept to be able to run an older version of the HLT code
   // with newer AliRoot versions.
-  TString libs("");
   TString option = GetOption();
   TObjArray* pTokens=option.Tokenize(" ");
   option="";
@@ -145,14 +152,17 @@ void AliHLTReconstructor::Init()
        pSystem->SwitchAliLog(0);
       } else if (token.CompareTo("ignore-hltout")==0) {
        fFlags|=kAliHLTReconstructorIgnoreHLTOUT;
+      } else if (token.CompareTo("run-online-config")==0) {
+        fFlags|=kAliHLTReconstructorIgnoreHLTOUT;
+       if (option.Length()>0) option+=" ";
+       option+=token;
+      } else if (token.CompareTo("ignore-ctp")==0) {
+       fFlags|=kAliHLTReconstructorIgnoreCTP;
       } else if (token.Contains("esdmanager=")) {
        token.ReplaceAll("esdmanager=", "");
        token.ReplaceAll(","," ");
        token.ReplaceAll("'","");
        esdManagerOptions=token;
-      } else if (token.BeginsWith("lib") && token.EndsWith(".so")) {
-       libs+=token;
-       libs+=" ";
       } else {
        if (option.Length()>0) option+=" ";
        option+=token;
@@ -161,24 +171,24 @@ void AliHLTReconstructor::Init()
     delete pTokens;
   }
 
-  if (!libs.IsNull() &&
-      (!pSystem->CheckStatus(AliHLTSystem::kLibrariesLoaded)) &&
-      (pSystem->LoadComponentLibraries(libs.Data())<0)) {
-    AliError("error while loading HLT libraries");
-    return;
+  TString ecsParam;
+  TString ctpParam;
+  if ((fFlags&kAliHLTReconstructorIgnoreCTP)==0 &&
+      BuildCTPTriggerClassString(ctpParam)>=0) {
+    if (!ecsParam.IsNull()) ecsParam+=";";
+    ecsParam+="CTP_TRIGGER_CLASS=";
+    ecsParam+=ctpParam;
+  }
+
+  if (!ecsParam.IsNull()) {
+    option+=" ECS=";
+    option+=ecsParam;
   }
 
   if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
-    typedef int (*AliHLTSystemSetOptions)(AliHLTSystem* pInstance, const char* options);
-    gSystem->Load("libHLTinterface.so");
-    AliHLTSystemSetOptions pFunc=(AliHLTSystemSetOptions)(gSystem->DynFindSymbol("libHLTinterface.so", "AliHLTSystemSetOptions"));
-    if (pFunc) {
-      if ((pFunc)(pSystem, option.Data())<0) {
+    pSystem->SetDetectorMask(GetRunInfo()->GetDetectorMask());
+    if (pSystem->ScanOptions(option.Data())<0) {
       AliError("error setting options for HLT system");
-      return;  
-      }
-    } else if (option.Length()>0) {
-      AliError(Form("version of HLT system does not support the options \'%s\'", option.Data()));
       return;
     }
     if ((pSystem->Configure())<0) {
@@ -187,101 +197,79 @@ void AliHLTReconstructor::Init()
     }
   }
 
-  gSystem->Load("libHLTinterface.so");
-  fFctProcessHLTOUT=(void (*)())gSystem->DynFindSymbol("libHLTinterface.so", "AliHLTSystemProcessHLTOUT");
-
   fpEsdManager=AliHLTEsdManager::New();
-  fpEsdManager->SetOption(esdManagerOptions.Data());
+  if (fpEsdManager) {
+    fpEsdManager->SetOption(esdManagerOptions.Data());
+  }
 
-  InitStreamerInfos();
+  AliHLTMisc::Instance().InitStreamerInfos(fgkCalibStreamerInfoEntry);
 }
 
-const char* AliHLTReconstructor::fgkCalibStreamerInfoEntry="HLT/Calib/StreamerInfo";
-
-int AliHLTReconstructor::InitStreamerInfos()
+void AliHLTReconstructor::Terminate()
 {
-  // init streamer infos for HLT reconstruction
-  // Root schema evolution is not enabled for AliHLTMessage and all streamed objects.
-  // Objects in the raw data payload rely on the availability of the correct stream info.
-  // The relevant streamer info for a specific run is stored in the OCDB.
-  // The method evaluates the following entries:
-  // - HLT/Calib/StreamerInfo
-
-  // to be activated later, this is supposed to go as patch into the v4-17-Release branch
-  // which doe snot have the AliHLTMisc implementation
-  //AliCDBEntry* pEntry=AliHLTMisc::Instance().LoadOCDBEntry(fgkCalibStreamerInfoEntry);
-  AliCDBEntry* pEntry=AliCDBManager::Instance()->Get(fgkCalibStreamerInfoEntry);
-  TObject* pObject=NULL;
-  //if (pEntry && (pObject=AliHLTMisc::Instance().ExtractObject(pEntry))!=NULL)
-  if (pEntry && (pObject=pEntry->GetObject())!=NULL)
-    {
-    TObjArray* pSchemas=dynamic_cast<TObjArray*>(pObject);
-    if (pSchemas) {
-    } else {
-      AliError(Form("internal mismatch in OCDB entry %s: wrong class type", fgkCalibStreamerInfoEntry));
+  /// overloaded from AliReconstructor: terminate event processing
+
+  // indicate step 'Terminate'
+  SetProcessingStep(kProcessingStepTerminate);
+
+  if (fpPluginBase) {
+    AliHLTSystem* pSystem=fpPluginBase->GetInstance();
+    if (pSystem) {
+      // 2012-04-02
+      // clean up the HLTOUT instance if still existing, currently FinishEvent
+      // is not called at the end of the event processing and the cleanup
+      // needs to be done here to avoid a warning message. Later it can be
+      // declared a malfunction if the HLTOUT instance is still existing at
+      // this point.
+      AliHLTOUT* pHLTOUT=NULL;
+      pSystem->InvalidateHLTOUT(&pHLTOUT);
+      if (pHLTOUT) {
+       pHLTOUT->Reset();
+       delete pHLTOUT;
+       pHLTOUT=NULL;
+      }
+
+      AliDebug(0, Form("terminate HLT system: status %#x", pSystem->GetStatusFlags()));
+      if (pSystem->CheckStatus(AliHLTSystem::kStarted)) {
+       // send specific 'event' to execute the stop sequence
+       pSystem->Reconstruct(0, NULL, NULL);
+      }
     }
-  } else {
-    AliWarning(Form("missing HLT reco data (%s), skipping initialization of streamer info for TObjects in HLT raw data payload", fgkCalibStreamerInfoEntry));
   }
-  return 0;
 }
 
-int AliHLTReconstructor::InitStreamerInfos(TObjArray* pSchemas) const
+void AliHLTReconstructor::FinishEvent()
 {
-  // init streamer infos for HLT reconstruction from an array of TStreamerInfo objects
-
-  for (int i=0; i<pSchemas->GetEntriesFast(); i++) {
-    if (pSchemas->At(i)) {
-      TStreamerInfo* pSchema=dynamic_cast<TStreamerInfo*>(pSchemas->At(i));
-      if (pSchema) {
-       int version=pSchema->GetClassVersion();
-       TClass* pClass=TClass::GetClass(pSchema->GetName());
-       if (pClass) {
-         if (pClass->GetClassVersion()==version) {
-           AliDebug(0,Form("skipping schema definition %d version %d to class %s as this is the native version", i, version, pSchema->GetName()));
-           continue;
-         }
-         TObjArray* pInfos=pClass->GetStreamerInfos();
-         if (pInfos /*&& version<pInfos->GetEntriesFast()*/) {
-           if (pInfos->At(version)==NULL) {
-             TStreamerInfo* pClone=(TStreamerInfo*)pSchema->Clone();
-             if (pClone) {
-               pClone->SetClass(pClass);
-               pClone->BuildOld();
-               pInfos->AddAtAndExpand(pClone, version);
-               AliDebug(0,Form("adding schema definition %d version %d to class %s", i, version, pSchema->GetName()));
-             } else {
-               AliError(Form("skipping schema definition %d (%s), unable to create clone object", i, pSchema->GetName()));
-             }
-           } else {
-             TStreamerInfo* pInfo=dynamic_cast<TStreamerInfo*>(pInfos->At(version));
-             if (pInfo && pInfo->GetClassVersion()==version) {
-               AliDebug(0,Form("schema definition %d version %d already available in class %s, skipping ...", i, version, pSchema->GetName()));
-             } else {
-               AliError(Form("can not verify version for already existing schema definition %d (%s) version %d: version of existing definition is %d", i, pSchema->GetName(), version, pInfo?pInfo->GetClassVersion():-1));
-             }
-           }
-         } else {
-           AliError(Form("skipping schema definition %d (%s), unable to set version %d in info array of size %d", i, pSchema->GetName(), version, pInfos?pInfos->GetEntriesFast():-1));
-         }
-       } else {
-         AliError(Form("skipping schema definition %d (%s), unable to find class", i, pSchema->GetName()));
-       }
-      } else {
-       AliError(Form("skipping schema definition %d, not of TStreamerInfo", i));
-      }
+  /// overloaded from AliReconstructor: finish current event
+  if (!fpPluginBase) return;
+
+  // indicate step 'FinishEvent'
+  SetProcessingStep(kProcessingStepFinishEvent);
+
+  AliInfo("finishing event");
+  AliHLTSystem* pSystem=fpPluginBase->GetInstance();
+  if (pSystem) {
+    // this is the end of the lifetime of the HLTOUT instance
+    // called after all other modules have been reconstructed
+    AliHLTOUT* pHLTOUT=NULL;
+    pSystem->InvalidateHLTOUT(&pHLTOUT);
+    if (pHLTOUT) {
+      pHLTOUT->Reset();
+      delete pHLTOUT;
+      pHLTOUT=NULL;
     }
   }
-
-  return 0;
 }
 
+const char* AliHLTReconstructor::fgkCalibStreamerInfoEntry="HLT/Calib/StreamerInfo";
+
 void AliHLTReconstructor::Reconstruct(AliRawReader* rawReader, TTree* /*clustersTree*/) const 
 {
   // reconstruction of real data without writing of ESD
   // For each event, HLT reconstruction chains can be executed and
   // added to the existing HLTOUT data
   // The HLTOUT data is finally processed in FillESD
+
   if (!fpPluginBase) {
     AliError("internal memory error: can not get AliHLTSystem instance from plugin");
     return;
@@ -291,14 +279,55 @@ void AliHLTReconstructor::Reconstruct(AliRawReader* rawReader, TTree* /*clusters
   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
 
   if (pSystem) {
+    AliHLTOUT* pHLTOUT=NULL;
+    pSystem->InvalidateHLTOUT(&pHLTOUT);
+    if (pHLTOUT) {
+      // at this stage we always have a new event, regardless state of
+      // fProcessingStep; build the HLTOUT instance from scratch
+      pHLTOUT->Reset();
+      delete pHLTOUT;
+      pHLTOUT=NULL;
+    }
     if (pSystem->CheckStatus(AliHLTSystem::kError)) {
-      AliError("HLT system in error state");
+      // this is the highest level where an error can be detected, no error
+      // codes can be returned
+      AliFatal("HLT system in error state");
       return;
     }
     if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
       AliError("HLT system in wrong state");
       return;
     }
+
+    // indicate the local reconstruction step
+    SetProcessingStep(kProcessingStepLocal);
+
+    // init the HLTOUT instance for the current event
+    // not nice. Have to query the global run loader to get the current event no.
+    Int_t eventNo=-1;
+    AliRunLoader* runloader = AliRunLoader::Instance();
+    if (runloader) {
+      eventNo=runloader->GetEventNumber();
+    }
+    if (eventNo>=0) {
+      AliRawReader* input=NULL;
+      if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
+       input=rawReader;
+      }
+      pHLTOUT=new AliHLTOUTRawReader(input, eventNo, fpEsdManager);
+      if (pHLTOUT) {
+       if (pHLTOUT->Init()>=0) {
+         pSystem->InitHLTOUT(pHLTOUT);
+       } else {
+         AliError("error : initialization of HLTOUT handler failed");
+       }
+      } else {
+       AliError("memory allocation failed: can not create AliHLTOUT object");
+      }
+    } else {
+      AliError("can not get event number");
+    }
+
     if ((iResult=pSystem->Reconstruct(1, NULL, rawReader))>=0) {
     }
   }
@@ -322,7 +351,9 @@ void AliHLTReconstructor::FillESD(AliRawReader* rawReader, TTree* /*clustersTree
 
   if (pSystem) {
     if (pSystem->CheckStatus(AliHLTSystem::kError)) {
-      AliError("HLT system in error state");
+      // this is the highest level where an error can be detected, no error
+      // codes can be returned
+      AliFatal("HLT system in error state");
       return;
     }
     if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
@@ -331,14 +362,38 @@ void AliHLTReconstructor::FillESD(AliRawReader* rawReader, TTree* /*clustersTree
     }
     pSystem->FillESD(-1, NULL, esd);
 
-    AliRawReader* input=NULL;
-    if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
-      input=rawReader;
+    // the HLTOUT handler has either been created in the AliHLTReconstructor::Reconstruct
+    // step of this event or is created now. In either case the instance is deleted after
+    // the processing
+    AliHLTOUT* pHLTOUT=NULL;
+    pSystem->InvalidateHLTOUT(&pHLTOUT);
+    if (pHLTOUT && fProcessingStep!=kProcessingStepLocal) {
+      // this is a new event, if local reconstruction would have been executed
+      // the HLTOUT instance would have been created for the current event already,
+      // in all other cases one has to create the HLTOUT instance here
+      pHLTOUT->Reset();
+      delete pHLTOUT;
+      pHLTOUT=NULL;
+    }
+    if (!pHLTOUT) {
+      AliRawReader* input=NULL;
+      if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
+       input=rawReader;
+      }
+      pHLTOUT=new AliHLTOUTRawReader(input, esd->GetEventNumberInFile(), fpEsdManager);
     }
-    AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(input, esd->GetEventNumberInFile(), fpEsdManager);
+
+    // indicate step 'ESD filling'
+    SetProcessingStep(kProcessingStepESD);
+
     if (pHLTOUT) {
-      ProcessHLTOUT(pHLTOUT, esd);
-      delete pHLTOUT;
+      ProcessHLTOUT(pHLTOUT, esd, (pSystem->GetGlobalLoggingLevel()&kHLTLogDebug)!=0);
+      // 2012-03-30: a change in the module sequence of AliReconstruction is soon
+      // going to be applied: HLT reconstruction is executed fully (i.e. both local
+      // reconstruction and FillESD) before all the other modules. In order to make the
+      // HLTOUT data available for other modules it is kept here and released in the method
+      // FinishEvent
+      pSystem->InitHLTOUT(pHLTOUT);
     } else {
       AliError("error creating HLTOUT handler");
     }
@@ -349,9 +404,55 @@ void AliHLTReconstructor::Reconstruct(TTree* /*digitsTree*/, TTree* /*clustersTr
 {
   // reconstruct simulated data
 
-  // all reconstruction has been moved to FillESD
-  //AliReconstructor::Reconstruct(digitsTree,clustersTree);
-  AliInfo("running digit data reconstruction");
+  AliHLTSystem* pSystem=fpPluginBase->GetInstance();
+
+  if (pSystem) {
+    // create the HLTOUT instance in order to be available for other detector reconstruction
+    // first cleanup any existing instance
+    AliHLTOUT* pHLTOUT=NULL;
+    pSystem->InvalidateHLTOUT(&pHLTOUT);
+    if (pHLTOUT) {
+      // at this stage we always have a new event, regardless state of
+      // fProcessingStep; build the HLTOUT instance from scratch
+      pHLTOUT->Reset();
+      delete pHLTOUT;
+      pHLTOUT=NULL;
+    }
+
+    // indicate the local reconstruction step
+    SetProcessingStep(kProcessingStepLocal);
+
+    // not nice. Have to query the global run loader to get the current event no.
+    // This is related to the missing AliLoader for HLT.
+    // Since AliReconstruction can not provide a digits tree, the file needs to be accessed
+    // explicitely, and the corresponding event needs to be selected.
+    Int_t eventNo=-1;
+    AliRunLoader* runloader = AliRunLoader::Instance();
+    if (runloader) {
+      eventNo=runloader->GetEventNumber();
+    }
+    if (eventNo>=0) {
+      const char* digitfile=NULL;
+      if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
+       digitfile="HLT.Digits.root";
+      }
+
+      pHLTOUT=new AliHLTOUTDigitReader(eventNo, fpEsdManager, digitfile);
+      if (pHLTOUT) {
+       if (pHLTOUT->Init()>=0) {
+         pSystem->InitHLTOUT(pHLTOUT);
+       } else {
+         AliError("error : initialization of HLTOUT handler failed");
+       }
+      } else {
+       AliError("memory allocation failed: can not create AliHLTOUT object");
+      }
+    } else {
+      AliError("can not get event number");
+    }
+
+    // all data processing happens in FillESD
+  }
 }
 
 void AliHLTReconstructor::FillESD(TTree* /*digitsTree*/, TTree* /*clustersTree*/, AliESDEvent* esd) const
@@ -364,10 +465,12 @@ void AliHLTReconstructor::FillESD(TTree* /*digitsTree*/, TTree* /*clustersTree*/
   TString option = GetOption();
   if (!option.IsNull() && 
       (option.Contains("config=") || option.Contains("chains="))) {
-    AliWarning(Form("HLT reconstruction can be run embedded into Alireconstruction from\n"
-                   "raw data (real or simulated)). Reconstruction of of digit data takes\n"
-                   "place in AliSimulation, appropriate input conversion is needed.\n"
-                   "Consider running embedded into AliSimulation."
+    AliWarning(Form("You are trying to run a custom HLT chain on digits data.\n\n"
+                   "HLT reconstruction can be run embedded into AliReconstruction from\n"
+                   "raw data (real or simulated)). Reconstruction of digit data takes\n"
+                   "place in AliSimulation, appropriate input conversion is needed to\n"
+                   "feed data from the detector digits into the HLT chain.\n"
+                   "Consider running embedded into AliSimulation.\n"
                    "        /***  run macro *****************************************/\n"
                    "        AliSimulation sim;\n"
                    "        sim.SetRunHLT(\"%s\");\n"
@@ -376,7 +479,8 @@ void AliHLTReconstructor::FillESD(TTree* /*digitsTree*/, TTree* /*clustersTree*/
                    "        sim.SetMakeSDigits(\"\");\n"
                    "        sim.SetMakeDigitsFromHits(\"\");\n"
                    "        sim.Run();\n"
-                   "        /*********************************************************/", option.Data()));
+                   "        /*********************************************************/\n\n",
+                   option.Data()));
   }
   if (!fpPluginBase) {
     AliError("internal memory error: can not get AliHLTSystem instance from plugin");
@@ -386,7 +490,9 @@ void AliHLTReconstructor::FillESD(TTree* /*digitsTree*/, TTree* /*clustersTree*/
   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
   if (pSystem) {
     if (pSystem->CheckStatus(AliHLTSystem::kError)) {
-      AliError("HLT system in error state");
+      // this is the highest level where an error can be detected, no error
+      // codes can be returned
+      AliFatal("HLT system in error state");
       return;
     }
     if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
@@ -394,10 +500,38 @@ void AliHLTReconstructor::FillESD(TTree* /*digitsTree*/, TTree* /*clustersTree*/
       return;
     }
 
-    AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(esd->GetEventNumberInFile(), fpEsdManager);
-    if (pHLTOUT) {
-      ProcessHLTOUT(pHLTOUT, esd);
+    // the HLTOUT handler has either been created in the AliHLTReconstructor::Reconstruct
+    // step of this event or is created now. In either case the instance is deleted after
+    // the processing
+    AliHLTOUT* pHLTOUT=NULL;
+    pSystem->InvalidateHLTOUT(&pHLTOUT);
+    if (pHLTOUT && fProcessingStep!=kProcessingStepLocal) {
+      // this is a new event, if local reconstruction would have been executed
+      // the HLTOUT instance would have been created for the current event already,
+      // in all other cases one has to create the HLTOUT instance here
+      pHLTOUT->Reset();
       delete pHLTOUT;
+      pHLTOUT=NULL;
+    }
+    if (!pHLTOUT) {
+      const char* digitfile=NULL;
+      if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
+       digitfile="HLT.Digits.root";
+      }
+      pHLTOUT=new AliHLTOUTDigitReader(esd->GetEventNumberInFile(), fpEsdManager, digitfile);
+    }
+
+    // indicate step 'ESD filling'
+    SetProcessingStep(kProcessingStepESD);
+
+    if (pHLTOUT) {
+      ProcessHLTOUT(pHLTOUT, esd, (pSystem->GetGlobalLoggingLevel()&kHLTLogDebug)!=0);
+      // 2012-03-30: a change in the module sequence of AliReconstruction is soon
+      // going to be applied: HLT reconstruction is executed fully (i.e. both local
+      // reconstruction and FillESD) before all the other modules. In order to make the
+      // HLTOUT data available for other modules it is kept here and released in the method
+      // FinishEvent
+      pSystem->InitHLTOUT(pHLTOUT);
     } else {
       AliError("error creating HLTOUT handler");
     }
@@ -436,7 +570,7 @@ void AliHLTReconstructor::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd, bo
       if (pObject) {
        TObjArray* pArray=dynamic_cast<TObjArray*>(pObject);
        if (pArray) {
-         InitStreamerInfos(pArray);
+         AliHLTMisc::Instance().InitStreamerInfos(pArray);
        } else {
          AliError(Form("wrong class type of streamer info list: expected TObjArray, but object is of type %s", pObject->Class()->GetName()));
        }
@@ -448,14 +582,14 @@ void AliHLTReconstructor::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd, bo
     }
   }
 
-  if (fFctProcessHLTOUT) {
-    typedef int (*AliHLTSystemProcessHLTOUT)(AliHLTSystem* pInstance, AliHLTOUT* pHLTOUT, AliESDEvent* esd);
-    AliHLTSystemProcessHLTOUT pFunc=(AliHLTSystemProcessHLTOUT)fFctProcessHLTOUT;
-    if ((pFunc)(pSystem, pHLTOUT, esd)<0) {
-      AliError("error processing HLTOUT");
-    }
+  if (pSystem->ProcessHLTOUT(pHLTOUT, esd)<0) {
+    AliError("error processing HLTOUT");
+  }
+
+  if (bVerbose && esd) {
+    AliInfo("HLT ESD content:");
+    esd->Print();
   }
-  pHLTOUT->Reset();
 }
 
 void AliHLTReconstructor::ProcessHLTOUT(const char* digitFile, AliESDEvent* pEsd) const
@@ -543,3 +677,55 @@ void AliHLTReconstructor::PrintHLTOUTContent(AliHLTOUT* pHLTOUT) const
     AliInfo(Form("   %s  0x%x: size %d", AliHLTComponent::DataType2Text(dt).c_str(), spec, size));
   }
 }
+
+int AliHLTReconstructor::BuildCTPTriggerClassString(TString& triggerclasses) const
+{
+  // build the CTP trigger class string from the OCDB entry of the CTP trigger
+  int iResult=0;
+  
+  triggerclasses.Clear();
+  AliCentralTrigger* pCTP = new AliCentralTrigger();
+  AliTriggerConfiguration *config=NULL;
+  TString configstr("");
+  if (pCTP->LoadConfiguration(configstr) && 
+      (config = pCTP->GetConfiguration())!=NULL) {
+    const TObjArray& classesArray = config->GetClasses();
+    int nclasses = classesArray.GetEntriesFast();
+    for( int iclass=0; iclass < nclasses; iclass++ ) {
+      AliTriggerClass* trclass = NULL;
+      if (classesArray.At(iclass) && (trclass=dynamic_cast<AliTriggerClass*>(classesArray.At(iclass)))!=NULL) {
+       TString entry;
+       int trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
+       entry.Form("%02d:%s:", trindex, trclass->GetName());
+       AliTriggerCluster* cluster=NULL;
+       TObject* clusterobj=config->GetClusters().FindObject(trclass->GetCluster());
+       if (clusterobj && (cluster=dynamic_cast<AliTriggerCluster*>(clusterobj))!=NULL) {
+         TString detectors=cluster->GetDetectorsInCluster();
+         TObjArray* pTokens=detectors.Tokenize(" ");
+         if (pTokens) {
+           for (int dix=0; dix<pTokens->GetEntriesFast(); dix++) {
+             int id=AliDAQ::DetectorID(((TObjString*)pTokens->At(dix))->GetString());
+             if (id>=0) {
+               TString detstr; detstr.Form("%s%02d", dix>0?"-":"", id);
+               entry+=detstr;
+             } else {
+               AliError(Form("invalid detector name extracted from trigger cluster: %s (%s)", ((TObjString*)pTokens->At(dix))->GetString().Data(), detectors.Data()));
+               iResult=-EPROTO;
+               break;
+             }
+           }
+           delete pTokens;
+         }
+       } else {
+         AliError(Form("can not find trigger cluster %s in config", trclass->GetCluster()?trclass->GetCluster()->GetName():"NULL"));
+         iResult=-EPROTO;
+         break;
+       }
+       if (!triggerclasses.IsNull()) triggerclasses+=",";
+       triggerclasses+=entry;
+      }
+    }
+  }
+
+  return iResult;
+}