]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - ANALYSIS/AliAnalysisManager.cxx
Updated branch aliroot-master, development and master to
[u/mrichter/AliRoot.git] / ANALYSIS / AliAnalysisManager.cxx
index 9455399e52c432c9047ca5bfad6b9bd6bd2b332a..9ba3e8860938cd21c08b1221880903be5623ba9a 100644 (file)
@@ -33,6 +33,8 @@
 #include <TMap.h>
 #include <TClass.h>
 #include <TFile.h>
+#include <TTreeCache.h>
+#include <TEnv.h>
 #include <TMath.h>
 #include <TH1.h>
 #include <TMethodCall.h>
@@ -61,6 +63,7 @@ ClassImp(AliAnalysisManager)
 
 AliAnalysisManager *AliAnalysisManager::fgAnalysisManager = NULL;
 TString AliAnalysisManager::fgCommonFileName = "";
+TString AliAnalysisManager::fgMacroNames = "";
 Int_t AliAnalysisManager::fPBUpdateFreq = 1;
 
 //______________________________________________________________________________
@@ -78,6 +81,7 @@ AliAnalysisManager::AliAnalysisManager(const char *name, const char *title)
                     fMustClean(kFALSE),
                     fIsRemote(kFALSE),
                     fLocked(kFALSE),
+                    fMCLoop(kFALSE),
                     fDebug(0),
                     fSpecialOutputLocation(""), 
                     fTasks(0),
@@ -87,6 +91,7 @@ AliAnalysisManager::AliAnalysisManager(const char *name, const char *title)
                     fInputs(0),
                     fOutputs(0),
                     fParamCont(0),
+                    fExchangeCont(0),
                     fDebugOptions(0),
                     fFileDescriptors(new TObjArray()),
                     fCurrentDescriptor(0),
@@ -97,10 +102,12 @@ AliAnalysisManager::AliAnalysisManager(const char *name, const char *title)
                     fExtraFiles(),
                     fFileInfoLog(),
                     fAutoBranchHandling(kTRUE), 
+                    fAsyncReading(kFALSE), // default prefetching on
                     fTable(),
                     fRunFromPath(0),
                     fNcalls(0),
                     fMaxEntries(0),
+                    fCacheSize(100000000), // default 100 MB
                     fStatisticsMsg(),
                     fRequestedBranches(),
                     fStatistics(0),
@@ -123,6 +130,7 @@ AliAnalysisManager::AliAnalysisManager(const char *name, const char *title)
      fInputs     = new TObjArray();
      fOutputs    = new TObjArray();
      fParamCont  = new TObjArray();
+     fExchangeCont = new TObjArray();
      fGlobals    = new TMap();
    }
    fIOTimer = new TStopwatch();
@@ -146,6 +154,7 @@ AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
                     fMustClean(other.fMustClean),
                     fIsRemote(other.fIsRemote),
                     fLocked(other.fLocked),
+                    fMCLoop(other.fMCLoop),
                     fDebug(other.fDebug),
                     fSpecialOutputLocation(""), 
                     fTasks(NULL),
@@ -155,6 +164,7 @@ AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
                     fInputs(NULL),
                     fOutputs(NULL),
                     fParamCont(NULL),
+                    fExchangeCont(NULL),
                     fDebugOptions(NULL),
                     fFileDescriptors(new TObjArray()),
                     fCurrentDescriptor(0),
@@ -165,10 +175,12 @@ AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
                     fExtraFiles(other.fExtraFiles),
                     fFileInfoLog(other.fFileInfoLog),
                     fAutoBranchHandling(other.fAutoBranchHandling), 
+                    fAsyncReading(other.fAsyncReading),
                     fTable(),
                     fRunFromPath(0),
                     fNcalls(other.fNcalls),
                     fMaxEntries(other.fMaxEntries),
+                    fCacheSize(other.fCacheSize),
                     fStatisticsMsg(other.fStatisticsMsg),
                     fRequestedBranches(other.fRequestedBranches),
                     fStatistics(other.fStatistics),
