1 //===================== ANALYSIS TRAIN =========================================
2 // To use: copy this macro to your work directory, modify the global part to match
3 // your needs, then run root.
4 // root[0] .L AnalysisTrainHMPID.C
5 // Grid full mode as below (other modes: test, offline, submit, terminate)
6 // root[1] AnalysisTrainHMPID("grid", "full")
7 // CAF mode (requires root v5-23-02 + aliroot v4-16-Rev08)
8 // root[2] AnalysisTrainHMPID("proof")
9 // Local mode requires AliESds.root or AliAOD.root in ./data directory
10 // root[3] AnalysisTrainHMPID("local")
11 // In proof and grid modes, a token is needed and sourcing the produced environment file.
14 // =============================================================================
15 // ### General Steering variables
16 // =============================================================================
17 //== general setup variables
18 TString kTrainName = "hmpidAnalysis"; // (no blancs or special characters)
19 TString kJobTag = "HMPID Tasks analysis train configured"; //
20 Bool_t kUsePAR = kFALSE; // use par files for extra libs
21 Bool_t kUseCPAR = kFALSE; // use par files for common libs
22 Bool_t kFillAOD = kFALSE; // switch of AOD filling for on the fly analysis
24 Int_t iAODanalysis = 0; // Analysis on input AOD's
25 Int_t iAODhandler = 1; // Analysis produces an AOD or dAOD's
26 Int_t iESDfilter = 0; // ESD to AOD filter (barrel + muon tracks)
27 Int_t iPhysicsSelection = 1; // Physics selection task
28 Int_t iCentrality = 0; // Physics selection task
29 Bool_t kUseKinefilter = kFALSE; // use Kinematics filter
30 Bool_t kUseMuonfilter = kFALSE; // use muon filter
31 TString kCommonOutputFileName = "HmpidOutput.root";
34 //== general process variables
36 // ### Other flags to steer the analysis
37 //==============================================================================
38 Bool_t kSkipTerminate = kFALSE; // Do not call Teminate
39 Bool_t kDebugLevel = kTRUE; // activate debugging
40 Int_t kUseSysInfo = 0; // activate debugging
41 Long64_t kNumberOfEvents = 1234567890; // number of events to process from the chain
42 Bool_t kUseMC = kFALSE; // use MC info
43 Bool_t kIsMC = kFALSE; // is MC info, if false it overwrites Use(AOD)MC
44 Bool_t kUseESDTags = kFALSE; // use ESD tags for selection
45 Bool_t kUseTR = kFALSE; // use track references
47 // ### Analysis modules to be included. Some may not be yet fully implemented.
48 //==============================================================================
49 Int_t iHMPID = 1; // Basic HMPID analysis task
50 Int_t iHMPIDperf = 0; // Basic HMPID performance task
51 Int_t iJETAN = 0; // Jet analysis (PWGJE) // 1 write standard 2 write non-standard jets
52 Int_t iHMPIDJets = 0; // Jet chemistry with HMPID
54 Int_t kHighPtFilterMask = 16; // change depending on the used AOD Filter
57 //==============================================================================
58 // ### PROOF Steering varibales
59 //==============================================================================
60 //== proof setup variables
61 TString kProofCluster = "alice-caf.cern.ch";
62 Bool_t kProofUseAFPAR = kTRUE; // use AF special par file
63 TString kProofAFversion = "VO_ALICE@AliRoot::v4-20-08-AN";
64 //== proof input and output variables
65 TString kProofDataSet = "/alice/sim/LHC10d2_117220";
66 //== proof process variables
67 Bool_t kProofClearPackages = kFALSE;
68 Int_t kProofEvents = 10000;
69 Int_t kProofOffset = 0;
71 //==============================================================================
72 // ### Grid plugin Steering varibiables
73 //==============================================================================
74 //== grid plugin setup variables
75 Bool_t kPluginUse = kTRUE; // do not change
76 Bool_t kPluginUseProductionMode = kFALSE; // use the plugin in production mode
77 TString kPluginRootVersion = "v5-33-02b"; // *CHANGE ME IF MORE RECENT IN GRID*
78 TString kPluginAliRootVersion = "v5-03-31-AN"; // *CHANGE ME IF MORE RECENT IN GRID*
79 Bool_t kPluginMergeViaJDL = kTRUE; // merge via JDL
80 Bool_t kPluginFastReadOption = kFALSE; // use xrootd flags to reduce timeouts
81 Bool_t kPluginOverwriteMode = kTRUE; // overwrite existing collections
82 Int_t kPluginOutputToRunNumber = 1; // write the output to subdirs named after run number
83 TString kPluginExecutableCommand = "aliroot -b -q";
85 // == grid plugin input and output variables
86 TString kGridDatadir = "/alice/data/2010/LHC10e";
87 TString kGridLocalRunList = "";
88 TString kGridWorkDir = ""; // Alien working directory
89 TString kGridOutdir = ""; // AliEn output directory. If blank will become output_<kTrainName>
90 TString kGridDataSet = ""; // sub working directory not to confuse different run xmls
91 Int_t kGridRunRange[2] = {128260,128260}; // Set the run range
92 TString kGridRunPattern = "%03d"; // important for leading zeroes!!
93 TString kGridPassPattern = "/ESDs/pass2";
94 TString kGridExtraFiles = ""; // files that will be added to the input list in the JDL...
95 Int_t kGridMaxMergeFiles = 12; // Number of files merged in a chunk grid run range
96 Int_t kGridMaxMergeStages = 3; // Number of stages in the merging procedure
97 TString kGridMergeExclude = "AliAOD.root"; // Files that should not be merged
98 TString kGridOutputStorages = "disk=2"; // Make replicas on the storages
99 // == grid process variables
100 Int_t kGridRunsPerMaster = 1; // Number of runs per master job
101 Int_t kGridFilesPerJob = 50; // Maximum number of files per job (gives size of AOD)
103 //==============================================================================
104 // ### Local Steering variables
105 //==============================================================================
106 //== local setup variables
107 //== local input and output variables
108 TString kLocalXMLDataset = ""; // Change local xml dataset for local interactive analysis
109 TString kLocalDataList = "local_deltaaod.txt"; // Change local xml dataset for local interactive analysis
110 // == local process variables
115 TString anaPars = "";
116 TString anaLibs = "";
117 TString anaLibsExtra = "";
118 TString anaSources = "";
119 // Function signatures
120 class AliAnalysisAlien;
122 //______________________________________________________________________________
123 void AnalysisTrainHMPID(const char *analysis_mode="local", const char *plugin_mode="",
124 const char *config_file="",Int_t iOffset = 0)
126 // Main analysis train macro. If a configuration file is provided, all parameters
127 // are taken from there but may be altered by CheckModuleFlags.
129 if (strlen(config_file) && !LoadConfig(config_file)) return;
131 if(iOffset)kProofOffset = iOffset;
132 TString smode(analysis_mode);
134 // Check compatibility of selected modules
135 CheckModuleFlags(smode);
137 printf("==================================================================\n");
138 printf("=========== RUNNING ANALYSIS TRAIN %s IN %s MODE ==========\n", kTrainName.Data(),smode.Data());
139 printf("==================================================================\n");
140 printf("= Configuring analysis train for: =\n");
141 if (iAODanalysis) printf("= AOD analysis =\n");
142 else printf("= ESD analysis =\n");
143 if (iPhysicsSelection) printf("= Physics selection =\n");
144 if (iCentrality) printf("= Centrality =\n");
145 if (iESDfilter) printf("= ESD filter =\n");
146 if (iJETAN) printf("= Jet analysis =\n");
147 if (iHMPID) printf("= HMPID generic =\n");
148 if (iHMPIDperf) printf("= HMPID performance =\n");
149 if (iHMPIDJets) printf("= HMPID Jet chemistry =\n");
150 printf("==================================================================\n");
151 printf(":: use MC truth %d\n", (UInt_t)kUseMC);
152 printf(":: use KINE filter %d\n", (UInt_t)kUseKinefilter);
153 printf(":: use track refs %d\n", (UInt_t)kUseTR);
154 printf(":: use tags %d\n", (UInt_t)kUseESDTags);
155 printf(":: use debugging %d\n", (UInt_t)kDebugLevel);
156 printf(":: use PAR files %d\n", (UInt_t)kUsePAR);
157 printf(":: use AliEn plugin %d\n", (UInt_t)kPluginUse);
159 //==========================================================================
160 // Connect to back-end system
161 if (!Connect(smode)) {
162 ::Error("AnalysisTrain", "Could not connect to %s back-end", analysis_mode);
166 // Load common libraries and set include path
167 if (!LoadCommonLibraries(smode)) {
168 ::Error("AnalysisTrain", "Could not load common libraries");
173 // Make the analysis manager and connect event handlers
174 AliAnalysisManager *mgr = new AliAnalysisManager("HMPIDTrain", "HMPID train");
175 if (kCommonOutputFileName.Length()>0)mgr->SetCommonFileName(kCommonOutputFileName.Data());
177 if (!strcmp(plugin_mode, "test")) mgr->SetNSysInfo(1);
178 if (kUseSysInfo)mgr->SetNSysInfo(kUseSysInfo);
179 mgr->SetSkipTerminate(kSkipTerminate);
181 // Load analysis specific libraries
182 if (!LoadAnalysisLibraries(smode)) {
183 ::Error("AnalysisTrain", "Could not load analysis libraries");
187 // Create input handler (input container created automatically)
190 AliAODInputHandler *aodH = new AliAODInputHandler();
191 mgr->SetInputEventHandler(aodH);
194 AliESDInputHandler *esdHandler = new AliESDInputHandler();
195 if (kUseESDTags) esdHandler->SetReadTags();
196 esdHandler->SetReadFriends(kFALSE);
197 mgr->SetInputEventHandler(esdHandler);
200 // Monte Carlo handler
201 if (kUseMC && !iAODanalysis) {
202 AliMCEventHandler* mcHandler = new AliMCEventHandler();
203 mgr->SetMCtruthEventHandler(mcHandler);
204 mcHandler->SetReadTR(kUseTR);
207 // AOD output container, created automatically when setting an AOD handler
209 // AOD output handler
210 AliAODHandler* aodHandler = new AliAODHandler();
211 aodHandler->SetOutputFileName("AliAOD.root");
212 aodHandler->SetFillAODforRun(kFillAOD);
214 mgr->SetOutputEventHandler(aodHandler);
215 AliAnalysisDataContainer *cout_aod = mgr->GetCommonOutputContainer();
216 cout_aod->SetSpecialOutput();
219 // Debugging if needed
221 mgr->SetDebugLevel(3);
224 mgr->RegisterExtraFile("syswatch.root");
225 if(kGridMergeExclude.Length())kGridMergeExclude += " ";
226 kGridMergeExclude += "syswatch.root";
228 AliLog::SetGlobalLogLevel(AliLog::kError);
231 //==========================================================================
232 // Create the chain. In this example it is created only from ALIEN files but
233 // can be done to work in batch or grid mode as well.
234 TChain *chain = CreateChain(smode, plugin_mode);
236 //==========================================================================
237 // Load the tasks configuration macros for all wagons. These files are supposed now to be
238 // in the current workdir, but in AliEn they will be in the file catalog,
239 // mapped from AliRoot and pecified in the jdl input list.
240 if(iPhysicsSelection && !iAODanalysis){
241 gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
242 AliPhysicsSelectionTask* physSelTask = AddTaskPhysicsSelection(kIsMC,kTRUE,kTRUE); // last flag also adds information on
245 if(iCentrality && !iAODanalysis){
246 gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskCentrality.C");
247 AliCentralitySelectionTask *taskCentrality = AddTaskCentrality();
248 taskCentrality->SetPass(2); // remember to set the pass you are processing!!!
251 if (iESDfilter && !iAODanalysis) {
252 // ESD filter task configuration.
253 gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskESDFilter.C");
254 AliAnalysisTaskESDfilter *taskesdfilter = AddTaskESDFilter(kUseKinefilter,kUseMuonfilter);
255 // if jet analysis is included, better use the following macro with kHighPtFilterMask=272
256 /* gROOT->LoadMacro("$ALICE_ROOT/PWGJE/macros/AddTaskESDFilterPWGJETrain.C");
257 AliAnalysisTaskESDfilter *taskesdfilter = AddTaskESDFilterPWGJETrain(kUseKinefilter,kUseMuonfilter);
258 taskesdfilter->DisableV0s();
259 taskesdfilter->DisableCascades();
260 taskesdfilter->DisableKinks();
261 taskesdfilter->DisablePmdClusters();
262 taskesdfilter->DisableCaloClusters();
263 taskesdfilter->DisableCells();*/
265 mgr->RegisterExtraFile("pyxsec_hists.root");
266 if(kGridMergeExclude.Length())kGridMergeExclude += " ";
267 kGridMergeExclude += "pyxsec_hists.root";
273 gROOT->LoadMacro("$ALICE_ROOT/PWGJE/macros/AddTaskJets.C");
274 AliAnalysisTaskJets *taskjets = 0;
275 if (iJETAN&1) taskjets = AddTaskJets("AOD","FASTJET",0.4,kHighPtFilterMask);
276 if (!taskjets) ::Warning("AnalysisTrainHMPID", "AliAnalysisTaskJets cannot run for this train conditions - EXCLUDED");
280 gROOT->LoadMacro("$ALICE_ROOT/HMPID/AddTaskHMPID.C");
281 AliHMPIDAnalysisTask *taskHmpid = AddTaskHMPID(kUseMC);
282 if (!taskHmpid) ::Warning("AnalysisTrainHMPID", "AliHMPIDAnalysisTask cannot run for this train conditions - EXCLUDED");
286 gROOT->LoadMacro("$ALICE_ROOT/HMPID/AddTaskHMPIDPerformance.C");
287 AliHMPIDPerformanceTask *taskHmpidPerformance = AddTaskHMPIDPerformance(kUseMC);
288 if (!taskHmpidPerformance) ::Warning("AnalysisTrainHMPID", "AliHMPIDPerformanceTask cannot run for this train conditions - EXCLUDED");
292 gROOT->LoadMacro("$ALICE_ROOT/HMPID/AddTaskJetsHMPID.C");
293 AliAnalysisTaskJetsHMPID *taskHmpidJets = AddTaskJetsHMPID("jetsAOD_FASTJET04_B0_Filter00272_Cut00150","jeteventbackground_clustersAOD_KT04_B0_Filter00256_Cut00150_Skip00");
294 if (!taskHmpidJets) ::Warning("AnalysisTrainHMPID", "AliAnalysisTaskJetsHMPID cannot run for this train conditions - EXCLUDED");
298 AliAnalysisGrid *alienHandler = CreateAlienHandler(plugin_mode);
299 AliAnalysisManager::GetAnalysisManager()->SetGridHandler(alienHandler);
302 if (mgr->InitAnalysis()) {
304 if (!strcmp(plugin_mode,"submit") && smode=="GRID"){
305 TString alien_workdir = gGrid->GetHomeDirectory();
306 alien_workdir += kGridWorkDir.Data();
307 if(kGridDataSet.Length()>0)alien_workdir += Form("/%s",kGridDataSet.Data());
308 AliAnalysisAlien *gridhandler = (AliAnalysisAlien*)mgr->GetGridHandler();
309 printf("=== AnalysisTrainHMPID:: Registering jdl in the work directory alien://%s/%s, should be done by the manager! ===\n",
310 alien_workdir.Data(),gridhandler->GetGridOutputDir());
313 dest = Form("%s/%s/%s.jdl",alien_workdir.Data(),gridhandler->GetGridOutputDir(),kTrainName.Data());
314 if(AliAnalysisAlien::FileExists(dest.Data())){
315 // Printf("%s exist on grid removing...",dest.Data());
316 // gGrid->Rm(dest.Data());
318 TFile::Cp(Form("file:%s.jdl",kTrainName.Data()),Form("alien://%s",dest.Data()));
322 dest = Form("%s/%s/%s_merge.jdl",alien_workdir.Data(),gridhandler->GetGridOutputDir(),kTrainName.Data());
323 if(AliAnalysisAlien::FileExists(dest.Data())){
324 // Printf("%s exist on grid removing...",dest.Data());
325 // gGrid->Rm(dest.Data());
327 TFile::Cp(Form("file:%s_merge.jdl",kTrainName.Data()),Form("alien://%s",dest.Data()));
330 AliLog::SetGlobalLogLevel(AliLog::kError);
331 if((kUseSysInfo>0 && smode=="LOCAL") || !strcmp(plugin_mode, "test")){
332 TFile *fM = TFile::Open("manager_local.root","RECREATE");
337 StartAnalysis(smode, chain);
339 if((kUseSysInfo>0 && smode=="LOCAL") || !strcmp(plugin_mode, "test")){
340 for(int i = 0;i < mgr->GetTopTasks()->GetEntries();i++){
344 if (!strcmp(plugin_mode, "offline") && smode=="GRID"){
345 // Offline mode path files
347 PatchAnalysisMacro();
353 //______________________________________________________________________________
354 void StartAnalysis(const char *mode, TChain *chain) {
357 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
358 if (!strcmp(mode, "LOCAL")) imode = 0;
359 if (!strcmp(mode, "PROOF")) imode = 1;
360 if (!strcmp(mode, "GRID")) imode = 2;
364 ::Error("AnalysisTrainHMPID.C::StartAnalysis", "Cannot create the chain");
367 mgr->StartAnalysis(mode, chain, kNumberOfEvents);
370 if (!kProofDataSet.Length()) {
371 ::Error("AnalysisTrainHMPID.C::StartAnalysis", "kProofDataSet is empty");
374 mgr->StartAnalysis(mode, kProofDataSet, kProofEvents,kProofOffset);
378 if (!mgr->GetGridHandler()) {
379 ::Error("AnalysisTrainHMPID.C::StartAnalysis", "Grid plugin not initialized");
382 mgr->StartAnalysis("grid");
385 ::Error("AnalysisTrainHMPID.C::StartAnalysis", "Cannot create the chain");
388 mgr->StartAnalysis(mode, chain);
394 //______________________________________________________________________________
395 void CheckModuleFlags(const char *mode) {
396 // Checks selected modules and insure compatibility
398 if (!strcmp(mode, "LOCAL")) imode = 0;
399 if (!strcmp(mode, "PROOF")) imode = 1;
400 if (!strcmp(mode, "GRID")) imode = 2;
404 kPluginAliRootVersion = ""; // NO aliroot if we use CPAR
409 ::Info("AnalysisTrainHMPID.C::CheckModuleFlags", "PAR files enabled due to PROOF analysis");
414 ::Info("AnalysisTrainHMPID.C::CheckModuleFlags", "AliEn plugin disabled since not in GRID mode");
419 // switch off anything related to MC
427 ::Info("AnalysisTrainHMPID.C::CheckModuleFlags", "MC usage disabled in analysis on AOD's");
431 ::Info("AnalysisTrainHMPID.C::CheckModuleFlags", "ESD filter disabled in analysis on AOD's");
433 if (iPhysicsSelection)
434 ::Info("AnalysisTrainHMPID.C::CheckModuleFlags", "Physics Selection disabled in analysis on AOD's");
435 iPhysicsSelection = 0;
438 ::Info("AnalysisTrainHMPID.C::CheckModuleFlags", "JETAN disabled in analysis on AOD's without AOD handler");
441 if(iHMPID)::Info("AnalysisTrainHMPID.C::CheckModuleFlags", "HMPID analysis disabled in analysis on AOD's");
443 if(iHMPIDperf)::Info("AnalysisTrainHMPID.C::CheckModuleFlags", "HMPID performance disabled in analysis on AOD's");
449 if(kUseKinefilter)::Info("AnalysisTrainHMPID.C::CheckModuleFlags", "Kine Filter disabled in analysis without MC");
450 kUseKinefilter = kFALSE;
456 kUseKinefilter = kFALSE;
457 kUseMuonfilter = kFALSE;
461 iJETANLib = iJETAN && 1;
462 if (iESDfilter) {iAODhandler=1;}
463 if (kUseKinefilter && !kUseMC) kUseKinefilter = kFALSE;
468 //______________________________________________________________________________
469 Bool_t Connect(const char *mode) {
470 // Connect <username> to the back-end system.
472 if (!strcmp(mode, "LOCAL")) imode = 0;
473 if (!strcmp(mode, "PROOF")) imode = 1;
474 if (!strcmp(mode, "GRID")) imode = 2;
475 TString username = gSystem->Getenv("alien_API_USER");
480 if (!username.Length()) {
481 ::Error(Form("AnalysisTrainHMPID.C::Connect <%s>", mode), "Make sure you:\n \
482 1. Have called: alien-token-init <username>\n \
483 2. Have called: >source /tmp/gclient_env_$UID");
486 ::Info("AnalysisTrainHMPID.C::Connect", "Connecting user <%s> to PROOF cluster <%s>",
487 username.Data(), kProofCluster.Data());
488 gEnv->SetValue("XSec.GSI.DelegProxy", "2");
489 TProof::Open(Form("%s@%s", username.Data(), kProofCluster.Data()));
491 if (strcmp(gSystem->Getenv("XrdSecGSISRVNAMES"), "lxfsrd0506.cern.ch"))
492 ::Error(Form("AnalysisTrainHMPID.C::Connect <%s>", mode), "Environment XrdSecGSISRVNAMES different from lxfsrd0506.cern.ch");
495 if(kProofClearPackages)gProof->ClearPackages();
498 if (!username.Length()) {
499 ::Error(Form("AnalysisTrainHMPID.C::Connect <%s>", mode), "Make sure you:\n \
500 1. Have called: alien-token-init <username>\n \
501 2. Have called: >source /tmp/gclient_env_$UID");
504 if (kPluginUse && !gSystem->Getenv("alien_CLOSE_SE")) {
505 ::Error(Form("AnalysisTrainHMPID.C::Connect <%s>", mode),
506 "When using the AliEn plugin it is preferable to define the \
507 variable alien_CLOSE_SE in your environment.");
510 ::Info("AnalysisTrainHMPID.C::Connect", "Connecting user <%s> to AliEn ...",
512 TGrid::Connect("alien://");
513 if (!gGrid || !gGrid->IsConnected()) return kFALSE;
516 ::Error("AnalysisTrainHMPID.C::Connect", "Unknown run mode: %s", mode);
519 ::Info("AnalysisTrainHMPID.C::Connect","Connected in %s mode", mode);
524 //______________________________________________________________________________
525 Bool_t LoadCommonLibraries(const char *mode)
527 // Load common analysis libraries.
529 if (!strcmp(mode, "LOCAL")) imode = 0;
530 if (!strcmp(mode, "PROOF")) imode = 1;
531 if (!strcmp(mode, "GRID")) imode = 2;
532 if (!gSystem->Getenv("ALICE_ROOT")) {
533 ::Error("AnalysisTrainHMPID.C::LoadCommonLibraries", "Analysis train requires that analysis libraries are compiled with a local AliRoot");
536 Bool_t success = kTRUE;
538 gSystem->Load("libTree.so");
539 gSystem->Load("libGeom.so");
540 gSystem->Load("libVMC.so");
541 gSystem->Load("libPhysics.so");
543 // Load framework classes. Par option ignored here.
548 success &= LoadLibrary("STEERBase", mode, kTRUE);
549 success &= LoadLibrary("ESD", mode, kTRUE);
550 success &= LoadLibrary("AOD", mode, kTRUE);
551 success &= LoadLibrary("ANALYSIS", mode, kTRUE);
552 success &= LoadLibrary("ANALYSISalice", mode, kTRUE);
553 success &= LoadLibrary("CORRFW", mode, kTRUE);
555 success &= LoadLibrary("libSTEERBase.so", mode, kTRUE);
556 success &= LoadLibrary("libESD.so", mode, kTRUE);
557 success &= LoadLibrary("libAOD.so", mode, kTRUE);
558 success &= LoadLibrary("libANALYSIS.so", mode, kTRUE);
559 success &= LoadLibrary("libANALYSISalice.so", mode, kTRUE);
560 success &= LoadLibrary("libCORRFW.so", mode, kTRUE);
561 gROOT->ProcessLine(".include $ALICE_ROOT/include");
565 if (!kProofUseAFPAR) {
566 success &= LoadLibrary("STEERBase", mode);
567 success &= LoadLibrary("ESD", mode);
568 success &= LoadLibrary("AOD", mode);
569 success &= LoadLibrary("ANALYSIS", mode);
570 success &= LoadLibrary("ANALYSISalice", mode);
571 success &= LoadLibrary("CORRFW", mode);
573 success &= !gProof->EnablePackage(kProofAFversion);
574 success &= LoadLibrary("CORRFW", mode);
578 ::Error("AnalysisTrainHMPID.C::LoadCommonLibraries", "Unknown run mode: %s", mode);
582 ::Info("AnalysisTrainHMPID.C::LoadCommodLibraries", "Load common libraries: SUCCESS");
583 ::Info("AnalysisTrainHMPID.C::LoadCommodLibraries", "Include path for Aclic compilation:\n%s",
584 gSystem->GetIncludePath());
586 ::Info("AnalysisTrainHMPID.C::LoadCommodLibraries", "Load common libraries: FAILED");
593 //______________________________________________________________________________
594 Bool_t LoadAnalysisLibraries(const char *mode)
596 // Load common analysis libraries.
597 Bool_t success = kTRUE;
599 if (!LoadLibrary("PWGHFbase", mode, kTRUE) ||
600 !LoadLibrary("PWGmuon", mode, kTRUE)) return kFALSE;
604 // this part needs some rework in case we do not need the fastjed finders for processing
605 if (!LoadLibrary("JETAN", mode, kTRUE)) return kFALSE;
606 if (!strcmp(mode, "PROOF")){
607 gProof->Exec("gSystem->Load\(\"/afs/cern.ch/user/d/dperrino/public/libCGAL.so\"\)", kTRUE);
608 gProof->Exec("gSystem->Load\(\"/afs/cern.ch/user/d/dperrino/public/libfastjet.so\"\)", kTRUE);
609 // problem when loading siscone copiled with different gcc version??
610 // gProof->Exec("gSystem->Load\(\"/afs/cern.ch/user/d/dperrino/public/libsiscone.so\"\)", kTRUE);
611 gProof->Exec("gSystem->Load\(\"/afs/cern.ch/user/d/dperrino/public/libSISConePlugin.so\"\)", kTRUE);
614 if (!LoadLibrary("CGAL", mode, kTRUE)) return kFALSE;
615 if (!LoadLibrary("fastjet", mode, kTRUE)) return kFALSE;
616 if (!LoadLibrary("siscone", mode, kTRUE)) return kFALSE;
617 if (!LoadLibrary("SISConePlugin", mode, kTRUE)) return kFALSE;
620 if (!LoadLibrary("libCGAL.so", mode, kTRUE)) return kFALSE;
621 if (!LoadLibrary("libfastjet.so", mode, kTRUE)) return kFALSE;
622 if (!LoadLibrary("libsiscone.so", mode, kTRUE)) return kFALSE;
623 if (!LoadLibrary("libSISConePlugin.so", mode, kTRUE)) return kFALSE;
625 if (!LoadLibrary("FASTJETAN", mode, kTRUE)) return kFALSE;
629 if (!LoadSource(Form("%s/HMPID/AliHMPIDAnalysisTask.cxx",gSystem->ExpandPathName("$ALICE_ROOT")), mode, kTRUE))return kFALSE;
633 if (!LoadSource(Form("%s/HMPID/AliHMPIDPerformanceTask.cxx",gSystem->ExpandPathName("$ALICE_ROOT")), mode, kTRUE))return kFALSE;
637 if (!LoadSource(Form("%s/HMPID/AliAnalysisTaskJetsHMPID.cxx",gSystem->ExpandPathName("$ALICE_ROOT")), mode, kTRUE))return kFALSE;
641 if (!LoadLibrary("JETAN", mode, kTRUE)) return kFALSE;
644 ::Info("AnalysisTrainHMPID.C::LoadAnalysisLibraries", "Load other libraries: SUCCESS");
649 //______________________________________________________________________________
650 Bool_t LoadLibrary(const char *module, const char *mode, Bool_t rec=kFALSE)
652 // Load a module library in a given mode. Reports success.
655 TString smodule(module);
656 if (!strcmp(mode, "LOCAL")) imode = 0;
657 if (!strcmp(mode, "PROOF")) imode = 1;
658 if (!strcmp(mode, "GRID")) imode = 2;
661 ::Error("AnalysisTrainHMPID.C::LoadLibrary", "Empty module name");
664 // If a library is specified, just load it
665 if (smodule.EndsWith(".so")) {
666 mod.Remove(mod.Index(".so"));
667 result = gSystem->Load(mod);
669 ::Error("AnalysisTrainHMPID.C::LoadLibrary", "Could not load library %s", module);
672 if (rec) anaLibs += Form("%s.so ",mod.Data());
673 if (rec) anaLibsExtra += Form("%s.so ",mod.Data());
676 // Check if the library is already loaded
677 if (strlen(gSystem->GetLibraries(Form("%s.so", module), "", kFALSE)) > 0)
683 result = SetupPar(module);
684 if (rec) anaPars += Form("%s.par ", module);
686 result = gSystem->Load(Form("lib%s.so", module));
687 if (rec) anaLibs += Form("lib%s.so ", module);
691 if(!gSystem->AccessPathName(module)){
692 ::Info("AnalysisTrainHMPID.C::LoadLibrary", "Removing directory %s",module);
693 gSystem->Exec(Form("rm -rf %s",module));
695 result = gProof->UploadPackage(module);
697 result = gProof->UploadPackage(gSystem->ExpandPathName(Form("$ALICE_ROOT/%s.par", module)));
699 ::Error("AnalysisTrainHMPID.C::LoadLibrary", "Could not find module %s.par in current directory nor in $ALICE_ROOT", module);
703 result = gProof->EnablePackage(module);
709 ::Error("AnalysisTrainHMPID.C::LoadLibrary", "Could not load module %s", module);
715 //______________________________________________________________________________
716 Bool_t LoadSource(const char *source, const char *mode, Bool_t rec=kFALSE)
718 // Load a module library in a given mode. Reports success.
721 if (!strcmp(mode, "LOCAL")) imode = 0;
722 if (!strcmp(mode, "PROOF")) imode = 1;
723 if (!strcmp(mode, "GRID")) imode = 2;
724 TString ssource(source);
725 TString basename = gSystem->BaseName(ssource.Data());
726 if (!ssource.Length()) {
727 ::Error("AnalysisTrainHMPID.C::LoadSource", "Empty task name");
730 // we have a source code so compile it
731 if (ssource.EndsWith(".cxx")) {
732 // need to copy it here other wise the path is also used on grid...
733 ssource.Remove(ssource.Index(".cxx"));
734 basename.Remove(basename.Index(".cxx"));
735 Printf("LoadSources:: Copying... path %s{cxx,h}",ssource.Data());
736 gSystem->Exec(Form("cp %s.cxx . ",ssource.Data()));
737 gSystem->Exec(Form("cp %s.h . ",ssource.Data()));
739 // only needed for local compilation, in grid and proof mode
740 // the task headers are uploaded
741 // path.Remove(path.Index(gSystem->BaseName(path.Data())));
742 // Printf("LoadSources:: Including path %s",path.Data());
743 // if(path.Length()>0)gROOT->ProcessLine(Form(".include %s",path.Data()));
744 Printf("LoadSources:: Loading... path %s",basename.Data());
747 result = gROOT->LoadMacro(Form("%s.cxx++g",basename.Data()));
750 result = gProof->Load(Form("%s.cxx++g",basename.Data()));
753 result = gROOT->LoadMacro(Form("%s.cxx++g",basename.Data()));
755 // what we want to compile
756 anaSources += Form("%s.cxx ",basename.Data());
757 // what we need as input...
758 anaLibs += Form("%s.cxx %s.h ",basename.Data(),basename.Data());
766 ::Error("AnalysisTrainHMPID.C::LoadSources", "Could not load source %s", source);
772 //______________________________________________________________________________
773 TChain *CreateChain(const char *mode, const char *plugin_mode)
775 // Create the input chain
777 if (!strcmp(mode, "LOCAL")) imode = 0;
778 if (!strcmp(mode, "PROOF")) imode = 1;
779 if (!strcmp(mode, "GRID")) imode = 2;
780 TChain *chain = NULL;
785 if (!kLocalXMLDataset.Length()) {
787 chain = new TChain("aodTree");
790 in.open(kLocalDataList.Data());
793 if (line.Length() == 0) continue;
794 // cout << " line = " << line << endl;
795 chain->Add(line.Data());
799 chain = CreateChainSingle(kLocalXMLDataset, "aodTree");
802 if (!kLocalXMLDataset.Length()) {
804 chain = new TChain("esdTree");
807 in.open(kLocalDataList.Data());
810 if (line.Length() == 0) continue;
811 cout << " line = " << line << endl;
812 chain->Add(line.Data());
816 chain = CreateChainSingle(kLocalXMLDataset, "esdTree");
824 AliAnalysisGrid *alienHandler = CreateAlienHandler(plugin_mode);
825 AliAnalysisManager::GetAnalysisManager()->SetGridHandler(alienHandler);
827 TString treeName = "esdTree";
828 if (iAODanalysis) treeName = "aodTree";
829 chain = CreateChainSingle("wn.xml", treeName);
834 if (chain && chain->GetNtrees()) return chain;
838 //______________________________________________________________________________
839 TChain* CreateChainSingle(const char* xmlfile, const char *treeName)
841 printf("*******************************\n");
842 printf("*** Getting the ESD Chain ***\n");
843 printf("*******************************\n");
844 TAlienCollection * myCollection = TAlienCollection::Open(xmlfile);
847 ::Error("AnalysisTrainHMPID.C::CreateChainSingle", "Cannot create an AliEn collection from %s", xmlfile) ;
851 TChain* chain = new TChain(treeName);
852 myCollection->Reset() ;
853 while ( myCollection->Next() ) chain->Add(myCollection->GetTURL("")) ;
858 //______________________________________________________________________________
859 Int_t SetupPar(char* pararchivename)
861 if (!pararchivename || !strlen(pararchivename)) return -1;
862 char processline[1024];
863 if (gSystem->AccessPathName(Form("%s.par", pararchivename))) {
864 if (!gSystem->AccessPathName(Form("%s/%s.par", gSystem->Getenv("ALICE_ROOT"),pararchivename))) {
865 ::Info("AnalysisTrainHMPID.C::SetupPar", "Getting %s.par from $ALICE_ROOT", pararchivename);
866 TFile::Cp(gSystem->ExpandPathName(Form("$ALICE_ROOT/%s.par", pararchivename)),
867 Form("%s.par",pararchivename));
869 ::Error("AnalysisTrainHMPID.C::SetupPar", "Cannot find %s.par", pararchivename);
873 gSystem->Exec(Form("tar xvzf %s.par", pararchivename));
875 TString ocwd = gSystem->WorkingDirectory();
876 if (!gSystem->ChangeDirectory(pararchivename)) return -1;
878 // check for BUILD.sh and execute
879 if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
880 printf("*******************************\n");
881 printf("*** Building PAR archive ***\n");
882 printf("*******************************\n");
883 if (gSystem->Exec("PROOF-INF/BUILD.sh")) {
884 Error("runProcess","Cannot Build the PAR Archive! - Abort!");
889 // check for SETUP.C and execute
890 if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
891 printf("*******************************\n");
892 printf("*** Setup PAR archive ***\n");
893 printf("*******************************\n");
894 gROOT->Macro("PROOF-INF/SETUP.C");
896 if (!gSystem->ChangeDirectory(ocwd.Data())) return -1;
900 //______________________________________________________________________________
901 AliAnalysisAlien* CreateAlienHandler(const char *plugin_mode)
903 // Check if user has a valid token, otherwise make one. This has limitations.
904 // One can always follow the standard procedure of calling alien-token-init then
905 // source /tmp/gclient_env_$UID in the current shell.
906 if (!AliAnalysisGrid::CreateToken()) return NULL;
907 AliAnalysisAlien *plugin = new AliAnalysisAlien();
908 // Set the run mode (can be "full", "test", "offline", "submit" or "terminate")
909 plugin->SetRunMode(plugin_mode);
910 if (kPluginUseProductionMode) plugin->SetProductionMode();
911 plugin->SetJobTag(kJobTag);
912 plugin->SetNtestFiles(1);
913 // plugin->SetPreferedSE("ALICE::NIHAM::File");
914 // Set versions of used packages
915 plugin->SetAPIVersion("V1.1x");
916 plugin->SetROOTVersion(kPluginRootVersion);
917 plugin->SetAliROOTVersion(kPluginAliRootVersion);
919 // Declare input data to be processed.
920 // Method 1: Create automatically XML collections using alien 'find' command.
921 // Define production directory LFN
922 plugin->SetGridDataDir(kGridDatadir.Data());
923 // Set data search pattern
924 if (iAODanalysis) plugin->SetDataPattern(" *AliAOD.root");
925 else plugin->SetDataPattern(Form(" %s/*/*ESDs.root",kGridPassPattern.Data()));
926 // ...then add run numbers to be considered
927 plugin->SetRunPrefix("000"); // if real data
928 plugin->SetRunRange(kGridRunRange[0], kGridRunRange[1]);
930 if(kGridLocalRunList.Length()>0){
932 in1.open(kGridLocalRunList.Data());
934 // just use run numbers, negatives will be excluded
937 Printf("AnalysisTrainHMPID Adding run number from File %s", Form(kGridRunPattern.Data(),iRun));
938 plugin->AddRunNumber(Form(kGridRunPattern.Data(),iRun));
940 Printf("AnalysisTrainHMPID Skipping run number from File %d", iRun);
945 // Method 2: Declare existing data files (raw collections, xml collections, root file)
946 // If no path mentioned data is supposed to be in the work directory (see SetGridWorkingDir())
947 // XML collections added via this method can be combined with the first method if
948 // the content is compatible (using or not tags)
949 // plugin->AddDataFile("Hijing.xml");
950 // plugin->AddDataFile("/alice/data/2008/LHC08c/000057657/raw/Run57657.Merged.RAW.tag.root");
951 // Define alien work directory where all files will be copied. Relative to alien $HOME.
952 TString alien_workdir = "";
954 alien_workdir += kGridWorkDir.Data();
955 if(kGridDataSet.Length()>0)alien_workdir += Form("/%s",kGridDataSet.Data());
956 plugin->SetGridWorkingDir(alien_workdir.Data());
958 // Declare alien output directory. Relative to working directory.
959 if (!kGridOutdir.Length()) kGridOutdir = Form("output_%s",kTrainName.Data());
960 plugin->SetGridOutputDir(kGridOutdir);
962 // Add external packages
964 plugin->AddExternalPackage("boost::v1_43_0");
965 plugin->AddExternalPackage("cgal::v3.6");
966 plugin->AddExternalPackage("fastjet::v2.4.2");
969 // set extra libs before par file compilation
970 anaLibs += kGridExtraFiles;
971 anaLibs = anaLibs.Strip();
972 Printf("anaLibs %s",anaLibs.Data());
973 Printf("anaLibsExtra %s",anaLibsExtra.Data());
975 if (anaLibs.Length()) plugin->SetAdditionalLibs(anaLibs.Data());
976 if (anaLibsExtra.Length()) plugin->SetAdditionalRootLibs(anaLibsExtra.Data());
978 TString ana_sources = "";
979 TString ana_add = "";
980 if (kUsePAR && anaPars.Length()) {
981 printf("%s\n", anaPars.Data());
984 arr = anaPars.Tokenize(" ");
986 while ((objstr=(TObjString*)next())) plugin->EnablePackage(objstr->GetString());
990 // Declare the analysis source files names separated by blancs. To be compiled runtime
991 // using ACLiC on the worker nodes.
992 ana_sources = anaSources.Strip();
993 // Declare all libraries (other than the default ones for the framework. These will be
994 // loaded by the generated analysis macro. Add all extra files (task .cxx/.h) here.
996 if (ana_sources.Length()) plugin->SetAnalysisSource(ana_sources);
997 plugin->SetExecutableCommand(kPluginExecutableCommand.Data());
998 // Declare the output file names separated by blancs.
999 // (can be like: file.root or file.root@ALICE::Niham::File)
1000 plugin->SetUseSubmitPolicy(kFALSE);
1001 plugin->SetMergeExcludes(kGridMergeExclude);
1002 plugin->SetMaxMergeFiles(kGridMaxMergeFiles);
1003 plugin->SetMaxMergeStages(kGridMaxMergeStages);
1004 plugin->SetNrunsPerMaster(kGridRunsPerMaster);
1005 plugin->SetMergeViaJDL(kPluginMergeViaJDL);
1006 // Use fastread option
1007 plugin->SetFastReadOption(kPluginFastReadOption);
1008 // UseOverwrite mode
1009 plugin->SetOverwriteMode(kPluginOverwriteMode);
1010 // Optionally define the files to be archived.
1011 // plugin->SetOutputArchive("log_archive.zip:stdout,stderr@ALICE::NIHAM::File root_archive.zip:AliAOD.root,AOD.tag.root@ALICE::NIHAM::File");
1012 plugin->SetOutputToRunNo(kPluginOutputToRunNumber); // write the output to subdirs named after run number
1013 // plugin->SetDefaultOutputs(kFALSE);
1015 // Put default output files to archive
1016 TString listhists = "";
1017 TString listaods = "";
1018 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1019 TIter next(mgr->GetOutputs());
1020 AliAnalysisDataContainer *output;
1021 while ((output=(AliAnalysisDataContainer*)next())) {
1022 const char *filename = output->GetFileName();
1023 if (!(strcmp(filename, "default"))) {
1024 if (!mgr->GetOutputEventHandler()) continue;
1025 filename = mgr->GetOutputEventHandler()->GetOutputFileName();
1026 if (listaods.Length()) listaods += " ";
1027 listaods += filename;
1029 if(!listhists.Contains(filename)){
1030 if (listhists.Length()) listhists += " ";
1031 listhists += filename;
1036 if (mgr->GetExtraFiles().Length()) {
1037 if (listaods.Length()) listaods += " ";
1038 listaods += mgr->GetExtraFiles();
1041 TString outputArchive;
1042 outputArchive = Form("log_archive.zip:std*r@%s",kGridOutputStorages.Data());
1043 listaods.ReplaceAll(" ", ",");
1044 listhists.ReplaceAll(" ", ",");
1045 if (listhists.Length()) listhists = Form("hist_archive.zip:%s@%s", listhists.Data(), kGridOutputStorages.Data());
1046 if (listaods.Length()) listaods = Form("aod_archive.zip:%s@%s", listaods.Data(), kGridOutputStorages.Data());
1048 if (!listhists.Length() && !listaods.Length()) {
1049 ::Fatal("AnalysisTrainHMPID", "No task output !");
1052 if (listaods.Length()) {
1053 outputArchive += " ";
1054 outputArchive += listaods;
1056 if (listhists.Length()) {
1057 outputArchive += " ";
1058 outputArchive += listhists;
1060 // plugin->SetOutputArchive(outputArchive);
1062 // Optionally set a name for the generated analysis macro (default MyAnalysis.C)
1063 plugin->SetAnalysisMacro(Form("%s.C", kTrainName.Data()));
1064 // Optionally set maximum number of input files/subjob (default 100, put 0 to ignore)
1065 plugin->SetSplitMaxInputFileNumber(kGridFilesPerJob);
1066 // Optionally set number of failed jobs that will trigger killing waiting sub-jobs.
1067 // plugin->SetMaxInitFailed(5);
1068 // Optionally resubmit threshold.
1069 // plugin->SetMasterResubmitThreshold(90);
1070 // Optionally set time to live (default 30000 sec)
1071 plugin->SetTTL(30000);
1072 // Optionally set input format (default xml-single)
1073 plugin->SetInputFormat("xml-single");
1074 // Optionally modify the name of the generated JDL (default analysis.jdl)
1075 plugin->SetJDLName(Form("%s.jdl", kTrainName.Data()));
1076 // Optionally modify the executable name (default analysis.sh)
1077 plugin->SetExecutable(Form("%s.sh", kTrainName.Data()));
1078 // Optionally modify job price (default 1)
1079 plugin->SetPrice(1);
1080 // Optionally modify split mode (default 'se')
1081 plugin->SetSplitMode("se");
1082 plugin->SetCheckCopy(kFALSE);
1086 //______________________________________________________________________________
1087 Bool_t LoadConfig(const char *filename)
1089 // Read train configuration from file
1090 if (gSystem->AccessPathName(filename)) {
1091 ::Error("AnalysisTrainHMPID.C::LoadConfig", "Config file name not found");
1094 gROOT->ProcessLine(Form(".x %s", filename));
1095 ::Info("AnalysisTrainHMPID.C::LoadConfig", "Train configuration loaded from file %s", filename);
1099 //______________________________________________________________________________
1101 Printf(">>> Patching JDL");
1102 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1103 AliAnalysisAlien* gridHandler = (AliAnalysisAlien*)mgr->GetGridHandler();
1104 TGridJDL *jdl = gridHandler->GetGridJDL();
1105 if(iJETAN)jdl->AddToPackages("fastjet","v2.4.0");
1106 gridHandler->WriteJDL(kFALSE);
1107 Printf("<<< Patching JDL");
1111 //______________________________________________________________________________
1112 Bool_t PatchAnalysisMacro(){
1113 Printf(">>> Patching AnalysisMacro");
1114 gSystem->Exec(Form("mv %s.C %s.C_tmp",kTrainName.Data(),kTrainName.Data()));
1117 in1.open(Form("%s.C_tmp", kTrainName.Data()));
1120 while(in1.getline(cLine,250)){
1125 index = st.Index("gSystem->Load(\"libPhysics\");");
1126 index += strlen("gSystem->Load(\"libPhysics\");");
1130 arr = anaLibs.Tokenize(" ");
1133 add += "\n\n // added by CKB \n";
1134 while ((objstr=(TObjString*)next())){
1135 if(objstr->GetString().Contains("PWG3"))continue;
1136 if(objstr->GetString().EndsWith(".so"))add += Form("gSystem->Load(\"%s\");\n",objstr->GetString().Data());
1140 // add += Form("AliLog::SetGlobalLogLevel(%d);\n",AliLog::GetGlobalLogLevel());
1143 if(index<0)Printf("%s:%d index out of bounds",(char*)__FILE__,__LINE__);
1144 add += "\n\n // added by CKB \n";
1145 add += "\n gSystem->AddIncludePath(\"./\"); \n";
1146 if(gGrid && kPluginAliRootVersion.Length()==0){
1147 add += "\n // Dirty hack for TRD reference data \n";
1148 add += "\n gSystem->Setenv(\"ALICE_ROOT\",\"";
1149 add += Form("alien://%s/rootfiles/",gGrid->GetHomeDirectory());
1152 add += "// BKC \n\n";
1153 st.Insert(index,add.Data());
1155 if(kUseCPAR && kPluginAliRootVersion.Length()==0){
1156 index = st.Index("gSystem->AddIncludePath(\"-I$"); // uncommen $ALICE_ROOT include for par files
1157 if(index<0)Printf("%s:%d index out of bounds",(char*)__FILE__,__LINE__);
1158 st.Insert(index,"// CKB comment out whehn no aliroot is provided \n //");
1162 out.open(Form("%s.C", kTrainName.Data()));
1167 Printf("<<< Patching AnalysisMacro");
1169 Printf(">>> Patching Merge Macro");
1170 gSystem->Exec(Form("mv %s_merge.C %s_merge.C_tmp",kTrainName.Data(),kTrainName.Data()));
1173 in2.open(Form("%s_merge.C_tmp", kTrainName.Data()));
1175 while(in2.getline(cLine,250)){
1179 index = st2.Index("gSystem->Load(\"libPhysics\");");
1180 index += strlen("gSystem->Load(\"libPhysics\");");
1182 add2 += "\n gSystem->AddIncludePath(\"./\"); \n";
1183 if(gGrid&&kPluginAliRootVersion.Length()==0){
1184 add2 += "\n // Dirty hack for TRD reference data \n";
1185 add2 += "\n gSystem->Setenv(\"ALICE_ROOT\",\"";
1186 add2 += Form("alien://%s/rootfiles/",gGrid->GetHomeDirectory());
1189 add2 += "// BKC \n\n";
1190 if(index<0)Printf("%s:%d index out of bounds",(char*)__FILE__,__LINE__);
1191 st2.Insert(index,add.Data());
1193 if(kUseCPAR&&kPluginAliRootVersion.Length()==0){
1194 index = st2.Index("gSystem->AddIncludePath(\"-I$"); // uncommen $ALICE_ROOT include for par files
1195 if(index<0)Printf("%s:%d index out of bounds",(char*)__FILE__,__LINE__);
1196 st2.Insert(index,"// CKB comment out whehn no aliroot is provided \n //");
1199 // do not exclude the extra files from merign, this is done explicitly in this train script
1200 index = st2.Index("mergeExcludes +="); // uncommen $ALICE_ROOT include for par files
1201 if(index<0)Printf("%s:%d index out of bounds",(char*)__FILE__,__LINE__);
1202 st2.Insert(index,"// CKB comment out, handled explicitly by the train macro \n //");
1206 out2.open(Form("%s_merge.C", kTrainName.Data()));
1210 out2 << st2 << endl;
1211 Printf("<<< Patching Merging Macro");