Added the possibility to compute multiplicity according to recent ESDcut-based criterion
[u/mrichter/AliRoot.git] / PWG2 / RESONANCES / macros / test / runLocal.C
1 //
2 // This is an example steering macro for running RSN analysis task
3 // locally with a collection of files specified in a text file:
4 //
5 // Inputs:
6 //   - nReadFiles  = number of files to process from the list
7 //   - nSkipFiles  = how many lines to be skipped when reading the list
8 //   - addTaskName = name of the macro to add the RSN analysis task
9 //                   (assumed to have inside it a function named like the file)
10 //   - inputSource = name of the file containing all the inputs
11 //                   ---> to run on a local collection, the collection file 
12 //                        must contain on each line the full path 
13 //                        of one input file and it must have the ".txt" extension
14 //                   ---> to run on an AliEn collection, the collection file must be an XML
15 //                        file collection like those built from the "find -x" method in aliensh.
16 //   - dataLabel   = a label which is used to know what kind of data are being read
17 //                   (it is propagated to the 'addTask' macro for eventual setting up of something
18 //   - outName     = name for the file with RSN package outputs (without ROOT extension)
19 //
20 // Notes:
21 //   - in case the source is an ESD, and if inputs are a MC production
22 //     the MC input handler is created by default
23 // 
24 //
25 // In principle, the user should never modify this macro. 
26 //
27 void runLocal
28 (
29   Int_t       nReadFiles  = 1,
30   Int_t       nSkipFiles  = 0,
31   const char *addTaskName = "AddAnalysisTaskRsnTest.C",
32   const char *inputSource = "test.xml",
33   const char *dataLabel   = "7TeV_pass2_sim_ESD",
34   const char *outName     = "rsn-test"
35 )
36 {
37   
38   // convert the last argument into a BOOL variable
39   TString strDataLabel(dataLabel);
40   Bool_t isESD = strDataLabel.Contains("ESD");
41   Bool_t isAOD = strDataLabel.Contains("AOD");
42   Bool_t isSim = strDataLabel.Contains("sim");   
43   
44   //AliLog::SetGlobalDebugLevel(AliLog::kDebug+1);
45   //AliLog::SetClassDebugLevel("AliRsnCutPID", AliLog::kDebug+2);
46   //AliLog::SetClassDebugLevel("AliRsnPair", AliLog::kDebug+2);
47   //AliLog::SetClassDebugLevel("AliRsnPairFunctions", AliLog::kDebug+2);
48   //AliLog::SetClassDebugLevel("AliRsnValue", AliLog::kDebug+4);
49
50   // check extension of input to distinguish between XML and TXT
51   TString sInput(inputSource);
52   sInput.ToLower();
53   Bool_t isTXT = (!strcmp(sInput(sInput.Length() - 3, 3).Data(), "txt"));
54   cout << "Input = " << (isTXT ? "TXT" : "XML") << endl;
55
56   // load compiled libraries (for aliroot session)
57   gSystem->Load("libANALYSIS.so");
58   gSystem->Load("libANALYSISalice.so");
59   gSystem->Load("libCORRFW.so");
60   gSystem->Load("libPWG2resonances.so");
61   
62   // if input is XML, connect to AliEn
63   if (!isTXT) TGrid::Connect("alien://");
64
65   // create analysis manager
66   AliAnalysisManager *mgr = new AliAnalysisManager("taskRsnTest");
67   mgr->SetCommonFileName(Form("%s.root", outName));
68   
69   // create input handler
70   if (isESD)
71   {
72     AliESDInputHandler *esdHandler = new AliESDInputHandler();
73     mgr->SetInputEventHandler(esdHandler);
74     // if possible, create also MC handler
75     if (isSim)
76     {
77       AliMCEventHandler *mcHandler  = new AliMCEventHandler();
78       mgr->SetMCtruthEventHandler(mcHandler);
79     }
80   }
81   else if (isAOD)
82   {
83     AliAODInputHandler *aodHandler = new AliAODInputHandler();
84     mgr->SetInputEventHandler(aodHandler);
85   }
86   else
87   {
88     ::Error("Required an ESD or AOD input data set");
89     return;
90   }
91   
92   // add event selection for data
93   gROOT->LoadMacro("$(ALICE_ROOT)/ANALYSIS/macros/AddTaskPhysicsSelection.C");
94   AliPhysicsSelectionTask* physSelTask = AddTaskPhysicsSelection(isSim);
95   
96   // split the argument for macros in order to add many tasks
97   TString    sList(addTaskName);
98   TObjArray *list = sList.Tokenize(":");
99   for (Int_t i = 0; i < list->GetEntries(); i++)
100   {
101     TObjString *os  = (TObjString*)list->At(i);
102     TString     str = os->GetString();
103     gROOT->ProcessLine(Form(".x %s(\"%s\")", str.Data(), dataLabel));
104   }
105
106   // create TChain of input events
107   TChain *analysisChain = 0x0;
108   if (isTXT) analysisChain = CreateChainFromText(inputSource, "esdTree", nReadFiles, nSkipFiles);
109   else       analysisChain = CreateChainFromXML (inputSource, "esdTree", nReadFiles, nSkipFiles);
110
111   // start analysis
112   if (!analysisChain)
113   {
114     Error("runLocal", "Analysis chain not properly initialized");
115     return;
116   }
117   mgr->InitAnalysis();
118   mgr->PrintStatus();
119   if (isTXT) mgr->StartAnalysis("local", analysisChain);
120   else       mgr->StartAnalysis("alien", analysisChain);
121 }
122
123 //_________________________________________________________________________________________________
124 Bool_t LoadPars(const char *parList, const char *path)
125 {
126 //
127 // Load PAR libraries locally
128 // ---
129 // Arguments:
130 //  - parList = list of PARs without extension, separated by ':'
131 //  - path    = path where PARs are stored
132 //
133
134   // store position of working directory
135   TString ocwd = gSystem->WorkingDirectory();
136
137   // tokenize list
138   TString     pars(parList);
139   TObjArray  *array = pars.Tokenize(":");
140
141   // loop on list
142   TObjString *ostr;
143   TString     str;
144   Char_t      parName[200], parFile[200];
145   for (Int_t i = 0; i < array->GetEntriesFast(); i++)
146   {
147     ostr = (TObjString*) array->At(i);
148     str = ostr->GetString();
149     sprintf(parName, "%s", str.Data());
150     sprintf(parFile, "%s/%s.par", path, str.Data());
151
152     // check that file exists
153     if (!gSystem->AccessPathName(parFile))
154     {
155       // explode tar-ball and enter it
156       gROOT->ProcessLine(Form(".! tar xzf %s", parFile));
157       gSystem->ChangeDirectory(Form("%s", parName));
158       // checks for BUILD.sh and execute it
159       if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh"))
160       {
161         ::Info("", ">> Building PARs: %s", parName);
162         if (gSystem->Exec("PROOF-INF/BUILD.sh"))
163         {
164           ::Error("LoadPars", Form("BUILD.sh error for '%s'", parFile));
165           gSystem->ChangeDirectory(ocwd);
166           return kFALSE;
167         }
168       }
169       // check and execute SETUP.C
170       if (!gSystem->AccessPathName("PROOF-INF/SETUP.C"))
171       {
172         ::Info("", ">> Setting up PARs: %s", parName);
173         if (gROOT->Macro("PROOF-INF/SETUP.C"))
174         {
175           Error("LoadPars", Form("SETUP.C error for '%s'", parFile));
176           gSystem->ChangeDirectory(ocwd);
177           return kFALSE;
178         }
179       }
180     }
181     else
182     {
183       Error("LoadParsLocal", Form("File '%s' not found", parFile));
184       return kFALSE;
185     }
186   }
187
188   gSystem->ChangeDirectory(ocwd);
189   return kTRUE;
190 }
191
192 //_________________________________________________________________________________________________
193 TChain* CreateChainFromXML
194 (const char *xmlFileName, const char *treeName, Int_t nread, Int_t nskip)
195 {
196 //
197 // Create a TChain with all required files listed into an XML collection.
198 // Necessary to run analysis in AliEn jobs.
199 // ---
200 // Arguments:
201 //  - xmlFileName = input list
202 //  - treeName    = "esdTree" or "aodTree"
203 //  - nread       = how many files to read (0 = all)
204 //  - nskip       = how many files to skip from beginning
205 //
206
207   // if nread argument is 0, it is disabled
208   if (nread == 0) nread = 1000000000;
209
210   // initialize output object
211   TChain *chain = new TChain(treeName);
212
213   // initialize the AliEn collection
214   TAlienCollection *myCollection = TAlienCollection::Open(xmlFileName);
215   if (!myCollection)
216   {
217     Error("CreateChainFromXML", "Cannot create an AliEn collection from %s", xmlFileName);
218     return 0x0;
219   }
220
221   // loop on collection
222   myCollection->Reset();
223   while (myCollection->Next())
224   {
225     // skip until reached required number of offset
226     if (nskip > 0) {--nskip; continue;}
227
228     // stop if required number of read files is reached
229     // otherwise update the counter
230     if (nread <= 0) break;
231     nread--;
232
233     // recovery file and add it
234     Info("CreateChainFromXML", Form("Adding: %s", myCollection->GetTURL("")));
235     chain->Add(myCollection->GetTURL(""));
236   }
237
238   return chain;
239 }
240
241 //_________________________________________________________________________________________________
242 TChain* CreateChainFromText(const char *fileName, const char *treeName, Int_t nread, Int_t nskip)
243 {
244 //
245 // Create a TChain with all required files listed into a text file.
246 // Necessary to run analysis in local jobs.
247 // ---
248 // Arguments:
249 //  - xmlFileName = input file list
250 //  - treeName    = "esdTree" or "aodTree"
251 //  - nread       = how many files to read (0 = all)
252 //  - nskip       = how many files to skip from beginning
253 //
254
255   // if third argument is 0, it is interpreted
256   // as "read all lines"
257   Bool_t readAll = (nread <= 0);
258   
259   // initialize output object
260   TChain* target = new TChain(treeName);
261   
262   // open text file
263   ifstream fileIn(fileName);
264   
265   // loop on collection
266   TString line;
267   while (fileIn.good())
268   {
269     fileIn >> line;
270     if (line.IsNull()) continue;
271     
272     // skip until reached required number of offset
273     if (nskip > 0) {--nskip; continue;}
274     
275     // stop if required number of read files is reached
276     // otherwise update the counter
277     if (!readAll && nread <= 0) break;
278     nread--;
279     
280     // add file
281     Info("CreateChainFromText", "Adding '%s'", line.Data());
282     target->Add(line.Data());
283   }
284   
285   return target;
286 }