]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ANALYSIS/macros/AODtrainsim.C
Fix in physics selection OADB
[u/mrichter/AliRoot.git] / ANALYSIS / macros / AODtrainsim.C
1 // ### Settings that make sense when using the Alien plugin
2 //==============================================================================
3 Int_t       runOnData          = 0;       // Set to 1 if processing real data
4 Int_t       iCollision         = 0;       // 0=pp, 1=Pb-Pb
5 Int_t       run_flag           = 1100;   // year (2011 = 1100)
6 //==============================================================================
7 Bool_t      doCDBconnect      = 1;
8 Bool_t      usePhysicsSelection = kTRUE; // use physics selection
9 Bool_t      useTender           = kFALSE; // use tender wagon
10 Bool_t      useCentrality       = kFALSE; // centrality
11 Bool_t      useV0tender         = kFALSE;  // use V0 correction in tender
12 Bool_t      useDBG              = kTRUE;  // activate debugging
13 Bool_t      useMC               = kTRUE;  // use MC info
14 Bool_t      useKFILTER          = kTRUE;  // use Kinematics filter
15 Bool_t      useTR               = kTRUE;  // use track references
16 Bool_t      useCORRFW           = kFALSE; // do not change
17 Bool_t      useAODTAGS          = kFALSE; // use AOD tags
18 Bool_t      useSysInfo          = kFALSE; // use sys info
19
20 // ### Analysis modules to be included. Some may not be yet fully implemented.
21 //==============================================================================
22 Int_t       iAODhandler        = 1;      // Analysis produces an AOD or dAOD's
23 Int_t       iESDfilter         = 1;      // ESD to AOD filter (barrel + muon tracks)
24 Int_t       iMUONcopyAOD       = 1;      // Task that copies only muon events in a separate AOD (PWG3)
25 Int_t       iJETAN             = 0;      // Jet analysis (PWG4)
26 Int_t       iJETANdelta        = 0;      // Jet delta AODs
27 Int_t       iPWGHFvertexing     = 1;      // Vertexing HF task (PWG3)
28 Int_t       iPWGDQJPSIfilter    = 0;      // JPSI filtering (PWG3)
29 Int_t       iPWGHFd2h           = 1;      // D0->2 hadrons (PWG3)
30 Int_t       iPIDResponse        = 1;      // PID response
31 Int_t       iPWGLFForward       = 1;      // Forward mult task (PWGLF)
32
33 Int_t run_number = 0;
34
35 // ### Configuration macros used for each module
36 //==============================================================================
37  TString configPWGHFd2h = (iCollision==0)?"$ALICE_ROOT/PWGHF/vertexingHF/ConfigVertexingHF.C"
38                           :"$ALICE_ROOT/PWGHF/vertexingHF/ConfigVertexingHF_Pb_AllCent.C";
39 //                            :"$ALICE_ROOT/PWGHF/vertexingHF/ConfigVertexingHF_Pb_AllCent_NoLS_NoDstar_16var.C";
40 //                            :"$ALICE_ROOT/PWGHF/vertexingHF/ConfigVertexingHF_ITSUpgrade_16var.C";
41 // Temporaries.
42 class AliOADBPhysicsSelection;                                                                                                                  
43 AliOADBPhysicsSelection *CreateOADBphysicsSelection();
44 void AODmerge();
45 void AddAnalysisTasks();
46 Bool_t LoadCommonLibraries();
47 Bool_t LoadAnalysisLibraries();
48 Bool_t LoadLibrary(const char *);
49
50 TChain *CreateChain();
51 const char *cdbPath = "raw://";
52
53 //______________________________________________________________________________
54 void AODtrainsim(Int_t merge=0)
55 {
56 // Main analysis train macro.
57
58   if (merge || doCDBconnect) {
59     TGrid::Connect("alien://");
60     if (!gGrid || !gGrid->IsConnected()) {
61       ::Error("AODtrainsim", "No grid connection");
62       return;
63     }
64   }
65   // Set temporary merging directory to current one
66   gSystem->Setenv("TMPDIR", gSystem->pwd());
67   // Set temporary compilation directory to current one
68   gSystem->SetBuildDir(gSystem->pwd(), kTRUE);
69    printf("==================================================================\n");
70    printf("===========    RUNNING FILTERING TRAIN   ==========\n");
71    printf("==================================================================\n");
72    printf("=  Configuring analysis train for:                               =\n");
73    if (usePhysicsSelection)   printf("=  Physics selection                                                =\n");
74    if (useTender)    printf("=  TENDER                                                        =\n");
75    if (iESDfilter)   printf("=  ESD filter                                                    =\n");
76    if (iMUONcopyAOD) printf("=  MUON copy AOD                                                 =\n");
77    if (iJETAN)       printf("=  Jet analysis                                                  =\n");
78    if (iJETANdelta)  printf("=     Jet delta AODs                                             =\n");
79    if (iPWGHFvertexing) printf("=  PWGHF vertexing                                                =\n");
80    if (iPWGDQJPSIfilter) printf("=  PWGDQ j/psi filter                                             =\n");
81    if (iPWGHFd2h) printf("=  PWGHF D0->2 hadrons QA                                     =\n");
82
83    // Load common libraries and set include path
84    if (!LoadCommonLibraries()) {
85       ::Error("AnalysisTrain", "Could not load common libraries");
86       return;
87    }
88     
89    // Make the analysis manager and connect event handlers
90    AliAnalysisManager *mgr  = new AliAnalysisManager("Analysis Train", "Production train");
91    if (useSysInfo) mgr->SetNSysInfo(100);
92    // Load analysis specific libraries
93    if (!LoadAnalysisLibraries()) {
94       ::Error("AnalysisTrain", "Could not load analysis libraries");
95       return;
96    }   
97
98    // Create input handler (input container created automatically)
99    // ESD input handler
100    AliESDInputHandler *esdHandler = new AliESDInputHandler();
101    mgr->SetInputEventHandler(esdHandler);       
102    // Monte Carlo handler
103    if (useMC) {
104       AliMCEventHandler* mcHandler = new AliMCEventHandler();
105       mgr->SetMCtruthEventHandler(mcHandler);
106       mcHandler->SetPreReadMode(1);
107       mcHandler->SetReadTR(useTR); 
108    }   
109    // AOD output container, created automatically when setting an AOD handler
110    if (iAODhandler) {
111       // AOD output handler
112       AliAODHandler* aodHandler   = new AliAODHandler();
113       aodHandler->SetOutputFileName("AliAOD.root");
114       mgr->SetOutputEventHandler(aodHandler);
115    }
116    // Debugging if needed
117    if (useDBG) mgr->SetDebugLevel(3);
118
119    AddAnalysisTasks(cdbPath);
120    if (merge) {
121       AODmerge();
122       mgr->InitAnalysis();
123       mgr->SetGridHandler(new AliAnalysisAlien);
124       mgr->StartAnalysis("gridterminate",0);
125       return;
126    }   
127    // Run the analysis                                                                                                                     
128    //
129    TChain *chain = CreateChain();
130    if (!chain) return;
131                                                                                                                                                    
132    TStopwatch timer;
133    timer.Start();
134    mgr->SetSkipTerminate(kTRUE);
135    if (mgr->InitAnalysis()) {
136       mgr->PrintStatus();
137       mgr->StartAnalysis("local", chain);
138    }
139    timer.Print();
140 }                                                                                                                                          
141                                                                                                                                             
142 //______________________________________________________________________________                                                           
143 void AddAnalysisTasks(const char *cdb_location){                                                                                                                                          
144   // Add all analysis task wagons to the train                                                                                               
145    AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();                                                                     
146
147   //
148   // Tender and supplies. Needs to be called for every event.
149   //
150    AliAnalysisManager::SetCommonFileName("AODQA.root");
151     //
152    // PIDResponse(JENS)
153    //
154    if (iPIDResponse) {
155      gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPIDResponse.C"); 
156      AliAnalysisTaskPIDResponse *PIDResponse = AddTaskPIDResponse(kTRUE);
157 //     PIDResponse->SelectCollisionCandidates(AliVEvent::kAny);
158    }  
159   // CDB connection
160   //
161   if (doCDBconnect && !useTender) {
162     gROOT->LoadMacro("$ALICE_ROOT/PWGPP/PilotTrain/AddTaskCDBconnect.C");
163     AliTaskCDBconnect *taskCDB = AddTaskCDBconnect(cdb_location, run_number);
164     if (!taskCDB) return;
165     AliCDBManager *cdb = AliCDBManager::Instance();
166     cdb->SetDefaultStorage(cdb_location);
167 //    taskCDB->SetRunNumber(run_number);
168   }    
169    if (useTender) {
170       gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/TenderSupplies/AddTaskTender.C");
171       // IF V0 tender needed, put kTRUE below
172       AliAnalysisTaskSE *tender = AddTaskTender(useV0tender);
173 //      tender->SetDebugLevel(2);
174    }
175
176    if (usePhysicsSelection) {
177    // Physics selection task
178       gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
179       mgr->RegisterExtraFile("event_stat.root");
180       AliPhysicsSelectionTask *physSelTask = AddTaskPhysicsSelection(useMC);
181 //      AliOADBPhysicsSelection * oadbDefaultPbPb = CreateOADBphysicsSelection();      
182 //      physSelTask->GetPhysicsSelection()->SetCustomOADBObjects(oadbDefaultPbPb,0,0);
183       mgr->AddStatisticsTask(AliVEvent::kAny);
184     }
185    // Centrality (only Pb-Pb)
186    if (useCentrality) {
187       gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskCentrality.C");
188       AliCentralitySelectionTask *taskCentrality = AddTaskCentrality();
189       taskCentrality->SetMCInput();
190     //  taskCentrality->SelectCollisionCandidates(AliVEvent::kAny);
191    }
192    
193 // --- PWGLF - Forward (cholm@nbi.dk) -----------------------------
194    if (iPWGLFForward && usePhysicsSelection) { 
195         gROOT->LoadMacro("$ALICE_ROOT/PWGLF/FORWARD/analysis2/AddTaskForwardMult.C");
196      UShort_t pwglfForwardSys = 0; // iCollision+1; // pp:1, PbPb:2, pPb:3
197      UShort_t pwglfSNN        = 0;            // GeV, 0==unknown
198      Short_t  pwglfField      = 0;
199      AddTaskForwardMult(useMC && useTR,        // Need track-refs 
200                         pwglfForwardSys,       // Collision system
201                         pwglfSNN, 
202                         pwglfField);
203         gROOT->LoadMacro("$ALICE_ROOT/PWGLF/FORWARD/analysis2/AddTaskCentralMult.C");
204         AddTaskCentralMult(useMC, pwglfForwardSys, pwglfSNN, pwglfField);
205    }
206  
207    
208    
209     if (iESDfilter) {
210       //  ESD filter task configuration.
211       gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/ESDfilter/macros/AddTaskESDFilter.C");
212       if (iMUONcopyAOD) {
213          printf("Registering delta AOD file\n");
214          mgr->RegisterExtraFile("AliAOD.Muons.root");
215          mgr->RegisterExtraFile("AliAOD.Dimuons.root");
216       }
217       AliAnalysisTaskESDfilter *taskesdfilter = 
218                  AddTaskESDFilter(useKFILTER, 
219                                   iMUONcopyAOD,         // write Muon AOD
220                                   kFALSE,               // write dimuon AOD 
221                                   kFALSE,               // usePhysicsSelection 
222                                   kFALSE,               // centrality OBSOLETE
223                                   kTRUE,                // enable TPS only tracks
224                                   kFALSE,               // disable cascades
225                                   kFALSE,               // disable kinks
226                                   run_flag);            // run flag (YY00)
227    }   
228
229 // ********** PWG3 wagons ******************************************************           
230    // PWG3 vertexing
231    if (iPWGHFvertexing) {
232       gROOT->LoadMacro("$ALICE_ROOT/PWGHF/vertexingHF/macros/AddTaskVertexingHF.C");
233       if (!iPWGHFd2h) TFile::Cp(gSystem->ExpandPathName(configPWG3d2h.Data()), "file:ConfigVertexingHF.C");
234       AliAnalysisTaskSEVertexingHF *taskvertexingHF = AddTaskVertexingHF();
235       if (!taskvertexingHF) ::Warning("AnalysisTrainNew", "AliAnalysisTaskSEVertexingHF cannot run for this train conditions - EXCLUDED");
236       else mgr->RegisterExtraFile("AliAOD.VertexingHF.root");
237       taskvertexingHF->SelectCollisionCandidates(0);
238    }   
239       
240    // PWG3 JPSI filtering (only pp)
241    if (iPWGDQJPSIfilter && (iCollision==0)) {
242       gROOT->LoadMacro("$ALICE_ROOT/PWGDQ/dielectron/macros/AddTaskJPSIFilter.C");
243       AliAnalysisTaskSE *taskJPSIfilter = AddTaskJPSIFilter();
244       if (!taskJPSIfilter) ::Warning("AnalysisTrainNew", "AliAnalysisTaskDielectronFilter cannot run for this train conditions - EXCLUDED");
245       else mgr->RegisterExtraFile("AliAOD.Dielectron.root");
246       taskJPSIfilter->SelectCollisionCandidates(0);
247    }   
248
249    // PWG3 D2h
250    if (iPWGHFd2h) {   
251      gROOT->LoadMacro("$ALICE_ROOT/PWGHF/vertexingHF/AddD2HTrain.C");
252      TFile::Cp(gSystem->ExpandPathName(configPWGHFd2h.Data()), "file:ConfigVertexingHF.C");
253      AddD2HTrain(kFALSE, 1,0,0,0,0,0,0,0,0,0,0);                                 
254    }
255    
256    // ********** PWG4 wagons ******************************************************
257    // Jet analysis
258
259    // Configurations flags, move up?
260    TString kDeltaAODJetName = "AliAOD.Jets.root"; //
261    Bool_t  kIsPbPb = (iCollision==0)?false:true; // can be more intlligent checking the name of the data set
262    TString kDefaultJetBackgroundBranch = "";
263    TString kJetSubtractBranches = "";
264    UInt_t kHighPtFilterMask = 768;// from esd filter
265    UInt_t iPhysicsSelectionFlag = 0;
266    if (iJETAN) {
267      gROOT->LoadMacro("$ALICE_ROOT/PWGJE/macros/AddTaskJets.C");
268      // Default jet reconstructor running on ESD's
269      AliAnalysisTaskJets *taskjets = AddTaskJets("AOD","UA1",0.4,kHighPtFilterMask,1.,0); // no background subtraction     
270      if (!taskjets) ::Fatal("AnalysisTrainNew", "AliAnalysisTaskJets cannot run for this train conditions - EXCLUDED");
271      if(kDeltaAODJetName.Length()>0) taskjets->SetNonStdOutputFile(kDeltaAODJetName.Data());
272      if (iJETANdelta) {
273         //            AddTaskJetsDelta("AliAOD.Jets.root"); // need to modify this accordingly in the add task jets
274         mgr->RegisterExtraFile(kDeltaAODJetName.Data());
275         TString cTmp("");
276         if(kIsPbPb){
277           // UA1 intrinsic background subtraction
278           taskjets = AddTaskJets("AOD","UA1",0.4,kHighPtFilterMask,1.,2); // background subtraction
279           if(kDeltaAODJetName.Length()>0)taskjets->SetNonStdOutputFile(kDeltaAODJetName.Data());
280        }
281        // SICONE 
282        taskjets = AddTaskJets("AOD","SISCONE",0.4,kHighPtFilterMask,0.15,0); //no background subtration to be done later....                                                                                  
283        if(kDeltaAODJetName.Length()>0)taskjets->SetNonStdOutputFile(kDeltaAODJetName.Data());
284        cTmp = taskjets->GetNonStdBranch();
285        if(cTmp.Length()>0)kJetSubtractBranches += Form("%s ",cTmp.Data());
286          
287        // Add the clusters..
288        gROOT->LoadMacro("$ALICE_ROOT/PWGJE/macros/AddTaskJetCluster.C");
289        AliAnalysisTaskJetCluster *taskCl = 0;
290        Float_t fCenUp = 0;
291        Float_t fCenLo = 0;
292        Float_t fTrackEtaWindow = 0.9;
293        taskCl = AddTaskJetCluster("AOD","",kHighPtFilterMask,iPhysicsSelectionFlag,"KT",0.4,0,1, kDeltaAODJetName.Data(),0.15,fTrackEtaWindow,0); // this one is for the background and random jets, random cones with no skip                                                                                 
294        taskCl->SetBackgroundCalc(kTRUE);
295        taskCl->SetNRandomCones(10);
296        taskCl->SetCentralityCut(fCenLo,fCenUp);
297        taskCl->SetGhostEtamax(fTrackEtaWindow);
298        kDefaultJetBackgroundBranch = Form("%s_%s",AliAODJetEventBackground::StdBranchName(),taskCl->GetJetOutputBranch());
299
300        taskCl = AddTaskJetCluster("AOD","",kHighPtFilterMask,iPhysicsSelectionFlag,"ANTIKT",0.4,2,1,kDeltaAODJetName.Data(),0.15);
301        taskCl->SetCentralityCut(fCenLo,fCenUp);
302        if(kIsPbPb)taskCl->SetBackgroundBranch(kDefaultJetBackgroundBranch.Data());
303        taskCl->SetNRandomCones(10);
304        kJetSubtractBranches += Form("%s ",taskCl->GetJetOutputBranch());
305
306        taskCl = AddTaskJetCluster("AOD","",kHighPtFilterMask,iPhysicsSelectionFlag,"ANTIKT",0.2,0,1,kDeltaAODJetName.Data(),0.15);
307        taskCl->SetCentralityCut(fCenLo,fCenUp);
308        if(kIsPbPb)taskCl->SetBackgroundBranch(kDefaultJetBackgroundBranch.Data());
309        kJetSubtractBranches += Form("%s ",taskCl->GetJetOutputBranch());
310          
311        // DO THE BACKGROUND SUBTRACTION
312        if(kIsPbPb&&kJetSubtractBranches.Length()){
313          gROOT->LoadMacro("$ALICE_ROOT/PWGJE/macros/AddTaskJetBackgroundSubtract.C");
314          AliAnalysisTaskJetBackgroundSubtract *taskSubtract = 0;
315          taskSubtract = AddTaskJetBackgroundSubtract(kJetSubtractBranches,1,"B0","B%d");
316          taskSubtract->SetBackgroundBranch(kDefaultJetBackgroundBranch.Data());
317          if(kDeltaAODJetName.Length()>0)taskSubtract->SetNonStdOutputFile(kDeltaAODJetName.Data());
318        }
319      } 
320    }
321 }
322
323 //______________________________________________________________________________
324 Bool_t LoadCommonLibraries()
325 {
326 // Load common analysis libraries.
327    if (!gSystem->Getenv("ALICE_ROOT")) {
328       ::Error("AnalysisTrainNew.C::LoadCommonLibraries", "Analysis train requires that analysis libraries are compiled with a local AliRoot"); 
329       return kFALSE;
330    }   
331    Bool_t success = kTRUE;
332    // Load framework classes. Par option ignored here.
333    success &= LoadLibrary("libSTEERBase.so");
334    success &= LoadLibrary("libESD.so");
335    success &= LoadLibrary("libAOD.so");
336    success &= LoadLibrary("libANALYSIS.so");
337    success &= LoadLibrary("libOADB.so");
338    success &= LoadLibrary("libANALYSISalice.so");
339    success &= LoadLibrary("libESDfilter.so");
340    success &= LoadLibrary("libCORRFW.so");
341    gROOT->ProcessLine(".include $ALICE_ROOT/include");
342    if (success) {
343       ::Info("AnalysisTrainNew.C::LoadCommodLibraries", "Load common libraries:    SUCCESS");
344       ::Info("AnalysisTrainNew.C::LoadCommodLibraries", "Include path for Aclic compilation:\n%s",
345               gSystem->GetIncludePath());
346    } else {           
347       ::Info("AnalysisTrainNew.C::LoadCommodLibraries", "Load common libraries:    FAILED");
348    }   
349    return success;
350 }
351
352 //______________________________________________________________________________
353 Bool_t LoadAnalysisLibraries()
354 {
355 // Load common analysis libraries.
356    if (useTender || doCDBconnect) {
357       if (!LoadLibrary("TENDER") ||
358           !LoadLibrary("TENDERSupplies")) return kFALSE;
359    }       
360    // CDBconnect
361    if (doCDBconnect && !useTender) {
362       if (!LoadLibrary("PWGPP")) return kFALSE;
363    }
364
365    if (iESDfilter || iPWGMuonTrain) {
366       if (!LoadLibrary("PWGmuon")) return kFALSE;
367    }   
368    // JETAN
369    if (iJETAN) {
370       if (!LoadLibrary("JETAN")) return kFALSE;
371    }
372    if (iJETANdelta) {
373       if (!LoadLibrary("JETAN") ||
374           !LoadLibrary("CGAL") ||
375           !LoadLibrary("fastjet") ||
376           !LoadLibrary("siscone") ||
377           !LoadLibrary("SISConePlugin") ||
378           !LoadLibrary("FASTJETAN")) return kFALSE;
379    }     
380    // PWG3 Vertexing HF
381    if (iPWGHFvertexing || iPWGHFd2h) {
382       if (!LoadLibrary("PWGflowBase") ||
383           !LoadLibrary("PWGflowTasks") ||
384           !LoadLibrary("PWGHFvertexingHF")) return kFALSE;
385    }    
386  //    if (iPWGHFvertexing || iPWG3d2h) {
387  //     if (!LoadLibrary("PWG3base") ||
388  //         !LoadLibrary("PWGHFvertexingHF")) return kFALSE;
389  //  }   
390    // PWG3 dielectron
391    if (iPWGDQJPSIfilter) {
392       if (!LoadLibrary("PWGDQdielectron")) return kFALSE;
393    }   
394    
395    ::Info("AnalysisTrainNew.C::LoadAnalysisLibraries", "Load other libraries:   SUCCESS");
396    return kTRUE;
397 }
398
399
400 //______________________________________________________________________________
401 Bool_t LoadLibrary(const char *module)
402 {
403 // Load a module library in a given mode. Reports success.
404    Int_t result;
405    TString mod(module);
406    if (!mod.Length()) {
407       ::Error("AnalysisTrainNew.C::LoadLibrary", "Empty module name");
408       return kFALSE;
409    }   
410    // If a library is specified, just load it
411    if (mod.EndsWith(".so")) {
412       mod.Remove(mod.Index(".so"));
413       result = gSystem->Load(mod);
414       if (result < 0) {
415          ::Error("AnalysisTrainNew.C::LoadLibrary", "Could not load library %s", module);
416          return kFALSE;
417       }
418       return kTRUE;
419    } 
420    // Check if the library is already loaded
421    if (strlen(gSystem->GetLibraries(Form("%s.so", module), "", kFALSE)) > 0) return kTRUE;    
422    result = gSystem->Load(Form("lib%s.so", module));
423    if (result < 0) {
424       ::Error("AnalysisTrainNew.C::LoadLibrary", "Could not load module %s", module);
425       return kFALSE;
426    }
427    return kTRUE;
428 }           
429
430
431 //______________________________________________________________________________
432 TChain *CreateChain()
433 {
434 // Create the input chain
435    chain = new TChain("esdTree");
436    if (gSystem->AccessPathName("AliESDs.root")) 
437       ::Error("AnalysisTrainNew.C::CreateChain", "File: AliESDs.root not in ./data dir");
438    else 
439        chain->Add("AliESDs.root");
440    if (chain->GetNtrees()) return chain;
441    return NULL;
442 }   
443
444 //______________________________________________________________________________
445 void AODmerge()
446 {
447 // Merging method. No staging and no terminate phase.
448   TStopwatch timer;
449   timer.Start();
450   TString outputDir = "wn.xml";
451   TString outputFiles = "EventStat_temp.root,AODQA.root,AliAOD.root,AliAOD.VertexingHF.root,AliAOD.Muons.root,AliAOD.Jets.root,pyxsec_hists.root";
452   TString mergeExcludes = "";
453   TObjArray *list = outputFiles.Tokenize(",");
454   TIter *iter = new TIter(list);
455   TObjString *str;
456   TString outputFile;
457   Bool_t merged = kTRUE;
458   while((str=(TObjString*)iter->Next())) {
459     outputFile = str->GetString();
460     // Skip already merged outputs
461     if (!gSystem->AccessPathName(outputFile)) {
462        printf("Output file <%s> found. Not merging again.",outputFile.Data());
463        continue;
464     }
465     if (mergeExcludes.Contains(outputFile.Data())) continue;
466     merged = AliAnalysisAlien::MergeOutput(outputFile, outputDir, 10, 0);
467     if (!merged) {
468        printf("ERROR: Cannot merge %s\n", outputFile.Data());
469        continue;
470     }
471   }
472   // all outputs merged, validate
473   ofstream out;
474   out.open("outputs_valid", ios::out);
475   out.close();
476   timer.Print();
477 }