Analysis train configuration

The guidelines below are meant for improving the efficiency of organized analysis within ALICE analysis framework. Once a given analysis algorithm is implemented following the AliAnalysisTask rules, it becomes compliant with the framework and it can be run in the same process with other such tasks. This mode will ensure fast and efficient access to data as soon as this is available in AliEn catalog or staged in the CAF cluster. This approach may however fail if some simple rules are not followed:

  • The analysis tasks are available in AliRoot SVN repository, compiled in libraries.

  • Configuration for analysis tasks is done using available macros which are also available and maintained in sync with the analysis code by PWG.

  • The analysis tasks are accessing and relying only on standard data types which are made available via the framework (ESD or AOD).

  • When running in parallel in the same process, memory and CPU- prohibitive tasks will affect the execution of the whole train.

For having a fast analysis development cycle we foresee the deployment of a light analysis package in AliEn. This will include the analysis framework and base libraries (STEERBase, ESD, AOD, ANALYSIS, ANALYSISalice, CORRFW) plus the agreed code and analysis tasks from PWG. No other direct dependencies on core libraries or detector code are foreseen. This “light” analysis package will also include the configuration to be applied to analysis tasks and will be deployed much more frequent than AliRoot releases. This will allow running regularly “trains” over the available data giving a fast feedback.

At this moment it is hard to foresee in detail how many trains will be needed and what composition of wagons will maximize the efficiency of analysis. What is very important for this to work is that all modules that may become wagons do provide a single macro that adds a fully configured task to an existing train. Below we provide a template on how the main train and a wagon looks like in this approach.

Template for the train macro

