]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG/muon/AliVAnalysisMuon.cxx
Use only one function to set the trigger classes: patterns and trigger combinations...
[u/mrichter/AliRoot.git] / PWG / muon / AliVAnalysisMuon.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2007, 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: AliVAnalysisMuon.cxx 47782 2011-02-24 18:37:31Z martinez $ */
17
18 //-----------------------------------------------------------------------------
19 /// \class AliVAnalysisMuon
20 /// Base class with utilities for muon analysis
21 ///
22 /// \author Diego Stocco
23 //-----------------------------------------------------------------------------
24
25 #include "AliVAnalysisMuon.h"
26
27 // ROOT includes
28 #include "TROOT.h"
29 #include "TH1.h"
30 #include "TH2.h"
31 #include "TAxis.h"
32 #include "TCanvas.h"
33 #include "TLegend.h"
34 #include "TMath.h"
35 #include "TObjString.h"
36 #include "TObjArray.h"
37 #include "THashList.h"
38 #include "TStyle.h"
39 //#include "TMCProcess.h"
40 #include "TLorentzVector.h"
41 #include "TRegexp.h"
42
43 // STEER includes
44 #include "AliInputEventHandler.h"
45 #include "AliCentrality.h"
46
47 #include "AliAODEvent.h"
48 #include "AliAODTrack.h"
49 #include "AliAODMCParticle.h"
50 #include "AliMCEvent.h"
51 #include "AliMCParticle.h"
52 //#include "AliStack.h"
53 #include "AliESDEvent.h"
54 #include "AliESDMuonTrack.h"
55 #include "AliCounterCollection.h"
56 #include "AliVVertex.h"
57
58 // ANALYSIS includes
59 #include "AliAnalysisManager.h"
60 #include "AliAnalysisTaskSE.h"
61 #include "AliAnalysisDataSlot.h"
62 #include "AliAnalysisDataContainer.h"
63
64 // CORRFW includes
65 #include "AliCFGridSparse.h"
66
67 // PWG3 includes
68 #include "AliMergeableCollection.h"
69 #include "AliMuonEventCuts.h"
70 #include "AliMuonTrackCuts.h"
71 #include "AliMuonPairCuts.h"
72 #include "AliAnalysisMuonUtility.h"
73
74 /// \cond CLASSIMP
75 ClassImp(AliVAnalysisMuon) // Class implementation in ROOT context
76 /// \endcond
77
78
79 //________________________________________________________________________
80 AliVAnalysisMuon::AliVAnalysisMuon() :
81   AliAnalysisTaskSE(),
82   fMuonEventCuts(0x0),
83   fMuonTrackCuts(0x0),
84   fMuonPairCuts(0x0),
85   fESDEvent(0x0),
86   fAODEvent(0x0),
87   fTerminateOptions(0x0),
88   fChargeKeys(0x0),
89   fSrcKeys(0x0),
90   fPhysSelKeys(0x0),
91   fWeights(0x0),
92   fEventCounters(0x0),
93   fMergeableCollection(0x0),
94   fOutputList(0x0),
95   fOutputPrototypeList(0x0)
96 {
97   /// Default ctor.
98 }
99
100 //________________________________________________________________________
101 AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonTrackCuts& trackCuts, const AliMuonPairCuts& pairCuts) :
102   AliAnalysisTaskSE(name),
103   fMuonEventCuts(new AliMuonEventCuts("stdEventCuts","stdEventCuts")),
104   fMuonTrackCuts(new AliMuonTrackCuts(trackCuts)),
105   fMuonPairCuts(new AliMuonPairCuts(pairCuts)),
106   fESDEvent(0x0),
107   fAODEvent(0x0),
108   fTerminateOptions(0x0),
109   fChargeKeys(0x0),
110   fSrcKeys(0x0),
111   fPhysSelKeys(0x0),
112   fWeights(new THashList()),
113   fEventCounters(0x0),
114   fMergeableCollection(0x0),
115   fOutputList(0x0),
116   fOutputPrototypeList(0x0)
117 {
118   //
119   /// Constructor.
120   //
121   
122   InitKeys();
123   SetTrigClassPatterns("");
124   SetCentralityClasses();
125   fWeights->SetOwner();
126
127   DefineOutput(1, TObjArray::Class());
128 }
129
130 //________________________________________________________________________
131 AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonTrackCuts& trackCuts) :
132   AliAnalysisTaskSE(name),
133   fMuonEventCuts(new AliMuonEventCuts("stdEventCuts","stdEventCuts")),
134   fMuonTrackCuts(new AliMuonTrackCuts(trackCuts)),
135   fMuonPairCuts(0x0),
136   fESDEvent(0x0),
137   fAODEvent(0x0),
138   fTerminateOptions(0x0),
139   fChargeKeys(0x0),
140   fSrcKeys(0x0),
141   fPhysSelKeys(0x0),
142   fWeights(new THashList()),
143   fEventCounters(0x0),
144   fMergeableCollection(0x0),
145   fOutputList(0x0),
146   fOutputPrototypeList(0x0)
147 {
148   //
149   /// Constructor.
150   //
151   
152   InitKeys();
153   SetTrigClassPatterns("");
154   SetCentralityClasses();
155   fWeights->SetOwner();
156   
157   DefineOutput(1, TObjArray::Class());
158 }
159
160
161 //________________________________________________________________________
162 AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonPairCuts& pairCuts) :
163   AliAnalysisTaskSE(name),
164   fMuonEventCuts(new AliMuonEventCuts("stdEventCuts","stdEventCuts")),
165   fMuonTrackCuts(0x0),
166   fMuonPairCuts(new AliMuonPairCuts(pairCuts)),
167   fESDEvent(0x0),
168   fAODEvent(0x0),
169   fTerminateOptions(0x0),
170   fChargeKeys(0x0),
171   fSrcKeys(0x0),
172   fPhysSelKeys(0x0),
173   fWeights(new THashList()),
174   fEventCounters(0x0),
175   fMergeableCollection(0x0),
176   fOutputList(0x0),
177   fOutputPrototypeList(0x0)
178 {
179   //
180   /// Constructor.
181   //
182   InitKeys();
183   SetTrigClassPatterns("");
184   SetCentralityClasses();
185   fWeights->SetOwner();
186     
187   DefineOutput(1, TObjArray::Class());
188 }
189
190
191 //________________________________________________________________________
192 AliVAnalysisMuon::~AliVAnalysisMuon()
193 {
194   //
195   /// Destructor
196   //
197
198   delete fMuonEventCuts;
199   delete fMuonTrackCuts;
200   delete fMuonPairCuts;
201   delete fTerminateOptions;
202   delete fChargeKeys;
203   delete fSrcKeys;
204   delete fPhysSelKeys;
205   delete fWeights;
206   delete fOutputPrototypeList;
207
208
209   // For proof: do not delete output containers
210   if ( ! AliAnalysisManager::GetAnalysisManager() || ! AliAnalysisManager::GetAnalysisManager()->IsProofMode() ) {
211     delete fOutputList;
212   }
213 }
214
215 //___________________________________________________________________________
216 void AliVAnalysisMuon::FinishTaskOutput()
217 {
218   //
219   /// Remove empty histograms to reduce the number of histos to be merged
220   //
221
222
223   fMergeableCollection->PruneEmptyObjects();
224   
225   // Add stat. info from physics selection
226   // (usefull when running on AODs)
227   if ( fInputHandler ) {
228     for ( Int_t istat=0; istat<2; istat++ ) {
229       TString statType = ( istat == 0 ) ? "ALL" : "BIN0";
230       TH2* hStat = dynamic_cast<TH2*>(fInputHandler->GetStatistics(statType.Data()));
231       if ( hStat ) {
232         TString objectName = Form("%s_%s", hStat->GetName(), GetName());
233         TH2* cloneStat = static_cast<TH2*>(hStat->Clone(objectName.Data()));
234         cloneStat->SetDirectory(0);
235         fOutputList->Add(cloneStat);
236       }
237       else {
238         AliWarning("Stat histogram not available");
239         break;
240       }
241     } // loop on stat type
242   }
243 }
244
245
246 //___________________________________________________________________________
247 void AliVAnalysisMuon::NotifyRun()
248 {
249   /// Set run number for cuts
250   if ( fMuonTrackCuts ) fMuonTrackCuts->SetRun(fInputHandler);
251   if ( fMuonPairCuts ) fMuonPairCuts->SetRun(fInputHandler);
252 }
253
254 //___________________________________________________________________________
255 void AliVAnalysisMuon::UserCreateOutputObjects() 
256 {
257   //
258   /// Create output objects
259   //
260   AliInfo(Form("   CreateOutputObjects of task %s\n", GetName()));
261   
262   fOutputList = new TObjArray();
263   fOutputList->SetOwner();
264
265   fEventCounters = new AliCounterCollection("eventCounters");
266
267   if ( ! GetCentralityClasses() ) SetCentralityClasses();
268   TString centralityClasses = "";
269   for ( Int_t icent=1; icent<=GetCentralityClasses()->GetNbins(); ++icent ) {
270     if ( ! centralityClasses.IsNull() ) centralityClasses += "/";
271     centralityClasses += GetCentralityClasses()->GetBinLabel(icent);
272   }
273   fEventCounters->AddRubric("selected", "yes/no");
274   fEventCounters->AddRubric("trigger", 100);
275   fEventCounters->AddRubric("centrality", centralityClasses);
276   fEventCounters->AddRubric("run", 10000);
277   fEventCounters->Init();
278   fOutputList->Add(fEventCounters);
279  
280   fMergeableCollection = new AliMergeableCollection("outputObjects");
281   fOutputList->Add(fMergeableCollection);
282
283   PostData(1, fOutputList);
284   
285   fMuonEventCuts->Print();
286   
287   MyUserCreateOutputObjects();
288 }
289
290
291 //________________________________________________________________________
292 void AliVAnalysisMuon::UserExec(Option_t * /*option*/) 
293 {
294   //
295   /// Main loop
296   /// Called for each event
297   //
298
299   fAODEvent = dynamic_cast<AliAODEvent*> (InputEvent());
300   if ( ! fAODEvent ) 
301     fESDEvent = dynamic_cast<AliESDEvent*> (InputEvent());
302
303   if ( ! fAODEvent && ! fESDEvent ) {
304     AliError ("AOD or ESD event not found. Nothing done!");
305     return;
306   }
307   
308   if ( ! fMuonEventCuts->IsSelected(fInputHandler) ) return;
309
310   Int_t physSel = ( fInputHandler->IsEventSelected() & AliVEvent::kAny ) ? kPhysSelPass : kPhysSelReject;
311
312   //
313   // Global event info
314   //
315   TObjArray* selectTrigClasses = fMuonEventCuts->GetSelectedTrigClassesInEvent(InputEvent());
316
317   Double_t centrality = fMuonEventCuts->GetCentrality(InputEvent());
318   Int_t centralityBin = GetCentralityClasses()->FindBin(centrality);
319   TString centralityBinLabel = GetCentralityClasses()->GetBinLabel(centralityBin);
320
321   TString selKey = ( physSel == kPhysSelPass ) ? "yes" : "no";
322   for ( Int_t itrig=0; itrig<selectTrigClasses->GetEntries(); ++itrig ) {
323     TString trigName = selectTrigClasses->At(itrig)->GetName();
324     fEventCounters->Count(Form("trigger:%s/selected:%s/centrality:%s/run:%i", trigName.Data(), selKey.Data(), centralityBinLabel.Data(),fCurrentRunNumber));
325   }
326
327   ProcessEvent(fPhysSelKeys->At(physSel)->GetName(), *selectTrigClasses, centralityBinLabel);
328
329   // Post final data. It will be written to a file with option "RECREATE"
330   PostData(1, fOutputList);
331 }
332
333 //________________________________________________________________________
334 void AliVAnalysisMuon::Terminate(Option_t *)
335 {
336   //
337   /// Draw some histogram at the end.
338   //
339   
340   if ( ! fTerminateOptions ) SetTerminateOptions();
341   
342   if ( gROOT->IsBatch() ) return;
343     
344   fOutputList = dynamic_cast<TObjArray*>(GetOutputData(1));
345   if ( ! fOutputList ) return;
346   fEventCounters = static_cast<AliCounterCollection*>(fOutputList->FindObject("eventCounters"));
347   fMergeableCollection = static_cast<AliMergeableCollection*>(fOutputList->FindObject("outputObjects"));
348   
349   if ( ! fMergeableCollection ) return;
350   AliInfo(Form("Mergeable collection size %g MB", fMergeableCollection->EstimateSize()/1024.0/1024.0));
351   if ( fTerminateOptions->At(3) ) {
352     TString sopt = fTerminateOptions->At(3)->GetName();
353     if ( sopt.Contains("verbose") ) fMergeableCollection->Print("*"); 
354   }
355   SetCentralityClassesFromOutput();
356 }
357
358
359 //________________________________________________________________________
360 Int_t AliVAnalysisMuon::GetParticleType(AliVParticle* track)
361 {
362   //
363   /// Get particle type from mathced MC track
364   //
365   
366   Int_t trackSrc = kUnidentified;
367   Int_t trackLabel = track->GetLabel();
368   if ( trackLabel >= 0 ) {
369     AliVParticle* matchedMCTrack = MCEvent()->GetTrack(trackLabel);
370     if ( matchedMCTrack ) trackSrc = RecoTrackMother(matchedMCTrack);
371   } // track has MC label
372   return trackSrc;
373 }
374
375
376 //________________________________________________________________________
377 Int_t AliVAnalysisMuon::RecoTrackMother(AliVParticle* mcParticle)
378 {
379   //
380   /// Find track mother from kinematics
381   //
382   
383   Int_t recoPdg = mcParticle->PdgCode();
384   
385   // Track is not a muon
386   if ( TMath::Abs(recoPdg) != 13 ) return kRecoHadron;
387   
388   Int_t imother = AliAnalysisMuonUtility::GetMotherIndex(mcParticle);
389   
390   Int_t den[3] = {100, 1000, 1};
391   
392   Int_t motherType = kDecayMu;
393   while ( imother >= 0 ) {
394     AliVParticle* part = MCEvent()->GetTrack(imother);
395     //if ( ! part ) return motherType;
396     
397     Int_t absPdg = TMath::Abs(part->PdgCode());
398     
399     Bool_t isPrimary = AliAnalysisMuonUtility::IsPrimary(part, MCEvent());
400     
401     if ( isPrimary ) {
402       if ( absPdg == 24 ) return kWbosonMu;
403       
404       for ( Int_t idec=0; idec<3; idec++ ) {
405         Int_t flv = (absPdg%100000)/den[idec];
406         if ( flv > 0 && flv < 4 ) return kDecayMu;
407         else if ( flv == 0 || flv > 5 ) continue;
408         else {
409           if ( den[idec] == 100 ) motherType = kQuarkoniumMu;
410           else if ( flv == 4 ) motherType = kCharmMu;
411           else motherType = kBeautyMu;
412           break; // break loop on pdg code
413           // but continue the global loop to find higher mass HF
414         }
415       } // loop on pdg code
416       if ( absPdg < 10 ) break; // particle loop
417     } // is primary
418     else {
419       if ( part->Zv() < -90. ) {
420         // If hadronic process => secondary
421         //if ( part->GetUniqueID() == kPHadronic ) {
422         return kSecondaryMu;
423         //}
424       }
425     } // is secondary
426     
427     imother = AliAnalysisMuonUtility::GetMotherIndex(part);
428     
429   } // loop on mothers
430   
431   return motherType;
432 }
433
434
435 //________________________________________________________________________
436 Bool_t AliVAnalysisMuon::AddObjectToCollection(TObject* object, Int_t index)
437 {
438   //
439   /// Add object to collection
440   //
441   
442   if ( ! fOutputPrototypeList ) {
443     fOutputPrototypeList = new TObjArray();
444     fOutputPrototypeList->SetOwner();
445   }
446   if ( fOutputPrototypeList->FindObject(object->GetName() ) ) {
447     AliWarning(Form("Object with name %s already in the list", object->GetName()));
448     return kFALSE;
449   }
450   if ( index < 0 ) fOutputPrototypeList->Add(object);
451   else fOutputPrototypeList->AddAtAndExpand(object, index);
452   
453   return kTRUE;
454 }
455
456 //________________________________________________________________________
457 TObject* AliVAnalysisMuon::GetMergeableObject(TString physSel, TString trigClassName, TString centrality, TString objectName)
458 {
459   //
460   /// Get mergeable object
461   /// (create collection if necessary)
462   //
463   
464   TString identifier = Form("/%s/%s/%s/", physSel.Data(), trigClassName.Data(), centrality.Data());
465   
466   TObject* obj = fMergeableCollection->GetObject(identifier.Data(), objectName.Data());
467   if ( ! obj ) {
468     CreateMergeableObjects(physSel, trigClassName, centrality);
469     obj = fMergeableCollection->GetObject(identifier.Data(), objectName.Data());
470     AliInfo(Form("Mergeable object collection size %g MB", fMergeableCollection->EstimateSize()/1024.0/1024.0));
471   }
472   return obj;
473 }
474
475 //________________________________________________________________________
476 TObject* AliVAnalysisMuon::GetSum(TString physSel, TString trigClassNames, TString centrality, TString objectPattern)
477 {
478   //
479   /// Sum objects
480   /// - physSel, trigClassNames must be in the form: key1,key2
481   /// - centrality must be in the form minValue_maxValue
482   /// - objectPattern must be in the form match1,match2
483   ///   meaning that the object name must contain match1 or match2
484   ///   wildcard * is allowed
485   
486   if ( ! fMergeableCollection ) return 0x0;
487   
488   // Get centrality range
489   Int_t firstCentrality = 1;
490   Int_t lastCentrality = GetCentralityClasses()->GetNbins();
491   
492   TObjArray* centralityRange = centrality.Tokenize("_");
493   Float_t range[2] = {0., 100.};
494   if ( centralityRange->GetEntries() >= 2 ) {
495     for ( Int_t irange=0; irange<2; ++irange ) {
496       range[irange] = ((TObjString*)centralityRange->At(irange))->GetString().Atof();
497     }
498     firstCentrality = GetCentralityClasses()->FindBin(range[0]+0.0001);
499     lastCentrality = GetCentralityClasses()->FindBin(range[1]-0.0001);
500   }
501   delete centralityRange;
502   
503   TString sumCentralityString = "";
504   for ( Int_t icent=firstCentrality; icent<=lastCentrality; ++icent ) {
505     if ( ! sumCentralityString.IsNull() ) sumCentralityString += ",";
506     sumCentralityString += GetCentralityClasses()->GetBinLabel(icent);
507   }
508   
509 //  objectPattern.ReplaceAll(" ","");
510 //  TObjArray* objPatternList = objectPattern.Tokenize("&");
511 //  TObjArray objPatternMatrix(objPatternList->GetEntries());
512 //  objPatternMatrix.SetOwner();
513 //  for ( Int_t ikey=0; ikey<objPatternList->GetEntries(); ikey++ ) {
514 //    TObjArray* subKeyList = ((TObjString*)objPatternList->At(ikey))->GetString().Tokenize(",");
515 //    objPatternMatrix.AddAt(subKeyList, ikey);
516 //  }
517 //  delete objPatternList;
518   
519
520   TObjArray objectNameInCollection;
521   objectNameInCollection.SetOwner();
522   TObjArray* physSelList = physSel.Tokenize(",");
523   TObjArray* trigClassList = trigClassNames.Tokenize(",");
524   TObjArray* centralityList = sumCentralityString.Tokenize(",");
525   for ( Int_t isel=0; isel<physSelList->GetEntries(); isel++ ) {
526     for ( Int_t itrig = 0; itrig<trigClassList->GetEntries(); itrig++ ) {
527       for ( Int_t icent=0; icent<centralityList->GetEntries(); icent++ ) {
528         TString currId = Form("/%s/%s/%s/", physSelList->At(isel)->GetName(), trigClassList->At(itrig)->GetName(),centralityList->At(icent)->GetName());
529         TList* objNameList = fMergeableCollection->CreateListOfObjectNames(currId.Data());
530         for ( Int_t iobj=0; iobj<objNameList->GetEntries(); iobj++ ) {
531           TString objName = objNameList->At(iobj)->GetName();
532           if ( ! objectNameInCollection.FindObject(objName.Data()) ) objectNameInCollection.Add(new TObjString(objName.Data()));
533         }
534         delete objNameList;
535       }
536     }
537   }
538   delete physSelList;
539   delete trigClassList;
540   delete centralityList;
541   
542   TObjArray* objPatternList = objectPattern.Tokenize(",");
543
544   TString matchingObjectNames = "";
545   for ( Int_t iobj=0; iobj<objectNameInCollection.GetEntries(); iobj++ ) {
546     TString objName = objectNameInCollection.At(iobj)->GetName();
547     for ( Int_t ipat=0; ipat<objPatternList->GetEntries(); ipat++ ) {
548       TString currPattern = ((TObjString*)objPatternList->At(ipat))->GetString();
549       if ( currPattern.Contains("*") ) {
550         if ( ! objName.Contains(TRegexp(currPattern.Data(),kTRUE)) ) continue;
551       }
552       else if ( objName != currPattern ) continue;
553
554       if ( ! matchingObjectNames.IsNull() ) matchingObjectNames.Append(",");
555       matchingObjectNames += objName;
556     }
557   }
558   delete objPatternList;
559   
560 //  for ( Int_t iobj=0; iobj<objectNameInCollection.GetEntries(); iobj++ ) {
561 //    TString objName = objectNameInCollection.At(iobj)->GetName();
562 //    Bool_t matchAnd = kTRUE;
563 //    for ( Int_t ikey=0; ikey<objPatternMatrix.GetEntries(); ikey++ ) {
564 //      TObjArray*  subKeyList = (TObjArray*)objPatternMatrix.At(ikey);
565 //      Bool_t matchOr = kFALSE;
566 //      for ( Int_t isub=0; isub<subKeyList->GetEntries(); isub++ ) {
567 //        TString subKeyString = ((TObjString*)subKeyList->At(isub))->GetString();
568 //        if ( subKeyString.Contains("*") ) {
569 //          if ( objName.Contains(TRegexp(subKeyString.Data())) ) {
570 //            matchOr = kTRUE;
571 //            break;
572 //          }
573 //        }
574 //        else if ( objName == subKeyString ) {
575 //          matchOr = kTRUE;
576 //          break;
577 //        }
578 //      }
579 //      if ( ! matchOr ) {
580 //        matchAnd = kFALSE;
581 //        break;
582 //      }
583 //    }
584 //    if ( ! matchAnd ) continue;
585 //    if ( ! matchingObjectNames.IsNull() ) matchingObjectNames.Append(",");
586 //    matchingObjectNames += objName;
587 //  }
588
589   TString idPattern = Form("/%s/%s/%s/%s", physSel.Data(), trigClassNames.Data(), sumCentralityString.Data(), matchingObjectNames.Data());
590   idPattern.ReplaceAll(" ","");
591   
592   AliDebug(1,Form("Sum pattern %s", idPattern.Data()));
593   
594   return fMergeableCollection->GetSum(idPattern.Data());
595 }
596
597 //___________________________________________________________________________
598 void AliVAnalysisMuon::CreateMergeableObjects(TString physSel, TString trigClassName, TString centrality)
599 {
600   TObject* obj = 0x0;
601   TString objectName = "";
602   TString identifier = Form("/%s/%s/%s/", physSel.Data(), trigClassName.Data(), centrality.Data());
603   for ( Int_t iobj=0; iobj<fOutputPrototypeList->GetEntries(); ++iobj ) {
604     objectName = fOutputPrototypeList->At(iobj)->GetName();
605     obj = fOutputPrototypeList->At(iobj)->Clone(objectName.Data());
606     fMergeableCollection->Adopt(identifier, obj);
607   } // loop on histos
608 }
609
610
611 //_______________________________________________________________________
612 Bool_t AliVAnalysisMuon::SetSparseRange(AliCFGridSparse* gridSparse,
613                                         Int_t ivar, TString labelName,
614                                         Double_t varMin, Double_t varMax,
615                                         TString option)
616 {
617   //
618   /// Set range in a smart way.
619   /// Allows to select a bin from the label.
620   /// Check the bin limits.
621   //
622   
623   // Keep for backward compatibility
624   
625   return AliAnalysisMuonUtility::SetSparseRange(gridSparse,ivar,labelName,varMin, varMax,option);
626 }
627
628 //________________________________________________________________________
629 TString AliVAnalysisMuon::GetDefaultTrigClassPatterns() const
630 {
631   /// Get default trigger class patterns
632   return fMuonEventCuts->GetDefaultTrigClassPatterns();
633 }
634
635 //________________________________________________________________________
636 void AliVAnalysisMuon::SetTrigClassPatterns(const TString pattern)
637 {
638   /// Set trigger classes
639   TString currPattern = pattern;
640   if ( currPattern.IsNull() ) { 
641     currPattern = GetDefaultTrigClassPatterns();
642     currPattern.Append(",!CMUP*"); // by default do not account for UltraPeripheral events
643   }
644   fMuonEventCuts->SetTrigClassPatterns(currPattern);
645 }
646
647 //________________________________________________________________________
648 TList* AliVAnalysisMuon::GetAllSelectedTrigClasses() const
649 {
650   /// Get trigger classes
651   return fMuonEventCuts->GetAllSelectedTrigClasses();
652 }
653
654 //________________________________________________________________________
655 void AliVAnalysisMuon::SetCentralityClasses(Int_t nCentralityBins, Double_t* centralityBins)
656 {
657   //
658   /// Set centrality classes
659   //
660   fMuonEventCuts->SetCentralityClasses(nCentralityBins, centralityBins);
661 }
662
663 //________________________________________________________________________
664 TAxis* AliVAnalysisMuon::GetCentralityClasses() const
665 {
666   //
667   /// Set centrality classes
668   //
669   return fMuonEventCuts->GetCentralityClasses();
670 }
671
672 //________________________________________________________________________
673 Bool_t AliVAnalysisMuon::SetCentralityClassesFromOutput()
674 {
675   //
676   /// Get axis of centrality classes from output key
677   //
678   if ( ! fMergeableCollection ) return kFALSE;
679   TList* centrKeyList = fMergeableCollection->CreateListOfKeys(2);
680   TObjArray centrLimitsList;
681   centrLimitsList.SetOwner();
682   if ( ! centrKeyList ) return kFALSE;
683   for ( Int_t ikey=0; ikey<centrKeyList->GetEntries(); ikey++ ) {
684     TString centr = static_cast<TObjString*>(centrKeyList->At(ikey))->GetString();
685     TObjArray* array = centr.Tokenize("_");
686     for ( Int_t ilim=0; ilim<array->GetEntries(); ilim++ ) {
687       TString currLim = static_cast<TObjString*>(array->At(ilim))->GetString();
688       if ( ! centrLimitsList.FindObject(currLim.Data()) ) centrLimitsList.Add(new TObjString(currLim));
689     }
690     delete array;
691   }
692   delete centrKeyList;
693   
694   // Get unsorted array
695   TArrayD bins(centrLimitsList.GetEntries());
696   for ( Int_t ibin=0; ibin<centrLimitsList.GetEntries(); ibin++ ) {
697     bins[ibin] = static_cast<TObjString*>(centrLimitsList.At(ibin))->GetString().Atof();
698   }
699   
700   // Sort it
701   Int_t index[bins.GetSize()];
702   TMath::Sort(bins.GetSize(),bins.GetArray(),index, kFALSE);
703   
704   TArrayD sortedBins(bins.GetSize());
705   for ( Int_t ibin=0; ibin<centrLimitsList.GetEntries(); ibin++ ) {
706     sortedBins[ibin] = bins[index[ibin]];
707   }
708   
709   SetCentralityClasses(sortedBins.GetSize()-1, sortedBins.GetArray());
710   return kTRUE;
711 }
712
713 //________________________________________________________________________
714 void AliVAnalysisMuon::SetTerminateOptions(TString physSel, TString trigClass, TString centralityRange, TString furtherOpts)
715 {
716   //
717   /// Set terminate options
718   //
719   if ( ! fTerminateOptions ) {
720     fTerminateOptions = new TObjArray(4);
721     fTerminateOptions->SetOwner();
722   }
723   fTerminateOptions->AddAt(new TObjString(physSel), 0);
724   fTerminateOptions->AddAt(new TObjString(trigClass), 1);
725   fTerminateOptions->AddAt(new TObjString(centralityRange),2);
726   fTerminateOptions->AddLast(new TObjString(furtherOpts));
727 }
728
729 //________________________________________________________________________
730 void AliVAnalysisMuon::InitKeys()
731 {
732   //
733   /// Init keys
734   //
735   TString chargeKeys = "MuMinus MuPlus";
736   fChargeKeys = chargeKeys.Tokenize(" ");
737   
738   TString srcKeys = "CharmMu BeautyMu QuarkoniumMu WbosonMu DecayMu SecondaryMu Hadron Unidentified";
739   fSrcKeys = srcKeys.Tokenize(" ");
740   
741   TString physSelKeys = "PhysSelPass PhysSelReject";
742   fPhysSelKeys = physSelKeys.Tokenize(" ");
743 }
744
745
746 //________________________________________________________________________
747 void AliVAnalysisMuon::SetWeight ( TObject* wgtObj )
748 {
749   /// Set weight
750   if ( fWeights->FindObject(wgtObj->GetName()) ) {
751     AliWarning(Form("Weight object %s is already in the list",wgtObj->GetName()));
752     return;
753   }
754   fWeights->Add(wgtObj);
755 }
756
757 //________________________________________________________________________
758 TObject* AliVAnalysisMuon::GetWeight ( const Char_t* wgtName )
759 {
760   /// Get weight
761   return fWeights->FindObject(wgtName);
762 }
763
764