1 /**************************************************************************
2 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 /* $Id: AliVAnalysisMuon.cxx 47782 2011-02-24 18:37:31Z martinez $ */
18 //-----------------------------------------------------------------------------
19 /// \class AliVAnalysisMuon
20 /// Base class with utilities for muon analysis
22 /// \author Diego Stocco
23 //-----------------------------------------------------------------------------
25 #include "AliVAnalysisMuon.h"
35 #include "TObjString.h"
36 #include "TObjArray.h"
37 #include "THashList.h"
39 //#include "TMCProcess.h"
40 #include "TLorentzVector.h"
44 #include "AliInputEventHandler.h"
45 #include "AliCentrality.h"
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"
59 #include "AliAnalysisManager.h"
60 #include "AliAnalysisTaskSE.h"
61 #include "AliAnalysisDataSlot.h"
62 #include "AliAnalysisDataContainer.h"
65 #include "AliCFGridSparse.h"
68 #include "AliMergeableCollection.h"
69 #include "AliMuonEventCuts.h"
70 #include "AliMuonTrackCuts.h"
71 #include "AliMuonPairCuts.h"
72 #include "AliAnalysisMuonUtility.h"
75 ClassImp(AliVAnalysisMuon) // Class implementation in ROOT context
79 //________________________________________________________________________
80 AliVAnalysisMuon::AliVAnalysisMuon() :
87 fTerminateOptions(0x0),
92 fMergeableCollection(0x0),
94 fOutputPrototypeList(0x0)
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)),
107 fTerminateOptions(0x0),
112 fMergeableCollection(0x0),
114 fOutputPrototypeList(0x0)
121 SetTrigClassPatterns("");
122 SetCentralityClasses();
124 DefineOutput(1, TObjArray::Class());
127 //________________________________________________________________________
128 AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonTrackCuts& trackCuts) :
129 AliAnalysisTaskSE(name),
130 fMuonEventCuts(new AliMuonEventCuts("stdEventCuts","stdEventCuts")),
131 fMuonTrackCuts(new AliMuonTrackCuts(trackCuts)),
135 fTerminateOptions(0x0),
140 fMergeableCollection(0x0),
142 fOutputPrototypeList(0x0)
149 SetTrigClassPatterns("");
150 SetCentralityClasses();
152 DefineOutput(1, TObjArray::Class());
156 //________________________________________________________________________
157 AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonPairCuts& pairCuts) :
158 AliAnalysisTaskSE(name),
159 fMuonEventCuts(new AliMuonEventCuts("stdEventCuts","stdEventCuts")),
161 fMuonPairCuts(new AliMuonPairCuts(pairCuts)),
164 fTerminateOptions(0x0),
169 fMergeableCollection(0x0),
171 fOutputPrototypeList(0x0)
177 SetTrigClassPatterns("");
178 SetCentralityClasses();
180 DefineOutput(1, TObjArray::Class());
184 //________________________________________________________________________
185 AliVAnalysisMuon::~AliVAnalysisMuon()
191 delete fMuonEventCuts;
192 delete fMuonTrackCuts;
193 delete fMuonPairCuts;
194 delete fTerminateOptions;
198 delete fOutputPrototypeList;
201 // For proof: do not delete output containers
202 if ( ! AliAnalysisManager::GetAnalysisManager() || ! AliAnalysisManager::GetAnalysisManager()->IsProofMode() ) {
207 //___________________________________________________________________________
208 void AliVAnalysisMuon::FinishTaskOutput()
211 /// Remove empty histograms to reduce the number of histos to be merged
215 fMergeableCollection->PruneEmptyObjects();
217 TString objectName = "";
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()));
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);
232 AliWarning("Stat histogram not available");
235 } // loop on stat type
240 //___________________________________________________________________________
241 void AliVAnalysisMuon::NotifyRun()
243 /// Set run number for cuts
244 if ( fMuonTrackCuts ) fMuonTrackCuts->SetRun(fInputHandler);
245 if ( fMuonPairCuts ) fMuonPairCuts->SetRun(fInputHandler);
248 //___________________________________________________________________________
249 void AliVAnalysisMuon::UserCreateOutputObjects()
252 /// Create output objects
254 AliInfo(Form(" CreateOutputObjects of task %s\n", GetName()));
256 fOutputList = new TObjArray();
257 fOutputList->SetOwner();
259 fEventCounters = new AliCounterCollection("eventCounters");
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);
267 fEventCounters->AddRubric("selected", "yes/no");
268 fEventCounters->AddRubric("trigger", 100);
269 fEventCounters->AddRubric("centrality", centralityClasses);
270 fEventCounters->Init();
271 fOutputList->Add(fEventCounters);
273 fMergeableCollection = new AliMergeableCollection("outputObjects");
274 fOutputList->Add(fMergeableCollection);
276 PostData(1, fOutputList);
278 fMuonEventCuts->Print();
280 MyUserCreateOutputObjects();
284 //________________________________________________________________________
285 void AliVAnalysisMuon::UserExec(Option_t * /*option*/)
289 /// Called for each event
292 fAODEvent = dynamic_cast<AliAODEvent*> (InputEvent());
294 fESDEvent = dynamic_cast<AliESDEvent*> (InputEvent());
296 if ( ! fAODEvent && ! fESDEvent ) {
297 AliError ("AOD or ESD event not found. Nothing done!");
301 if ( ! fMuonEventCuts->IsSelected(fInputHandler) ) return;
303 Int_t physSel = ( fInputHandler->IsEventSelected() & AliVEvent::kAny ) ? kPhysSelPass : kPhysSelReject;
308 TObjArray* selectTrigClasses = fMuonEventCuts->GetSelectedTrigClassesInEvent(InputEvent());
310 Double_t centrality = fMuonEventCuts->GetCentrality(InputEvent());
311 Int_t centralityBin = GetCentralityClasses()->FindBin(centrality);
312 TString centralityBinLabel = GetCentralityClasses()->GetBinLabel(centralityBin);
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()));
320 ProcessEvent(fPhysSelKeys->At(physSel)->GetName(), *selectTrigClasses, centralityBinLabel);
322 // Post final data. It will be written to a file with option "RECREATE"
323 PostData(1, fOutputList);
326 //________________________________________________________________________
327 void AliVAnalysisMuon::Terminate(Option_t *)
330 /// Draw some histogram at the end.
333 if ( ! fTerminateOptions ) SetTerminateOptions();
335 if ( gROOT->IsBatch() ) return;
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"));
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("*");
348 SetCentralityClassesFromOutput();
352 //________________________________________________________________________
353 Int_t AliVAnalysisMuon::GetParticleType(AliVParticle* track)
356 /// Get particle type from mathced MC track
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
369 //________________________________________________________________________
370 Int_t AliVAnalysisMuon::RecoTrackMother(AliVParticle* mcParticle)
373 /// Find track mother from kinematics
376 Int_t recoPdg = mcParticle->PdgCode();
378 // Track is not a muon
379 if ( TMath::Abs(recoPdg) != 13 ) return kRecoHadron;
381 Int_t imother = AliAnalysisMuonUtility::GetMotherIndex(mcParticle);
383 Int_t den[3] = {100, 1000, 1};
385 Int_t motherType = kDecayMu;
386 while ( imother >= 0 ) {
387 AliVParticle* part = AliAnalysisMuonUtility::GetMCTrack(imother,InputEvent(),MCEvent());
388 //if ( ! part ) return motherType;
390 Int_t absPdg = TMath::Abs(part->PdgCode());
392 Bool_t isPrimary = AliAnalysisMuonUtility::IsPrimary(part, MCEvent());
395 if ( absPdg == 24 ) return kWbosonMu;
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;
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
408 } // loop on pdg code
409 if ( absPdg < 10 ) break; // particle loop
412 if ( part->Zv() < -90. ) {
413 // If hadronic process => secondary
414 //if ( part->GetUniqueID() == kPHadronic ) {
420 imother = AliAnalysisMuonUtility::GetMotherIndex(part);
428 //________________________________________________________________________
429 Bool_t AliVAnalysisMuon::AddObjectToCollection(TObject* object, Int_t index)
432 /// Add object to collection
435 if ( ! fOutputPrototypeList ) {
436 fOutputPrototypeList = new TObjArray();
437 fOutputPrototypeList->SetOwner();
439 if ( fOutputPrototypeList->FindObject(object->GetName() ) ) {
440 AliWarning(Form("Object with name %s already in the list", object->GetName()));
443 if ( index < 0 ) fOutputPrototypeList->Add(object);
444 else fOutputPrototypeList->AddAtAndExpand(object, index);
449 //________________________________________________________________________
450 TObject* AliVAnalysisMuon::GetMergeableObject(TString physSel, TString trigClassName, TString centrality, TString objectName)
453 /// Get mergeable object
454 /// (create collection if necessary)
457 TString identifier = Form("/%s/%s/%s/", physSel.Data(), trigClassName.Data(), centrality.Data());
459 TObject* obj = fMergeableCollection->GetObject(identifier.Data(), objectName.Data());
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));
468 //________________________________________________________________________
469 TObject* AliVAnalysisMuon::GetSum(TString physSel, TString trigClassNames, TString centrality, TString objectPattern)
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
479 if ( ! fMergeableCollection ) return 0x0;
481 // Get centrality range
482 Int_t firstCentrality = 1;
483 Int_t lastCentrality = GetCentralityClasses()->GetNbins();
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();
491 firstCentrality = GetCentralityClasses()->FindBin(range[0]+0.0001);
492 lastCentrality = GetCentralityClasses()->FindBin(range[1]-0.0001);
494 delete centralityRange;
496 TString sumCentralityString = "";
497 for ( Int_t icent=firstCentrality; icent<=lastCentrality; ++icent ) {
498 if ( ! sumCentralityString.IsNull() ) sumCentralityString += ",";
499 sumCentralityString += GetCentralityClasses()->GetBinLabel(icent);
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);
510 // delete objPatternList;
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()));
532 delete trigClassList;
533 delete centralityList;
535 TObjArray* objPatternList = objectPattern.Tokenize(",");
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;
545 else if ( objName != currPattern ) continue;
547 if ( ! matchingObjectNames.IsNull() ) matchingObjectNames.Append(",");
548 matchingObjectNames += objName;
551 delete objPatternList;
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())) ) {
567 // else if ( objName == subKeyString ) {
572 // if ( ! matchOr ) {
573 // matchAnd = kFALSE;
577 // if ( ! matchAnd ) continue;
578 // if ( ! matchingObjectNames.IsNull() ) matchingObjectNames.Append(",");
579 // matchingObjectNames += objName;
582 TString idPattern = Form("/%s/%s/%s/%s", physSel.Data(), trigClassNames.Data(), sumCentralityString.Data(), matchingObjectNames.Data());
583 idPattern.ReplaceAll(" ","");
585 AliDebug(1,Form("Sum pattern %s", idPattern.Data()));
587 return fMergeableCollection->GetSum(idPattern.Data());
590 //___________________________________________________________________________
591 void AliVAnalysisMuon::CreateMergeableObjects(TString physSel, TString trigClassName, TString centrality)
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);
604 //_______________________________________________________________________
605 Bool_t AliVAnalysisMuon::SetSparseRange(AliCFGridSparse* gridSparse,
606 Int_t ivar, TString labelName,
607 Double_t varMin, Double_t varMax,
611 /// Set range in a smart way.
612 /// Allows to select a bin from the label.
613 /// Check the bin limits.
617 Int_t minVarBin = -1, maxVarBin = -1;
618 TAxis* axis = gridSparse->GetAxis(ivar);
621 printf("Warning: Axis %i not found in %s", ivar, gridSparse->GetName());
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());
633 else if ( option.Contains( "USEBIN" ) ) {
634 minVarBin = (Int_t)varMin;
635 maxVarBin = (Int_t)varMax;
638 minVarBin = axis->FindBin(varMin);
639 maxVarBin = axis->FindBin(varMax);
642 if ( axis->GetFirst() == minVarBin && axis->GetLast() == maxVarBin ) return kFALSE;
644 gridSparse->SetRangeUser(ivar, axis->GetBinCenter(minVarBin), axis->GetBinCenter(maxVarBin));
649 //________________________________________________________________________
650 TString AliVAnalysisMuon::GetDefaultTrigClassPatterns() const
652 /// Get default trigger class patterns
653 return fMuonEventCuts->GetDefaultTrigClassPatterns();
656 //________________________________________________________________________
657 void AliVAnalysisMuon::SetTrigClassPatterns(const TString pattern)
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
665 fMuonEventCuts->SetTrigClassPatterns(currPattern);
668 //________________________________________________________________________
669 TList* AliVAnalysisMuon::GetAllSelectedTrigClasses() const
671 /// Get trigger classes
672 return fMuonEventCuts->GetAllSelectedTrigClasses();
675 //________________________________________________________________________
676 void AliVAnalysisMuon::SetCentralityClasses(Int_t nCentralityBins, Double_t* centralityBins)
679 /// Set centrality classes
681 fMuonEventCuts->SetCentralityClasses(nCentralityBins, centralityBins);
684 //________________________________________________________________________
685 TAxis* AliVAnalysisMuon::GetCentralityClasses() const
688 /// Set centrality classes
690 return fMuonEventCuts->GetCentralityClasses();
693 //________________________________________________________________________
694 Bool_t AliVAnalysisMuon::SetCentralityClassesFromOutput()
697 /// Get axis of centrality classes from output key
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));
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();
722 Int_t index[bins.GetSize()];
723 TMath::Sort(bins.GetSize(),bins.GetArray(),index, kFALSE);
725 TArrayD sortedBins(bins.GetSize());
726 for ( Int_t ibin=0; ibin<centrLimitsList.GetEntries(); ibin++ ) {
727 sortedBins[ibin] = bins[index[ibin]];
730 SetCentralityClasses(sortedBins.GetSize()-1, sortedBins.GetArray());
734 //________________________________________________________________________
735 void AliVAnalysisMuon::SetTerminateOptions(TString physSel, TString trigClass, TString centralityRange, TString furtherOpts)
738 /// Set terminate options
740 if ( ! fTerminateOptions ) {
741 fTerminateOptions = new TObjArray(4);
742 fTerminateOptions->SetOwner();
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));
750 //________________________________________________________________________
751 void AliVAnalysisMuon::InitKeys()
753 TString chargeKeys = "MuMinus MuPlus";
754 fChargeKeys = chargeKeys.Tokenize(" ");
756 TString srcKeys = "CharmMu BeautyMu QuarkoniumMu WbosonMu DecayMu SecondaryMu Hadron Unidentified";
757 fSrcKeys = srcKeys.Tokenize(" ");
759 TString physSelKeys = "PhysSelPass PhysSelReject";
760 fPhysSelKeys = physSelKeys.Tokenize(" ");