@@ -188,6 +200,7 @@ AliAnalysisManager::AliAnalysisManager(const AliAnalysisManager& other)
    fInputs     = new TObjArray(*other.fInputs);
    fOutputs    = new TObjArray(*other.fOutputs);
    fParamCont  = new TObjArray(*other.fParamCont);
+   fExchangeCont  = new TObjArray(*other.fExchangeCont);
    fgCommonFileName  = "AnalysisResults.root";
    fgAnalysisManager = this;
 }
@@ -209,6 +222,7 @@ AliAnalysisManager& AliAnalysisManager::operator=(const AliAnalysisManager& othe
       fInitOK     = other.fInitOK;
       fIsRemote   = other.fIsRemote;
       fLocked     = other.fLocked;
+      fMCLoop     = other.fMCLoop;
       fDebug      = other.fDebug;
       fTasks      = new TObjArray(*other.fTasks);
       fTopTasks   = new TObjArray(*other.fTopTasks);
@@ -217,6 +231,7 @@ AliAnalysisManager& AliAnalysisManager::operator=(const AliAnalysisManager& othe
       fInputs     = new TObjArray(*other.fInputs);
       fOutputs    = new TObjArray(*other.fOutputs);
       fParamCont  = new TObjArray(*other.fParamCont);
+      fExchangeCont  = new TObjArray(*other.fExchangeCont);
       fDebugOptions = NULL;
       fFileDescriptors = new TObjArray();
       fCurrentDescriptor = 0;
@@ -229,10 +244,12 @@ AliAnalysisManager& AliAnalysisManager::operator=(const AliAnalysisManager& othe
       fgCommonFileName = "AnalysisResults.root";
       fgAnalysisManager = this;
       fAutoBranchHandling = other.fAutoBranchHandling;
+      fAsyncReading = other.fAsyncReading;
       fTable.Clear("nodelete");
       fRunFromPath = other.fRunFromPath;
       fNcalls     = other. fNcalls;
       fMaxEntries = other.fMaxEntries;
+      fCacheSize = other.fCacheSize;
       fStatisticsMsg = other.fStatisticsMsg;
       fRequestedBranches = other.fRequestedBranches;
       fStatistics = other.fStatistics;
@@ -252,18 +269,19 @@ AliAnalysisManager::~AliAnalysisManager()
 {
 // Destructor.
    if (fTasks) {fTasks->Delete(); delete fTasks;}
-   if (fTopTasks) delete fTopTasks;
-   if (fZombies) delete fZombies;
+   delete fTopTasks;
+   delete fZombies;
    if (fContainers) {fContainers->Delete(); delete fContainers;}
-   if (fInputs) delete fInputs;
-   if (fOutputs) delete fOutputs;
-   if (fParamCont) delete fParamCont;
-   if (fDebugOptions) delete fDebugOptions;
-   if (fGridHandler) delete fGridHandler;
-   if (fInputEventHandler) delete fInputEventHandler;
-   if (fOutputEventHandler) delete fOutputEventHandler;
-   if (fMCtruthEventHandler) delete fMCtruthEventHandler;
-   if (fEventPool) delete fEventPool;
+   delete fInputs;
+   delete fOutputs;
+   delete fParamCont;
+   delete fExchangeCont;
+   delete fDebugOptions;
+   delete fGridHandler;
+   delete fInputEventHandler;
+   delete fOutputEventHandler;
+   delete fMCtruthEventHandler;
+   delete fEventPool;
    if (fgAnalysisManager==this) fgAnalysisManager = NULL;
    if (fGlobals) {fGlobals->DeleteAll(); delete fGlobals;}
    if (fFileDescriptors) {fFileDescriptors->Delete(); delete fFileDescriptors;}
@@ -272,6 +290,65 @@ AliAnalysisManager::~AliAnalysisManager()
    delete fInitTimer;
 }
 
+//______________________________________________________________________________
+void AliAnalysisManager::CreateReadCache()
+{
+// Create cache for reading according fCacheSize and fAsyncReading.
+   if (!fTree || !fTree->GetCurrentFile()) {
+      Error("CreateReadCache","Current tree or tree file not yet defined");
+      return;
+   }   
+   if (!fCacheSize) {
+      if (fDebug) Info("CreateReadCache","=== Read caching disabled ===");
+      return;
+   }
+   gEnv->SetValue("TFile.AsyncPrefetching",(Int_t)fAsyncReading);
+//   if (fAsyncReading) gEnv->SetValue("Cache.Directory",Form("file://%s/cache", gSystem->WorkingDirectory()));
+//   if (fAsyncReading) gEnv->SetValue("TFile.AsyncReading",1);
+   fTree->SetCacheSize(fCacheSize);
+   TTreeCache::SetLearnEntries(1);  //<<< we can take the decision after 1 entry
+   if (!fAutoBranchHandling && !fRequestedBranches.IsNull()) {
+      TObjArray *arr = fRequestedBranches.Tokenize(",");
+      TIter next(arr);
+      TObject *obj;
+      while ((obj=next()))
+         fTree->AddBranchToCache(obj->GetName(),kTRUE);  //<<< add requested branches to cache
+      delete arr;   
+   } else {
+      fTree->AddBranchToCache("*", kTRUE);  //<<< add all branches to cache
+   }   
+   if (fDebug) {
+      Info("CreateReadCache","Read cache enabled %lld bytes with async reading=%d",fCacheSize, (Int_t)fAsyncReading);
+   }
+   return;
+}   
+
+//______________________________________________________________________________
+Bool_t AliAnalysisManager::EventLoop(Long64_t nevents)
+{
+// Initialize an event loop where the data producer is the input handler
+// The handler must implement MakeTree creating the tree of events (likely
+// memory resident) and generate the current event in the method BeginEvent.
+// If the tree is memory resident, the handler should never call TTree::Fill
+// method.
+   cout << "===== RUNNING IN EVENT LOOP MODE: " << GetName() << endl;
+   if (!fInputEventHandler) {
+     Error("EventLoop", "No input handler: exiting");
+     return kFALSE;
+   }
+   TTree *tree = new TTree("DummyTree", "Dummy tree for AliAnalysisManager::EventLoop");
+   SetExternalLoop(kTRUE);
+   if (!Init(tree)) return kFALSE;
+   SlaveBegin(tree);
+   for (Long64_t iev=0; iev<nevents; iev++)
+      ExecAnalysis();
+   TList dummyList;
+   PackOutput(&dummyList);
+   fIsRemote = kTRUE;
+   Terminate();
+   return kTRUE;
+}
+      
 //______________________________________________________________________________
 Int_t AliAnalysisManager::GetEntry(Long64_t entry, Int_t getall)
 {
@@ -279,7 +356,7 @@ Int_t AliAnalysisManager::GetEntry(Long64_t entry, Int_t getall)
    fCurrentEntry = entry;
    if (!fAutoBranchHandling)
      return 123456789;
-   if (!fTree) return -1; 
+   if (!fTree || !fTree->GetTree()) return -1;
    fIOTimer->Start(kTRUE); 
    Long64_t readbytes = fTree->GetTree()->GetEntry(entry, getall);
    fIOTimer->Stop();
@@ -383,7 +460,11 @@ Bool_t AliAnalysisManager::Init(TTree *tree)
    if (!fInitOK) InitAnalysis();
    if (!fInitOK) return kFALSE;
    fTree = tree;
-   fTable.Rehash(100);
+   if (fMode != kProofAnalysis) CreateReadCache();
+   else {
+     // cholm - here we should re-add to the table or branches 
+     fTable.Clear();
+   }
    AliAnalysisDataContainer *top = fCommonInput;
    if (!top) top = (AliAnalysisDataContainer*)fInputs->At(0);
    if (!top) {
@@ -392,6 +473,7 @@ Bool_t AliAnalysisManager::Init(TTree *tree)
    }
    top->SetData(tree);
    CheckBranches(kFALSE);
+   fTable.Rehash(100);
    if (fDebug > 1) {
       printf("<-AliAnalysisManager::Init(%s)\n", tree->GetName());
    }
@@ -408,7 +490,9 @@ void AliAnalysisManager::SlaveBegin(TTree *tree)
    // Init timer should be already started
    // Apply debug options
    ApplyDebugOptions();
-   
+   if (fCacheSize && 
+       fMCtruthEventHandler &&
+       (fMode != kProofAnalysis)) fMCtruthEventHandler->SetCacheSize(fCacheSize);
    if (!CheckTasks()) Fatal("SlaveBegin", "Not all needed libraries were loaded");
    static Bool_t isCalled = kFALSE;
    Bool_t init = kFALSE;
@@ -467,6 +551,7 @@ void AliAnalysisManager::SlaveBegin(TTree *tree)
    AliAnalysisTask *task;
    // Call CreateOutputObjects for all tasks
    Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
+   if (getsysInfo) AliSysInfo::SetVerbose(kTRUE); 
    Bool_t dirStatus = TH1::AddDirectoryStatus();
    Int_t itask = 0;
    while ((task=(AliAnalysisTask*)next())) {
@@ -515,7 +600,7 @@ Bool_t AliAnalysisManager::Notify()
       if (fCurrentDescriptor) fCurrentDescriptor->Done();
       fCurrentDescriptor = new AliAnalysisFileDescriptor(curfile);
       fFileDescriptors->Add(fCurrentDescriptor);
-   }   
+   } 
    
    if (fDebug > 1) printf("->AliAnalysisManager::Notify() file: %s\n", curfile->GetName());
    Int_t run = AliAnalysisManager::GetRunFromAlienPath(curfile->GetName());
@@ -817,6 +902,16 @@ void AliAnalysisManager::PackOutput(TList *target)
          out << "init_time    " << fInitTime << endl;
          out << "io_mng_time  " << fIOTime << endl;
          out << "exec_time    " << fCPUTime << endl;
+         TString aliensite = gSystem->Getenv("ALIEN_SITE");
+         out << "alien_site   " << aliensite << endl;
+         out << "host_name    ";
+         TString hostname = gSystem->Getenv("ALIEN_HOSTNAME");
+         if (hostname.IsNull()) {
+            out.close();
+            gSystem->Exec(Form("hostname -f >> %s", fFileInfoLog.Data()));
+         } else {
+            out << hostname << endl;
+         }   
       }
    }
               
@@ -934,9 +1029,11 @@ void AliAnalysisManager::UnpackOutput(TList *source)
             // If task is active, execute it
             if (task->IsPostEventLoop() && task->IsActive()) {
                if (fDebug > 1) printf("== Executing post event loop task %s\n", task->GetName());
+               if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
                task->ExecuteTask();
             }   
          }
