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