]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/CreateWeightedRejectList.C
add calculation and histograms for MC cross section
[u/mrichter/AliRoot.git] / MUON / CreateWeightedRejectList.C
CommitLineData
f0938a5b 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16// $Id$
17
18///
19/// \ingroup macros
20///
21/// \file CreateWeightedRejectList.C
22///
23/// \brief Macro test for the creation of a RejectList object (for simulations) in the OCDB, for the MUON Tracke
24///
25/// Usage:
26///
27/// root[0] .L CreateWeightedRejectList.C+
28/// root[1] CreateWeightedRejectList("runlist.txt","local://$HOME/myLocalOCDB");
29///
30/// where runlist.txt has 2 integers per line = "run nevents"
31/// where nevents is the number of events where there's (for instance) a CMUS1B trigger
32///
951dd287 33///
34/// Assuming the file coming from the Export feature of the logbook is runlist.logbook.txt =>
35///
36/// 115521;PHYSICS_1;1357;0.9
37/// 115516;PHYSICS_1;944;0.9
38///
39/// The awk command below will output the needed format for this macro :
40///
41/// awk '{split ($0,a,";"); print a[1] " " a[3];}' runlist.logbook.txt =>
42///
43/// 115521 1357
44/// 115516 944
45///
f0938a5b 46/// \author Matthieu Lenhardt, Subatech
47///
48
49#include "AliCDBEntry.h"
50#include "AliCDBManager.h"
51#include "AliDAQ.h"
52#include "AliDCSValue.h"
53#include "AliMUONCDB.h"
54#include "AliMUONCalibParamNI.h"
55#include "AliMUONCalibrationData.h"
56#include "AliMUONPadStatusMaker.h"
57#include "AliMUONPadStatusMapMaker.h"
58#include "AliMUONRecoParam.h"
59#include "AliMUONRejectList.h"
60#include "AliMUONRejectList.h"
61#include "AliMUONTrackerData.h"
62#include "AliMUONVCalibParam.h"
63#include "AliMpBusPatch.h"
64#include "AliMpCDB.h"
65#include "AliMpConstants.h"
66#include "AliMpDCSNamer.h"
67#include "AliMpDDLStore.h"
68#include "AliMpDEIterator.h"
69#include "AliMpDEManager.h"
70#include "AliMpDetElement.h"
71#include "AliSysInfo.h"
72#include "TEnv.h"
73#include <Riostream.h>
74#include <TFile.h>
75#include <TGrid.h>
76#include <TMap.h>
77#include <TObjArray.h>
78#include <TObject.h>
79#include <TTree.h>
80#include <vector>
f07b5e4a 81#include "AliCounterCollection.h"
82
83#include "AliMUONTrackerDataWrapper.h"
84#include "AliMUONPainterDataRegistry.h"
f0938a5b 85
86class RunInfo
87{
88public:
89 RunInfo(Int_t run, Long64_t nevents) : fNumber(run), fNevents(nevents) { }
90
91 Int_t Number() const { return fNumber; }
92
93 Long64_t Nevents() const { return fNevents; }
94
95 void SetNevents(Long64_t n) { fNevents = n; }
96
97private:
98 Int_t fNumber;
99 Long64_t fNevents;
100};
101
102std::ostream& operator<<(std::ostream& out, const RunInfo& run)
103{
f07b5e4a 104 out << Form("RUN %09d NEVENTS %lld",run.Number(),run.Nevents());
f0938a5b 105 return out;
106}
107
108AliMUONRejectList* CheckDE_BP_ManuPedestals(Int_t rejectMask, AliMUONPadStatusMaker& status);
109
f07b5e4a 110Int_t AddEventsSingleRun(Int_t run_number, Long64_t nEvents,AliMUONRejectList& rejectedEvents);
f0938a5b 111
112std::vector<RunInfo> runs;
113
f07b5e4a 114//______________________________________________________________________________
115AliMUONRejectList* CreateWeightedRejectList(AliCounterCollection& cc,
116 const char* ocdbPath="local:///Users/laurent/Alice/OCDBcopy2013",
117 const char* weigthWithTrigger="CMSL7-B-NOPF-MUON")
118{
119 // create the reject using the runs in the collection
120 //
121 // the counter collection is expected to have "trigger","event","run" rubrics
122 // and event:PSALL should be a valid one.
123 //
124
125 if (!gGrid)
126 {
127 TGrid::Connect("alien://");
128 }
129
130 AliCDBManager::Instance()->SetDefaultStorage(ocdbPath);
131
132 AliMUONRejectList* weightedRejectList = new AliMUONRejectList;
133
134 AliMUONRejectList rejectedEvents;
135
136 TString sruns = cc.GetKeyWords("run");
137 TObjArray* truns = sruns.Tokenize(",");
138
139 TIter next(truns);
140 TObjString* s;
141
142 Double_t nEventsTotal(0.0);
143
144 while ( ( s = static_cast<TObjString*>(next())) )
145 {
146 Int_t runNumber = s->String().Atoi();
147 AliSysInfo::Instance()->AddStamp(Form("RUN%d",runNumber));
148 Long64_t nEvents = cc.GetSum(Form("trigger:%s/event:PSALL/run:%d",weigthWithTrigger,runNumber));
149 if (!nEvents)
150 {
151 std::cout << "No events for run " << runNumber << " ??" << std::endl;
152 continue;
153 }
154 nEventsTotal += AddEventsSingleRun(runNumber,nEvents,rejectedEvents);
155 }
156
157 delete truns;
158
159 AliMpDEIterator DEiter;
160
161 for (DEiter.First(); !DEiter.IsDone(); DEiter.Next())
162 if (DEiter.CurrentDEId() < 1100)
163 {
164 Int_t DEid = DEiter.CurrentDEId();
165
166 Double_t nBadEventsDE = rejectedEvents.DetectionElementProbability(DEid);
167 Double_t nEventsTotalDE = static_cast<Double_t>(nEventsTotal);
168 Float_t probaDE = 0.0;
169 if (nEventsTotalDE != 0.0)
170 probaDE = nBadEventsDE / nEventsTotalDE;
171 weightedRejectList->SetDetectionElementProbability(DEid, probaDE);
172
173 Int_t nBusPatches = DEiter.CurrentDE()->GetNofBusPatches();
174 for (Int_t ii = 0; ii < nBusPatches; ii++)
175 {
176 Int_t BPid = DEiter.CurrentDE()->GetBusPatchId(ii);
177
178 Double_t nBadEventsBP = rejectedEvents.BusPatchProbability(BPid);
179 Double_t nEventsTotalBP = nEventsTotalDE - nBadEventsDE;
180 Float_t probaBP = 0.0;
181 if (nEventsTotalBP != 0.0)
182 probaBP = nBadEventsBP / nEventsTotalBP;
183 weightedRejectList->SetBusPatchProbability(BPid, probaBP);
184
185 Int_t nManus = AliMpDDLStore::Instance(kFALSE)->GetBusPatch(BPid, kFALSE)->GetNofManus();
186 for (Int_t jj = 0; jj < nManus; jj++)
187 {
188 Int_t manuId = AliMpDDLStore::Instance(kFALSE)->GetBusPatch(BPid, kFALSE)->GetManuId(jj);
189
190 Double_t nBadEventsManu = rejectedEvents.ManuProbability(DEid, manuId);
191 Double_t nEventsTotalManu = nEventsTotalBP - nBadEventsBP;
192 Float_t probaManu = 0.0;
193 if (nEventsTotalManu != 0.0)
194 probaManu = nBadEventsManu / nEventsTotalManu;
195 weightedRejectList->SetManuProbability(DEid, manuId, probaManu);
196
197 for (Int_t channel = 0; channel < AliMpConstants::ManuNofChannels(); channel++)
198 {
199 Double_t nBadEventsChannel = rejectedEvents.ChannelProbability(DEid, manuId, channel);
200 Double_t nEventsTotalChannel = nEventsTotalManu - nBadEventsManu;
201 Float_t probaChannel = 0.0;
202 if (nEventsTotalChannel != 0.0)
203 {
204 probaChannel = nBadEventsChannel / nEventsTotalChannel;
205 }
206
207 weightedRejectList->SetChannelProbability(DEid, manuId, channel, probaChannel);
208 }
209 }
210 }
211 }
212
213
214 AliMUONTrackerData* td = new AliMUONTrackerData("WeightedRejectList","RejectList",*weightedRejectList);
215
216 AliMUONVTrackerDataMaker* dw = new AliMUONTrackerDataWrapper(td);
217
218 AliMUONPainterDataRegistry::Instance()->Register(dw);
219
220 return weightedRejectList;
221}
222
f0938a5b 223//______________________________________________________________________________
224bool CreateWeightedRejectList(const char* runlistfile="runlist.txt",
f07b5e4a 225 const char* rejectListPath="local://$HOME/OCDB",
226 const char* author="Matthieu Lenhardt")
f0938a5b 227{
228 /// Create a weighted RejectList for the runs included in the run list
229 /// The cuts are the same that the one applied in the RecoParam used to create the ESDs.
230 ///
231 /// \param runlistfile : an ASCII file where each line is a pair "run nevents"
232 /// \param rejectListPath : set this to the folder where the RejectList will be created (must have right access to it, of course)
233
234 TGrid::Connect("alien://");
235
236 ifstream in(runlistfile);
237 int run, nevents;
238
239 while ( in >> run >> nevents )
240 {
241 runs.push_back(RunInfo(run,nevents));
242 };
243
244 for ( std::vector<RunInfo>::size_type i = 0; i < runs.size(); ++i )
245 {
246 cout << runs[i] << endl;
247 }
248
249 if (runs.empty()) return false;
250
251 Int_t firstRun = runs[0].Number();
252 Int_t lastRun = runs[runs.size()-1].Number();
253
254 const char* rawOCDB = "raw://";
255
256 AliCDBManager* manager = AliCDBManager::Instance();
257
258 manager->SetCacheFlag(kFALSE);
259
260 manager->SetDefaultStorage(rawOCDB);
261
262 manager->SetSpecificStorage("MUON/Calib/RejectList", rejectListPath);
263
264 AliMUONRejectList weightedRejectList;
265 AliMUONRejectList rejectedEvents;
266
267 Long64_t nEventsTotal = 0;
268
269 for (std::vector<RunInfo>::size_type ii = 0; ii < runs.size(); ++ii)
270 {
271 Int_t runNumber = runs[ii].Number();
272 AliSysInfo::Instance()->AddStamp(Form("RUN%d",runNumber));
f07b5e4a 273 Long64_t nEvents = runs[ii].Nevents();
274 nEventsTotal += AddEventsSingleRun(runNumber, nEvents, rejectedEvents);
f0938a5b 275 }
276
277 AliMpDEIterator DEiter;
278
279 for (DEiter.First(); !DEiter.IsDone(); DEiter.Next())
280 if (DEiter.CurrentDEId() < 1100)
281 {
282 Int_t DEid = DEiter.CurrentDEId();
283
284 Double_t nBadEventsDE = rejectedEvents.DetectionElementProbability(DEid);
285 Double_t nEventsTotalDE = static_cast<Double_t>(nEventsTotal);
286 Float_t probaDE = 0.0;
287 if (nEventsTotalDE != 0.0)
288 probaDE = nBadEventsDE / nEventsTotalDE;
289 weightedRejectList.SetDetectionElementProbability(DEid, probaDE);
290
291 Int_t nBusPatches = DEiter.CurrentDE()->GetNofBusPatches();
292 for (Int_t ii = 0; ii < nBusPatches; ii++)
293 {
294 Int_t BPid = DEiter.CurrentDE()->GetBusPatchId(ii);
295
296 Double_t nBadEventsBP = rejectedEvents.BusPatchProbability(BPid);
297 Double_t nEventsTotalBP = nEventsTotalDE - nBadEventsDE;
298 Float_t probaBP = 0.0;
299 if (nEventsTotalBP != 0.0)
300 probaBP = nBadEventsBP / nEventsTotalBP;
301 weightedRejectList.SetBusPatchProbability(BPid, probaBP);
302
303 Int_t nManus = AliMpDDLStore::Instance(kFALSE)->GetBusPatch(BPid, kFALSE)->GetNofManus();
304 for (Int_t jj = 0; jj < nManus; jj++)
305 {
306 Int_t manuId = AliMpDDLStore::Instance(kFALSE)->GetBusPatch(BPid, kFALSE)->GetManuId(jj);
307
308 Double_t nBadEventsManu = rejectedEvents.ManuProbability(DEid, manuId);
309 Double_t nEventsTotalManu = nEventsTotalBP - nBadEventsBP;
310 Float_t probaManu = 0.0;
311 if (nEventsTotalManu != 0.0)
312 probaManu = nBadEventsManu / nEventsTotalManu;
313 weightedRejectList.SetManuProbability(DEid, manuId, probaManu);
314
315 for (Int_t channel = 0; channel < AliMpConstants::ManuNofChannels(); channel++)
316 {
317 Double_t nBadEventsChannel = rejectedEvents.ChannelProbability(DEid, manuId, channel);
318 Double_t nEventsTotalChannel = nEventsTotalManu - nBadEventsManu;
319 Float_t probaChannel = 0.0;
320 if (nEventsTotalChannel != 0.0)
321 {
322 probaChannel = nBadEventsChannel / nEventsTotalChannel;
323 }
324
325 weightedRejectList.SetChannelProbability(DEid, manuId, channel, probaChannel);
326 }
327 }
328 }
329 }
330
331
332 AliMUONCDB::WriteToCDB(&weightedRejectList, "MUON/Calib/RejectList",
333 firstRun , lastRun,
334 "Weighted reject List for MCH, for simulations only",
f07b5e4a 335 author);
f0938a5b 336
337 return true;
338}
339
340//____________________________________________________________________________________________
341AliMUONRejectList* CheckDE_BP_ManuPedestals(Int_t rejectMask, AliMUONPadStatusMaker& status)
342{
343 AliMUONRejectList* nBadChannels = new AliMUONRejectList;
344
345 AliMpDEIterator DEiter;
346 for (DEiter.First(); !DEiter.IsDone(); DEiter.Next())
347 if (DEiter.CurrentDEId() < 1100)
348 {
349 Int_t DEid = DEiter.CurrentDEId();
350 Int_t nBusPatches = DEiter.CurrentDE()->GetNofBusPatches();
351 for (Int_t ii = 0; ii < nBusPatches; ii++)
352 {
353 Int_t BPid = DEiter.CurrentDE()->GetBusPatchId(ii);
354
355 Int_t nManus = AliMpDDLStore::Instance(kFALSE)->GetBusPatch(BPid, kFALSE)->GetNofManus();
356 for (Int_t jj = 0; jj < nManus; jj++)
357 {
358 Int_t manuId = AliMpDDLStore::Instance(kFALSE)->GetBusPatch(BPid, kFALSE)->GetManuId(jj);
359
360 Int_t nChannels = DEiter.CurrentDE()->NofChannelsInManu(manuId);
361 for (Int_t channel = 0; channel < nChannels; channel++)
362 {
363 Int_t padStatus = status.PadStatus(DEid, manuId, channel);
364 if ((rejectMask == 0 && padStatus != 0) || (padStatus & rejectMask) != 0)
365 {
366 nBadChannels->SetDetectionElementProbability(DEid, nBadChannels->DetectionElementProbability(DEid) + 1.0);
367 nBadChannels->SetBusPatchProbability(BPid, nBadChannels->BusPatchProbability(BPid) + 1.0);
368 nBadChannels->SetManuProbability(DEid, manuId, nBadChannels->ManuProbability(DEid, manuId) + 1.0);
369 nBadChannels->SetChannelProbability(DEid, manuId, channel, 1.0);
370 }
371 }
372 }
373 }
374 }
375
376 return nBadChannels;
377}
378
379
380//____________________________________________________________________________________________
f07b5e4a 381Int_t AddEventsSingleRun(Int_t runNumber, Long64_t nEvents, AliMUONRejectList& rejectedEvents)
f0938a5b 382{
383 AliCDBManager::Instance()->SetRun(runNumber);
384
385 AliMpCDB::LoadAll();
386
387 Double_t maxBadChannels = 80.0;
388
389 AliMUONRecoParam *recoParam = AliMUONCDB::LoadRecoParam();
390 AliMUONCalibrationData calibrationData(runNumber);
391 AliMUONPadStatusMaker status(calibrationData);
392
beffc4d5 393 status.SetLimits(*recoParam);
394
f0938a5b 395 Int_t rejectMask = recoParam->PadGoodnessMask();
396
397 // Functions to compute the number of bad channels at the DE, BP and Manu level
398 AliMUONRejectList* nBadChannels = CheckDE_BP_ManuPedestals(rejectMask, status);
399
400 AliMpDEIterator DEiter;
401 for (DEiter.First(); !DEiter.IsDone(); DEiter.Next())
402 if (DEiter.CurrentDEId() < 1100)
403 {
404 Int_t DEid = DEiter.CurrentDEId();
405 Int_t nBusPatches = DEiter.CurrentDE()->GetNofBusPatches();
406
407 Double_t nChannelsDE = static_cast<Double_t>(AliMpDDLStore::Instance(kFALSE)->GetDetElement(DEid)->NofChannels());
408 Double_t nBadChannelsDE = nBadChannels->DetectionElementProbability(DEid);
409 Double_t ratioBadChannelsDE = 0.0;
410 if (nChannelsDE != 0.0)
411 ratioBadChannelsDE = 100.0 * nBadChannelsDE / nChannelsDE;
412
413
414 Bool_t goodDE = kTRUE;
415 if (ratioBadChannelsDE >= maxBadChannels)
416 {
417 Double_t newRejectedEventsDE = rejectedEvents.DetectionElementProbability(DEid) + static_cast<Double_t>(nEvents);
418 rejectedEvents.SetDetectionElementProbability(DEid, newRejectedEventsDE);
419 goodDE = kFALSE;
420 }
421
422 if (goodDE)
423 for (Int_t ii = 0; ii < nBusPatches; ii++)
424 {
425 Int_t BPid = DEiter.CurrentDE()->GetBusPatchId(ii);
426 Int_t nManus = AliMpDDLStore::Instance(kFALSE)->GetBusPatch(BPid, kFALSE)->GetNofManus();
427
428 Double_t nChannelsBP = static_cast<Double_t>(nManus * AliMpConstants::ManuNofChannels());
429 Double_t nBadChannelsBP = nBadChannels->BusPatchProbability(BPid);
430 Double_t ratioBadChannelsBP = 100.0 * nBadChannelsBP / nChannelsBP;
431
432 Bool_t goodBP = kTRUE;
433
434 if (goodBP)
435 if (ratioBadChannelsBP >= maxBadChannels)
436 {
437 Double_t newRejectedEventsBP = rejectedEvents.BusPatchProbability(BPid) + static_cast<Double_t>(nEvents);
438 rejectedEvents.SetBusPatchProbability(BPid, newRejectedEventsBP);
439 goodBP = kFALSE;
440 }
441
442 if (goodBP)
443 for (Int_t jj = 0; jj < nManus; jj++)
444 {
445 Int_t manuId = AliMpDDLStore::Instance(kFALSE)->GetBusPatch(BPid, kFALSE)->GetManuId(jj);
446
447 Double_t nChannelsManu = DEiter.CurrentDE()->NofChannelsInManu(manuId);;
448 Double_t nBadChannelsManu = nBadChannels->ManuProbability(DEid, manuId);
449 Double_t ratioBadChannelsManu = 100.0 * nBadChannelsManu / nChannelsManu;
450
451 Bool_t goodManu = kTRUE;
452
453 if (ratioBadChannelsManu >= maxBadChannels)
454 {
455 Double_t newRejectedEventsManu = rejectedEvents.ManuProbability(DEid, manuId) + static_cast<Double_t>(nEvents);
456 rejectedEvents.SetManuProbability(DEid, manuId, newRejectedEventsManu);
457 goodManu = kFALSE;
458 }
459
460
461 Int_t nChannels = DEiter.CurrentDE()->NofChannelsInManu(manuId);
462
463 if (goodManu)
464 for (Int_t channel = 0; channel < nChannels; channel++)
465 if (nBadChannels->ChannelProbability(DEid, manuId, channel) > 0.0)
466 {
467 Double_t newRejectedEventsChannel = rejectedEvents.ChannelProbability(DEid, manuId, channel) + static_cast<Double_t>(nEvents);
468 rejectedEvents.SetChannelProbability(DEid, manuId, channel, newRejectedEventsChannel);
469 } // end of Channels loop
470 } // end of MANUs loop
471 } // end of BPs loop
472 } // end of DEs loop
473
474 delete nBadChannels;
475
476 return nEvents;
477}
478
479//______________________________________________________________________________
480//
481//
482// The code below might be used someday to retrieve the number of events
483// with at least one muon directly from a runlist, instead of requiring
484// as input both the run numbers and the number of events.
485//
486// This approach though is not without its problems :
487//
488// - even if we are using tags, as the tags are chunk-based (for the moment at
489// least), it's pretty slow to loop on all the chunks (it is becoming usual
490// to get runs with some 600 chunks or so...)
491// - if part of a run is not reconstructed (for whatever reason) with the pass
492// we use to compute the number of events with at least one muon, we might
493// underestimate its weight in the final rejectlist for the next passes (
494// if for the next passes the full run is correctly reconstructed for instance)
495// - a muon in the tag = either a trigger track or a tracker track, i.e. we don't
496// know for sure it's a good track...
497//
498// Given all those reasons, we for the moment use a dumb approach :
499//
500// - go to alice-logbook.cern.ch . Select the runs you want and the trigger class
501// you want (most probably CMUS1B), and export the list as (run,nevents)
502// - run this macro with this (run,nevents) list
503//
504//______________________________________________________________________________
505
506#if 0
507
508#include "TChain.h"
509#include "AliDetectorTagCuts.h"
510#include "AliEventTagCuts.h"
511#include "AliLHCTagCuts.h"
512#include "AliRunTagCuts.h"
513#include "AliTagAnalysis.h"
514#include "TGridResult.h"
515
516//______________________________________________________________________________
517bool CreateXMLCollectionFromRunList(const char* collectionName,
518 const char* runlist,
519 const char* type,
520 int passNumber)
521{
522 /// From a list of run, create a collection with only events containing at least one muon
523 /// \param collectionName : output name of the collection (without extension, which will be .xml)
524 /// \param runlist : text file containing one integer per line = one run number per line
525 /// \param type : files to consider, either ESD or AD
526 /// \param passNumber : 1 or 2 most probably (to distinguish which reco pass is used)
527
528 if (!gGrid) TGrid::Connect("alien://");
529 if (!gGrid)
530 {
531 return 0x0;
532 }
533
f0938a5b 534 TString stype(type);
535 stype.ToUpper();
536
537 if ( stype != "ESD" && stype != "AOD" )
538 {
539 cout << "Only ESD or AOD type supported" << endl;
540 return false;
541 }
542
543 ifstream in(gSystem->ExpandPathName(runlist));
544 Int_t runNumber;
545 Int_t ntagfiles(0);
546
547 AliTagAnalysis tagAnalysis("ESD");
548
549 while ( in >> runNumber )
550 {
551 TGridResult *res = gGrid->Query("/alice/data",
552 Form("%09d/%ss/pass%d/*%d*/Run%d.Event*.ESD.tag.root",
553 runNumber,stype.Data(),passNumber,runNumber,runNumber));
554 Int_t nFiles = res->GetEntries();
555 if (!nFiles)
556 {
557 continue;
558 }
559
560 for (Int_t i = 0; i < nFiles; ++i)
561 {
562 TString filename = res->GetKey(i, "turl");
563 if(filename == "") continue;
564 tagAnalysis.AddTagsFile(filename.Data(),kFALSE);
565 ++ntagfiles;
566 }
567 delete res;
568 }
569
570 cout << ntagfiles << " tag files added" << endl;
571
572 AliRunTagCuts runCuts;
573 AliEventTagCuts eventCuts;
574 AliLHCTagCuts lhcCuts;
575 AliDetectorTagCuts detCuts;
576
577 eventCuts.SetNMuonRange(1,99999);
578
579 return tagAnalysis.CreateXMLCollection(collectionName,&runCuts,&lhcCuts,&detCuts,&eventCuts);
580
581}
582
583//______________________________________________________________________________
584TChain* CreateChainFromXMLCollection(const char* collectionName, const char* type)
585{
586 /// Create a chain from an XML collection file.
587
588 if (!gGrid) TGrid::Connect("alien://");
589 if (!gGrid)
590 {
591 return 0x0;
592 }
593
594 TString stype(type);
595 stype.ToUpper();
596
597 if ( stype != "ESD" && stype != "AOD" )
598 {
599 cout << "Only ESD or AOD type supported" << endl;
600 return 0x0;
601 }
602
603 AliTagAnalysis tagAnalysis(stype.Data());
604
605 return tagAnalysis.CreateChainFromCollection(collectionName,stype=="ESD" ? "esdTree":"aodTree");
606}
607
608#endif