+         if (fStatistics) fStatistics->StopTimer();
       }   
    }
    fIOTimer->Stop();
@@ -959,6 +1056,7 @@ void AliAnalysisManager::Terminate()
    TIter next(fTasks);
    TStopwatch timer;
    Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
+   if (getsysInfo) AliSysInfo::SetVerbose(kTRUE);
    // Call Terminate() for tasks
    Int_t itask = 0;
    while (!IsSkipTerminate() && (task=(AliAnalysisTask*)next())) {
@@ -1308,6 +1406,14 @@ AliAnalysisTask *AliAnalysisManager::GetTask(const char *name) const
    return (AliAnalysisTask*)fTasks->FindObject(name);
 }
 
+//______________________________________________________________________________
+Int_t AliAnalysisManager::GetTaskIndex(const AliAnalysisTask *task) const
+{
+// Returns task inded in the manager's list, -1 if not registered.
+   if (!fTasks) return -1;
+   return fTasks->IndexOf(task);
+}  
+
 //______________________________________________________________________________
 AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name, 
                                 TClass *datatype, EAliAnalysisContType type, const char *filename)
@@ -1343,6 +1449,9 @@ AliAnalysisDataContainer *AliAnalysisManager::CreateContainer(const char *name,
          }   
          break;
       case kExchangeContainer:
