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