ROOT logo
// #include <iostream>
// #include "AliAnalysisManager.h"
// #include "AliESDInputHandler.h"
// #include "AliMCEventHandler.h"
// #include "AliAnalysisGrid.h"
// #include "AliCentralitySelectionTask.h"
// #include "AliAnalysisCentralitySelector.h"
// #include "AliAnalysisTaskPerformanceStrange.h"
// #include "TString.h"
// #include "TChain.h"
// #include "TAlienCollection.h"
// #include <fstream>
// #include "TObjString.h"
// #include "TIterator.h"
// #include "TGrid.h"
// #include "TROOT.h"

// #include "CreateAlienHandler.C"
// #include 

using namespace std;

enum { kMyRunModeLocal = 0, kMyRunModeCAF, kMyRunModeGRID};

TList * listToLoad = new TList(); // Additional classes to be loaded, see InitAndLoadLibs

TChain * GetAnalysisChain(const char * incollection);
void InitAndLoadLibs(Int_t runMode=kMyRunModeLocal, Int_t workers=0,Bool_t debug=0) ;

void run(const char * data, const char * passOrPath, Long64_t nev = -1, Long64_t offset = 0, Bool_t debug = kFALSE, Int_t runMode = 0, Bool_t isMC = 0, Bool_t usePID = kTRUE, const char* option = "",TString customSuffix = "", Int_t workers = -1, const char * gridMode="full", Int_t binMin=0, Int_t binMax = 6)
{
  // runMode:
  //
  // 0 local 
  // 1 proof
  // 2 grid

  if (nev < 0)
    nev = 1234567890;
  InitAndLoadLibs(runMode,workers,debug);

  // Create the analysis manager
  AliAnalysisManager * mgr = new AliAnalysisManager;

  // Add ESD handler
  AliESDInputHandler* esdH = new AliESDInputHandler;
  // Do I need any of this? 
  // esdH->SetInactiveBranches("AliESDACORDE FMD ALIESDTZERO ALIESDZDC AliRawDataErrorLogs CaloClusters Cascades EMCALCells EMCALTrigger ESDfriend Kinks AliESDTZERO ALIESDACORDE MuonTracks TrdTracks");
  mgr->SetInputEventHandler(esdH);

  if(isMC) {
    AliMCEventHandler* handler = new AliMCEventHandler;
    handler->SetPreReadMode(AliMCEventHandler::kLmPreRead);
    mgr->SetMCtruthEventHandler(handler);
  }


  // If we are running on grid, we need the alien handler
  if (runMode == kMyRunModeGRID) {
    // Create and configure the alien handler plugin
    TGrid::Connect("alien://");// Why do I need this? Without a get a bus error...
        gROOT->LoadMacro("CreateAlienHandler.C");
    AliAnalysisGrid *alienHandler = CreateAlienHandler(data, listToLoad, gridMode, isMC);  
    if (!alienHandler) {
      cout << "Cannot create alien handler" << endl;    
      exit(1);
    }
    mgr->SetGridHandler(alienHandler);  
  }
  

  // Physics selection
  gROOT->ProcessLine(".L $ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
  AliPhysicsSelectionTask * physicsSelectionTask = AddTaskPhysicsSelection(isMC);

  // Centrality
  gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskCentrality.C");
  AliCentralitySelectionTask *taskCentrality = AddTaskCentrality();
  taskCentrality->SetPass(2);
  if(isMC) taskCentrality->SetMCInput();

  AliAnalysisCentralitySelector * centrSelector = new AliAnalysisCentralitySelector();
  centrSelector->SetIsMC(isMC);
  centrSelector->SetCentralityEstimator("V0M"); // Todo: add parameter to macro?

  // Parse option strings
  TString optionStr(option);
  
  // remove SAVE option if set
  Bool_t doSave = kFALSE;

  if (optionStr.Contains("SAVE"))
    {
      optionStr = optionStr(0,optionStr.Index("SAVE")) + optionStr(optionStr.Index("SAVE")+4, optionStr.Length());
      doSave = kTRUE;
    }
  TString pathsuffix = "";
  // Not used, but may be useful
  Bool_t useMCKinematics = isMC;
  if (optionStr.Contains("NOMCKIN")) {
    cout << ">>>> Ignoring MC kinematics" << endl;
    useMCKinematics=kFALSE;
    pathsuffix+="_NOMCKIN";
  }
  
  gROOT->ProcessLine(".L AddTaskLambdaK0PbPb.C");
  Int_t nbin = 0; // will contain the number of centrality bins
  AliAnalysisTaskPerformanceStrange ** task = AddTaskLambdaK0PbPb("lambdak0.root", centrSelector, nbin, binMin, binMax); // FIXME also pass cuts, centrality bin type selection(5,10% percentiles, ranges...)
  // configure task
  //  else if (iAODanalysis) task->SetAnalysisType("AOD");
  // FIXME: add options to macro
  // FIXME: put physics selection inside the task
  cout << nbin << endl;
  
  for(Int_t ibin = 0; ibin < nbin; ibin++){
    cout << "ibin " << ibin << "  "<< endl;//task[ibin] << endl;
    
    task[ibin]->SetAnalysisType("ESD");
    cout << "1" << endl;
    task[ibin]->SetAnalysisMC(isMC); // 0 or 1
    cout << "2" << endl;
    task[ibin]->SetCollidingSystems(1); // 0 =pp, 1=AA
    cout << "3" << endl;
    task[ibin]->SetAnalysisCut("no");
    cout << "4" << endl;
    if(usePID) 
      task[ibin]->SetUsePID("withPID"); // withPID or withoutPID
    else
      task[ibin]->SetUsePID("withoutPID"); // withPID or withoutPID
    cout << "5" << endl;
  }

  // Init and run the analy
  if (!mgr->InitAnalysis()) return;

  mgr->PrintStatus();
  
  if (runMode == kMyRunModeLocal ) {
    // If running in local mode, create chain of ESD files
    cout << "RUNNING LOCAL, CHAIN" << endl;    
    TChain * chain = GetAnalysisChain(data);
    //    chain->Print();
    mgr->StartAnalysis("local",chain,nev);
  } else if (runMode == kMyRunModeCAF) {
    mgr->StartAnalysis("proof",TString(passOrPath)+data+"#esdTree",nev);
  } else if (runMode == kMyRunModeGRID) {
    mgr->StartAnalysis("grid");
  } else {
    cout << "ERROR: unknown run mode" << endl;        
  }

  pathsuffix += customSuffix;

  if (doSave) MoveOutput(data, pathsuffix.Data());

  
}

void MoveOutput(const char * data, const char * suffix = ""){

  TString path("output/");
  path = path + TString(data).Tokenize("/")->Last()->GetName() + suffix;
  
  TString fileName = "lambdak0.root";
  gSystem->mkdir(path, kTRUE);
  gSystem->Rename(fileName, path + "/" + fileName);
  for(Int_t ibin = 0; ibin < 20; ibin++){
    TString fileBin = fileName;
    fileBin.ReplaceAll(".root",Form("_%2.2d.root",ibin));
    gSystem->Rename(fileBin, path + "/" + fileBin);    
  }
  
  gSystem->Rename("event_stat.root", path + "/event_stat.root");      
  gSystem->Rename("EventStat_temp.root", path + "/EventStat_temp.root");      
  Printf(">>>>> Moved files to %s", path.Data());
}  



TChain * GetAnalysisChain(const char * incollection){
  // Builds a chain of esd files
  // incollection can be
  // - a single root file
  // - an xml collection of files on alien
  // - a ASCII containing a list of local root files

  TChain* analysisChain = 0;
  // chain
  analysisChain = new TChain("esdTree");
  if (TString(incollection).Contains(".root")){
    analysisChain->Add(incollection);
  }
  else if (TString(incollection).Contains("xml")){
    TGrid::Connect("alien://");
    TGridCollection * coll = TAlienCollection::Open (incollection);
    while(coll->Next()){
      analysisChain->Add(TString("alien://")+coll->GetLFN());
    }
  } else {
    ifstream file_collect(incollection);
    TString line;
    while (line.ReadLine(file_collect) ) {
      analysisChain->Add(line.Data());
    }
  }
  analysisChain->GetListOfFiles()->Print();

  return analysisChain;
}


void InitAndLoadLibs(Int_t runMode, Int_t workers,Bool_t debug) {
  // Loads libs and par files + custom task and classes (the order is important)
  // listToLoad->Add(new TObjString("$ALICE_ROOT/STEER/AliCentrality.cxx")); // FIXME: why do I have to load it?!?
  listToLoad->Add(new TObjString("AliAnalysisCentralitySelector.cxx"));
  listToLoad->Add(new TObjString("AliAnalysisTaskPerformanceStrange.cxx"));

  if (runMode == kMyRunModeCAF)
    {
      cout << "Init in CAF mode" << endl;
    
      gEnv->SetValue("XSec.GSI.DelegProxy", "2");
      Char_t* alienuser = gSystem->Getenv("alien_API_USER");
      TProof * p = TProof::Open(alienuser!=0 ? Form("%s@alice-caf.cern.ch",alienuser) : "alice-caf.cern.ch", workers>0 ? Form("workers=%d",workers) : "");
      //TProof * p = TProof::Open("skaf.saske.sk", workers>0 ? Form("workers=%d",workers) : "");    
      p->Exec("TObject *o = gEnv->GetTable()->FindObject(\"Proof.UseMergers\"); gEnv->GetTable()->Remove(o);", kTRUE); // avoid submerging
      //gProof->EnablePackage("VO_ALICE@AliRoot::v4-21-18-AN");
      gProof->EnablePackage("VO_ALICE@AliRoot::v4-21-20-AN");


      // Enable the needed package
      // FIXME: what if I don't want to use par files?
      gSystem->AddIncludePath("-I${ALICE_ROOT}/include/");
      gSystem->AddIncludePath("-I${ALICE_ROOT}/STEER/");
      // gProof->UploadPackage("$ALICE_ROOT/obj/STEERBase");
      // gProof->EnablePackage("$ALICE_ROOT/obj/STEERBase");
      // gProof->UploadPackage("$ALICE_ROOT/obj/ESD");
      // gProof->EnablePackage("$ALICE_ROOT/obj/ESD");
      // gProof->UploadPackage("$ALICE_ROOT/obj/AOD");
      // gProof->EnablePackage("$ALICE_ROOT/obj/AOD");
      // gProof->UploadPackage("$ALICE_ROOT/obj/ANALYSIS");
      // gProof->EnablePackage("$ALICE_ROOT/obj/ANALYSIS");
      // gProof->UploadPackage("$ALICE_ROOT/obj/ANALYSISalice");
      // gProof->EnablePackage("$ALICE_ROOT/obj/ANALYSISalice");
      // gProof->UploadPackage("$ALICE_ROOT/obj/CORRFW");
      // gProof->EnablePackage("$ALICE_ROOT/obj/CORRFW");
      // gProof->UploadPackage("~/Desktop/OADB");//FIXME
      // gProof->EnablePackage("~/Desktop/OADB");//FIXME
      
    }
  else
    {
      cout << "Init in Local or Grid mode" << endl;
      gSystem->Load("libCore.so");  
      gSystem->Load("libTree.so");
      gSystem->Load("libGeom.so");
      gSystem->Load("libVMC.so");
      gSystem->Load("libPhysics.so");
      gSystem->Load("libSTEERBase");
      gSystem->Load("libESD");
      gSystem->Load("libAOD");
      gSystem->Load("libANALYSIS");
      gSystem->Load("libANALYSISalice");   

      // gSystem->Load("libVMC");
      gROOT->ProcessLine(".include $ALICE_ROOT/include");
      gROOT->ProcessLine(".include $ALICE_ROOT/STEER");
    }
  // Load helper classes
  TIterator * iter = listToLoad->MakeIterator();
  TObjString * name = 0;
  while ((name = (TObjString *)iter->Next())) {
    gSystem->ExpandPathName(name->String());
    cout << name->String().Data() << endl;
    if (runMode == kMyRunModeCAF) {
      gProof->Load(name->String()+(debug?"++g":"+"));   
    } else {
      gROOT->LoadMacro(name->String()+(debug?"++g":"+"));   
    }
  }

}
 runQA.C:1
 runQA.C:2
 runQA.C:3
 runQA.C:4
 runQA.C:5
 runQA.C:6
 runQA.C:7
 runQA.C:8
 runQA.C:9
 runQA.C:10
 runQA.C:11
 runQA.C:12
 runQA.C:13
 runQA.C:14
 runQA.C:15
 runQA.C:16
 runQA.C:17
 runQA.C:18
 runQA.C:19
 runQA.C:20
 runQA.C:21
 runQA.C:22
 runQA.C:23
 runQA.C:24
 runQA.C:25
 runQA.C:26
 runQA.C:27
 runQA.C:28
 runQA.C:29
 runQA.C:30
 runQA.C:31
 runQA.C:32
 runQA.C:33
 runQA.C:34
 runQA.C:35
 runQA.C:36
 runQA.C:37
 runQA.C:38
 runQA.C:39
 runQA.C:40
 runQA.C:41
 runQA.C:42
 runQA.C:43
 runQA.C:44
 runQA.C:45
 runQA.C:46
 runQA.C:47
 runQA.C:48
 runQA.C:49
 runQA.C:50
 runQA.C:51
 runQA.C:52
 runQA.C:53
 runQA.C:54
 runQA.C:55
 runQA.C:56
 runQA.C:57
 runQA.C:58
 runQA.C:59
 runQA.C:60
 runQA.C:61
 runQA.C:62
 runQA.C:63
 runQA.C:64
 runQA.C:65
 runQA.C:66
 runQA.C:67
 runQA.C:68
 runQA.C:69
 runQA.C:70
 runQA.C:71
 runQA.C:72
 runQA.C:73
 runQA.C:74
 runQA.C:75
 runQA.C:76
 runQA.C:77
 runQA.C:78
 runQA.C:79
 runQA.C:80
 runQA.C:81
 runQA.C:82
 runQA.C:83
 runQA.C:84
 runQA.C:85
 runQA.C:86
 runQA.C:87
 runQA.C:88
 runQA.C:89
 runQA.C:90
 runQA.C:91
 runQA.C:92
 runQA.C:93
 runQA.C:94
 runQA.C:95
 runQA.C:96
 runQA.C:97
 runQA.C:98
 runQA.C:99
 runQA.C:100
 runQA.C:101
 runQA.C:102
 runQA.C:103
 runQA.C:104
 runQA.C:105
 runQA.C:106
 runQA.C:107
 runQA.C:108
 runQA.C:109
 runQA.C:110
 runQA.C:111
 runQA.C:112
 runQA.C:113
 runQA.C:114
 runQA.C:115
 runQA.C:116
 runQA.C:117
 runQA.C:118
 runQA.C:119
 runQA.C:120
 runQA.C:121
 runQA.C:122
 runQA.C:123
 runQA.C:124
 runQA.C:125
 runQA.C:126
 runQA.C:127
 runQA.C:128
 runQA.C:129
 runQA.C:130
 runQA.C:131
 runQA.C:132
 runQA.C:133
 runQA.C:134
 runQA.C:135
 runQA.C:136
 runQA.C:137
 runQA.C:138
 runQA.C:139
 runQA.C:140
 runQA.C:141
 runQA.C:142
 runQA.C:143
 runQA.C:144
 runQA.C:145
 runQA.C:146
 runQA.C:147
 runQA.C:148
 runQA.C:149
 runQA.C:150
 runQA.C:151
 runQA.C:152
 runQA.C:153
 runQA.C:154
 runQA.C:155
 runQA.C:156
 runQA.C:157
 runQA.C:158
 runQA.C:159
 runQA.C:160
 runQA.C:161
 runQA.C:162
 runQA.C:163
 runQA.C:164
 runQA.C:165
 runQA.C:166
 runQA.C:167
 runQA.C:168
 runQA.C:169
 runQA.C:170
 runQA.C:171
 runQA.C:172
 runQA.C:173
 runQA.C:174
 runQA.C:175
 runQA.C:176
 runQA.C:177
 runQA.C:178
 runQA.C:179
 runQA.C:180
 runQA.C:181
 runQA.C:182
 runQA.C:183
 runQA.C:184
 runQA.C:185
 runQA.C:186
 runQA.C:187
 runQA.C:188
 runQA.C:189
 runQA.C:190
 runQA.C:191
 runQA.C:192
 runQA.C:193
 runQA.C:194
 runQA.C:195
 runQA.C:196
 runQA.C:197
 runQA.C:198
 runQA.C:199
 runQA.C:200
 runQA.C:201
 runQA.C:202
 runQA.C:203
 runQA.C:204
 runQA.C:205
 runQA.C:206
 runQA.C:207
 runQA.C:208
 runQA.C:209
 runQA.C:210
 runQA.C:211
 runQA.C:212
 runQA.C:213
 runQA.C:214
 runQA.C:215
 runQA.C:216
 runQA.C:217
 runQA.C:218
 runQA.C:219
 runQA.C:220
 runQA.C:221
 runQA.C:222
 runQA.C:223
 runQA.C:224
 runQA.C:225
 runQA.C:226
 runQA.C:227
 runQA.C:228
 runQA.C:229
 runQA.C:230
 runQA.C:231
 runQA.C:232
 runQA.C:233
 runQA.C:234
 runQA.C:235
 runQA.C:236
 runQA.C:237
 runQA.C:238
 runQA.C:239
 runQA.C:240
 runQA.C:241
 runQA.C:242
 runQA.C:243
 runQA.C:244
 runQA.C:245
 runQA.C:246
 runQA.C:247
 runQA.C:248
 runQA.C:249
 runQA.C:250
 runQA.C:251
 runQA.C:252
 runQA.C:253
 runQA.C:254
 runQA.C:255
 runQA.C:256
 runQA.C:257
 runQA.C:258
 runQA.C:259
 runQA.C:260
 runQA.C:261
 runQA.C:262
 runQA.C:263
 runQA.C:264
 runQA.C:265
 runQA.C:266
 runQA.C:267
 runQA.C:268
 runQA.C:269
 runQA.C:270
 runQA.C:271
 runQA.C:272
 runQA.C:273
 runQA.C:274
 runQA.C:275
 runQA.C:276
 runQA.C:277
 runQA.C:278
 runQA.C:279
 runQA.C:280
 runQA.C:281
 runQA.C:282
 runQA.C:283