+         cont->SetExchange(kTRUE);
+         fExchangeCont->Add(cont);
+         cont->SetDataOwned(kFALSE); // data owned by the publisher
          break;   
    }
    return cont;
@@ -1554,8 +1663,8 @@ void AliAnalysisManager::CheckBranches(Bool_t load)
             Error("CheckBranches", "Could not find branch %s",obj->GetName());
             continue;
          }
+         fTable.Add(br);
       }   
-      fTable.Add(br);
       if (load && br->GetReadEntry()!=GetCurrentEntry()) {
          br->GetEntry(GetCurrentEntry());
       }      
@@ -1596,12 +1705,21 @@ void AliAnalysisManager::PrintStatus(Option_t *option) const
       return;
    }   
    Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
-   if (getsysInfo)
+   if (getsysInfo) {
+      AliSysInfo::SetVerbose(kTRUE);
       Info("PrintStatus", "System information will be collected each %lld events", fNSysInfo);
-   TIter next(fTopTasks);
+   }   
+   AliAnalysisDataContainer *cont = fCommonInput;
+   if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
+   printf("=== TOP CONTAINER:\n");
+   cont->PrintContainer(option,0);
+   // Reset "touched" flag
+   TIter next(fContainers);
+   while ((cont = (AliAnalysisDataContainer*)next())) cont->SetTouched(kFALSE);
+   TIter nextt(fTasks);
    AliAnalysisTask *task;