Train structure
//______________________________________________________________________________
void AnalysisTrainNew()
{
    // A.1 Global configuration flags and run mode
    //=========================================
    Bool_t debug         = kTRUE;
    Bool_t useMC         = kFALSE;
    Bool_t readTR        = kFALSE;
    const char *analysisMode = "grid";
   
    // A.2 List of wagons to be included
    //=========================================
    Int_t iAODanalysis   = 0;
    Int_t iAODhandler    = 1;
    Int_t iESDfilter     = 1;
    Int_t iMUONfilter    = 1;
    Int_t iJETAN         = 1;
    //...
   
    // B.1 Load common libraries (STEERBase, ESD, AOD, ANALYSIS. ANALYSISalice)
    //=====================================================================
    LoadCommonLibraries(analysisMode);
    // Set include path
    gROOT->ProcessLine(".include $ALICE_ROOT/include");
   
    // B.2 Load analysis specific libraries
    //==================================
    if (iMUONfilter) {
       gSystem->Load("libPWG3base.so");
       gSystem->Load("libPWG3muon.so");
    }  
    if (iJETAN) gSystem->Load("libJETAN.so");
    if (iPWG4partcorr || iPWG4pi0) {  
       gSystem->Load("libPWG4PartCorrBase.so");
       gSystem->Load("libPWG4PartCorrDep.so");
    }  
    if (iPWG2spectra) {
       gSystem->Load("libCORRFW.so");
       gSystem->Load("libPWG2spectra.so");
       // NOTE: Tasks should stay in compiled libraries, NOT as below.
       TFile::Cp(gSystem->ExpandPathName("$(ALICE_ROOT)/PWG2/AliAnalysisTaskProtons.cxx"),
                 "AliAnalysisTaskProtons.cxx");
       TFile::Cp(gSystem->ExpandPathName("$ALICE_ROOT/PWG2/AliAnalysisTaskProtons.h"),
                 "AliAnalysisTaskProtons.h");
       gROOT->ProcessLine(".include $ALICE_ROOT/PWG2/SPECTRA");
       gROOT->ProcessLine(".L AliAnalysisTaskProtons.cxx+g");
     }

     // C. Create the chain. This is dependent on the analysis mode.
     //=============================================================
     if (!strcmp(analysisMode, "grid") TGrid::Connect("alien://");
     TChain* chain = CreateChain(analysisMode); 
   
    // D. Create the train and set-up the handlers
    //=============================================
    AliAnalysisManager *mgr  = new AliAnalysisManager("Analysis Train", "A test setup for the analysis train");
    // Create input handler (input container created automatically)
    if (iAODanalysis) {
    // AOD input handler
       AliAODInputHandler *aodH = new AliAODInputHandler();
       mgr->SetInputEventHandler(aodH);
    } else {  
    // ESD input handler
       AliESDInputHandler *esdHandler = new AliESDInputHandler();
       mgr->SetInputEventHandler(esdHandler);      
    }
    // Monte Carlo handler
    if (useMC && !iAODanalysis) {
       AliMCEventHandler* mcHandler = new AliMCEventHandler();
       mgr->SetMCtruthEventHandler(mcHandler);
       mcHandler->SetReadTR(readTR);
    }  
    // AOD output container, created automatically when setting an AOD handler
    if (iAODhandler) {
       // AOD output handler
       AliAODHandler* aodHandler   = new AliAODHandler();
       mgr->SetOutputEventHandler(aodHandler);
       aodHandler->SetOutputFileName("AliAODs.root");
    }
    // Debugging if requested
    if (debug) mgr->SetDebugLevel(3);
       
    // E. Load the tasks configuration macros for all included wagons.
    //================================================================
    // These files are supposed now to be found in known $ALICE_ROOT/PWGn locations.
    if (iESDfilter && !iAODanalysis) {
       //  ESD filter task configuration.
       gROOT->LoadMacro("AddTaskESDFilter.C");
       AliAnalysisTaskESDfilter *esdfilter = AddTaskESDFilter();
    }  
    // Jet analysis
    if (iJETAN) {
       gROOT->LoadMacro("AddTaskJets.C");
       AliAnalysisTaskJets *taskjets = AddTaskJets();
    }      
    // Proton analysis
    if (iPWG2spectra) {
       gROOT->LoadMacro("AddTaskProtons.C");
       AliAnalysisTaskProtons *protonstask = AddTaskProtons();
    }    
    // ...

    // F. Run the analysis
    //=====================
    if (mgr->InitAnalysis()) {
       mgr->PrintStatus();
       mgr->StartAnalysis(analysisMode, chain);
    }  
}

 Template showing how to include an analysis task in the train

 

Template for the macro adding a car to an existing train
AliAnalysisTaskProtons *AddTaskProtons()
{
// Creates a proton analysis task and adds it to the analysis manager.
  
   // A. Get the pointer to the existing analysis manager via the static access method.
   //==============================================================================
   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
   if (!mgr) {
      Error("AddTaskESDFilter", "No analysis manager to connect to.");
      return NULL;
   }  

   // B. Check the analysis type using the event handlers connected to the analysis
   //    manager. The availability of MC handler cann also be checked here.
   //==============================================================================
   if (!mgr->GetInputEventHandler()) {
      ::Error("AddTaskProtons", "This task requires an input event handler");
      return NULL;
   }  
   TString type = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
   const char *analysisType = "TPC";

   // C. Create the task, add it to manager.
   //===========================================================================
   AliAnalysisTaskProtons *taskproton = new AliAnalysisTaskProtons("TaskProtons");
   mgr->AddTask(taskproton);

   // D. Configure the analysis task. Extra parameters can be used via optional
   // arguments of the AddTaskXXX() function.
   //===========================================================================
   taskproton->SetType(type);
   taskproton->SetTriggerMode(AliAnalysisTaskProtons::kMB2);
   switch(analysisType) {
   case "TPC":
     taskproton->SetAnalysisMode(AliAnalysisTaskProtons::kTPC);
     break;
   case "Hybrid":
     taskproton->SetAnalysisMode(AliAnalysisTaskProtons::kHybrid);
     break;
   case "Global":
     taskproton->SetAnalysisMode(AliAnalysisTaskProtons::kGlobal);
     break;
   default:
     break;
   }
   taskproton->SetAcceptedVertexDiamond(5.,5.,15.);
  
   // If some data files are needed, please put them in a separate /data folder
   //===========================================================================
  //Momentum dependent priors
  /*TFile *f = TFile::Open("PriorProbabilities.root ");
  TF1 *fitElectrons = (TF1 *)f->Get("fitElectrons");
  TF1 *fitMuons = (TF1 *)f->Get("fitMuons");
  TF1 *fitPions = (TF1 *)f->Get("fitPions");
  TF1 *fitKaons = (TF1 *)f->Get("fitKaons");
  TF1 *fitProtons = (TF1 *)f->Get("fitProtons");
  taskProtons->SetPriorProbabilityFunctions(fitElectrons,
                        fitMuons,
                        fitPions,
                        fitKaons,
                        fitProtons);*/
  
   // E. Create ONLY the output containers for the data produced by the task.
   // Get and connect other common input/output containers via the manager as below
   //==============================================================================
   AliAnalysisDataContainer *cout_proton = mgr->CreateContainer("protonhist", TList::Class(),
                 AliAnalysisManager::kOutputContainer,"protonhist.root");                             
   mgr->ConnectInput(taskproton, 0, mgr->GetCommonInputContainer());
   mgr->ConnectOutput(taskproton, 0, cout_proton);

   // Return task pointer at the end
   return taskproton;
}