-   while ((task=(AliAnalysisTask*)next()))
-      task->PrintTask(option);
+   while ((task=(AliAnalysisTask*)nextt()))
+      task->SetActive(kFALSE);
   
    if (!fAutoBranchHandling && !fRequestedBranches.IsNull()) 
       printf("Requested input branches:\n%s\n", fRequestedBranches.Data());
@@ -1624,7 +1742,13 @@ void AliAnalysisManager::PrintStatus(Option_t *option) const
 void AliAnalysisManager::ResetAnalysis()
 {
 // Reset all execution flags and clean containers.
-   CleanContainers();
+   TIter nextTask(fTasks);
+   AliAnalysisTask *task;
+   while ((task=(AliAnalysisTask*)nextTask())) {
+      // Clean all tasks
+      task->Reset();
+   }         
+//   CleanContainers();
 }
 
 //______________________________________________________________________________
@@ -1643,6 +1767,25 @@ void AliAnalysisManager::RunLocalInit()
    TObject::SetBit(kTasksInitialized, kTRUE);
 }   
 
+//______________________________________________________________________________
+void AliAnalysisManager::InputFileFromTree(TTree * const tree, TString &fname)
+{
+// Retrieves name of the file from tree
+   fname = "";
+   if (!tree) return;
+   TFile *file = tree->GetCurrentFile();
+   TString basename;
+   if (!file) {
+      TChain *chain = dynamic_cast<TChain*>(tree);
+      if (!chain || !chain->GetNtrees()) return;
+      basename = gSystem->BaseName(chain->GetListOfFiles()->First()->GetTitle());
+   } else {   
+      basename = gSystem->BaseName(file->GetName());
+   }   
+   Int_t index = basename.Index("#");
+   fname = basename(index+1, basename.Length());
+}   
+
 //______________________________________________________________________________
 Long64_t AliAnalysisManager::StartAnalysis(const char *type, Long64_t nentries, Long64_t firstentry)
 {
@@ -1684,6 +1827,11 @@ Long64_t AliAnalysisManager::StartAnalysis(const char *type, TTree * const tree,
    if (anaType.Contains("proof"))     fMode = kProofAnalysis;
    else if (anaType.Contains("grid")) fMode = kGridAnalysis;
    else if (anaType.Contains("mix"))  fMode = kMixingAnalysis;
+   if (fInputEventHandler) {
+      TString fname;
+      InputFileFromTree(tree, fname);
+      if (fname.Length()) fInputEventHandler->SetInputFileName(fname);
+   }
 
    if (fMode == kGridAnalysis) {
       fIsRemote = kTRUE;
@@ -1740,7 +1888,10 @@ Long64_t AliAnalysisManager::StartAnalysis(const char *type, TTree * const tree,
    }   
 
    Bool_t getsysInfo = ((fNSysInfo>0) && (fMode==kLocalAnalysis))?kTRUE:kFALSE;
-   if (getsysInfo) AliSysInfo::AddStamp("Start", 0);
+   if (getsysInfo) {
+      AliSysInfo::SetVerbose(kTRUE); 
+      AliSysInfo::AddStamp("Start", 0);
+   }   
    // Initialize locally all tasks (happens for all modes)
    TIter next(fTasks);
    AliAnalysisTask *task;
@@ -1902,6 +2053,7 @@ Long64_t AliAnalysisManager::StartAnalysis(const char *type, const char *dataset
    }   
    fMode = kProofAnalysis;
    TString line;
+   TString proofProcessOpt;
    SetEventLoop(kTRUE);
    // Set the dataset flag
    TObject::SetBit(kUseDataSet);
@@ -1918,6 +2070,8 @@ Long64_t AliAnalysisManager::StartAnalysis(const char *type, const char *dataset
       } else {
          dataset = fGridHandler->GetProofDataSet();
       }
+
+      proofProcessOpt = fGridHandler->GetProofProcessOpt();
    }   
 
    if (!gROOT->GetListOfProofs() || !gROOT->GetListOfProofs()->GetEntries()) {
@@ -1931,8 +2085,8 @@ Long64_t AliAnalysisManager::StartAnalysis(const char *type, const char *dataset
    line = Form("gProof->AddInput((TObject*)%p);", this);
    gROOT->ProcessLine(line);
    Long_t retv;
-   line = Form("gProof->Process(\"%s\", \"AliAnalysisSelector\", \"\", %lld, %lld);",
-               dataset, nentries, firstentry);
+   line = Form("gProof->Process(\"%s\", \"AliAnalysisSelector\", \"%s\", %lld, %lld);",
+               dataset,proofProcessOpt.Data(), nentries, firstentry);
    cout << "===== RUNNING PROOF ANALYSIS " << GetName() << " ON DATASET " << dataset << endl;
    retv = (Long_t)gROOT->ProcessLine(line);
    return retv;
@@ -2125,13 +2279,15 @@ void AliAnalysisManager::ExecAnalysis(Option_t *option)
    }
    fNcalls++;
    AliAnalysisTask *task;
+   // Reset the analysis
+   ResetAnalysis();
    // Check if the top tree is active.
    if (fTree) {
       if (getsysInfo && ((fNcalls%fNSysInfo)==0)) 
          AliSysInfo::AddStamp("Handlers_BeginEventGroup",fNcalls, 1002, 0);
       TIter next(fTasks);
-   // De-activate all tasks
-      while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
+   // De-activate all tasks (not needed anymore after ResetAnalysis
+//      while ((task=(AliAnalysisTask*)next())) task->SetActive(kFALSE);
       AliAnalysisDataContainer *cont = fCommonInput;
       if (!cont) cont = (AliAnalysisDataContainer*)fInputs->At(0);
       if (!cont) {
@@ -2139,7 +2295,7 @@ void AliAnalysisManager::ExecAnalysis(Option_t *option)
          if (cdir) cdir->cd();
          return;
       }   
-      cont->SetData(fTree); // This will notify all consumers
+      cont->SetData(fTree); // This set activity for all tasks reading only from the top container
       Long64_t entry = fTree->GetTree()->GetReadEntry();      
 //
 //    Call BeginEvent() for optional input/output and MC services 
@@ -2158,10 +2314,13 @@ void AliAnalysisManager::ExecAnalysis(Option_t *option)
       TIter next1(fTopTasks);
       Int_t itask = 0;
       while ((task=(AliAnalysisTask*)next1())) {
+         task->SetActive(kTRUE);
          if (fDebug >1) {
             cout << "    Executing task " << task->GetName() << endl;
-         }      
+         }
+         if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
          task->ExecuteTask(option);
+         if (fStatistics) fStatistics->StopTimer();
          gROOT->cd();
          if (getsysInfo && ((fNcalls%fNSysInfo)==0)) 
             AliSysInfo::AddStamp(task->ClassName(), fNcalls, itask, 1);
@@ -2202,7 +2361,9 @@ void AliAnalysisManager::ExecAnalysis(Option_t *option)
       if (fDebug > 1) {
          cout << "    Executing task " << task->GetName() << endl;
       }   
+      if (fStatistics) fStatistics->StartTimer(GetTaskIndex(task), task->GetName(), task->ClassName());
       task->ExecuteTask(option);
+      if (fStatistics) fStatistics->StopTimer();
       gROOT->cd();
    }   
    fCPUTimer->Stop();
@@ -2696,21 +2857,18 @@ void AliAnalysisManager::AddClassDebug(const char *className, Int_t debugLevel)
       fDebugOptions->SetOwner(kTRUE);
    }
 
-   // substracting DebugOffset, beacuse of AliLog::SetClassDebugLevel()
-   debugLevel -= AliLog::kDebug-1;
-
    TNamed *debugOpt = (TNamed*)fDebugOptions->FindObject(className);
    if (!debugOpt) {
-     AliInfo(TString::Format("Adding debug level %d for class %s",debugLevel+AliLog::kDebug-1,className).Data());
+     AliInfo(TString::Format("Adding debug level %d for class %s",debugLevel,className).Data());
      fDebugOptions->Add(new TNamed(className,TString::Format("%d",debugLevel).Data()));
    } else {
       TString oldDebugStr = debugOpt->GetTitle();
       Int_t oldDebug = oldDebugStr.Atoi();
       if (debugLevel > oldDebug) {
-         AliWarning(TString::Format("Overwriting debug level to %d class %s, because it is higher then previously set (%d).",debugLevel+AliLog::kDebug-1,className,oldDebug+AliLog::kDebug-1).Data());
+         AliWarning(TString::Format("Overwriting debug level to %d class %s, because it is higher then previously set (%d).",debugLevel,className,oldDebug).Data());
          debugOpt->SetTitle(TString::Format("%d",debugLevel).Data());
       } else {
-         AliWarning(TString::Format("Ignoring debug level to %d class %s, because it is smaller then previously set (%d).",debugLevel+AliLog::kDebug-1,className,oldDebug+AliLog::kDebug-1).Data());
+         AliWarning(TString::Format("Ignoring debug level to %d class %s, because it is smaller then previously set (%d).",debugLevel,className,oldDebug).Data());
       }
    }
 }
@@ -2727,11 +2885,42 @@ void AliAnalysisManager::ApplyDebugOptions()
    TString debugLevel;
    while ((debug=dynamic_cast<TNamed*>(next()))) {
       debugLevel = debug->GetTitle();
-      AliInfo(TString::Format("ApplyDebugOptions : Class=%s debulLevel=%d",debug->GetName(),debugLevel.Atoi()+AliLog::kDebug-1).Data());
+      AliInfo(TString::Format("Class=%s debulLevel=%d",debug->GetName(),debugLevel.Atoi()).Data());
       AliLog::SetClassDebugLevel(debug->GetName(), debugLevel.Atoi());
    }
 }
 
+//______________________________________________________________________________
+Bool_t AliAnalysisManager::IsMacroLoaded(const char * filename)
+{
+// Check if a macro was loaded.
+   return fgMacroNames.Contains(filename);
+}
+   
+//______________________________________________________________________________
+Int_t AliAnalysisManager::LoadMacro(const char *filename, Int_t *error, Bool_t check)
+{
+// Redirection of gROOT->LoadMacro which makes sure the same macro is not loaded 
+// twice
+   TString macroName = gSystem->BaseName(filename);
+   // Strip appended +, ++, +g, +O
+   Int_t index = macroName.Index("+");
+   if (index>0) macroName.Remove(index);
+   if (fgMacroNames.Contains(macroName)) {
+      // Macro with the same name loaded already in this root session, do 
+      // nothing
+      error = 0;
+      return 0;
+   }
+   Int_t ret = gROOT->LoadMacro(filename,error,check);
+   // In case of error return the error code
+   if (ret) return ret;
+   // Append the macro name to the loaded macros list
+   fgMacroNames += macroName;
+   fgMacroNames += " ";
+   return ret;
+}   
+
 //______________________________________________________________________________
 void AliAnalysisManager::Lock()
 {