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"
43 #include "AliInputEventHandler.h"
44 #include "AliCentrality.h"
46 #include "AliAODEvent.h"
47 #include "AliAODTrack.h"
48 #include "AliAODMCParticle.h"
49 #include "AliMCEvent.h"
50 #include "AliMCParticle.h"
51 //#include "AliStack.h"
52 #include "AliESDEvent.h"
53 #include "AliESDMuonTrack.h"
56 #include "AliAnalysisManager.h"
57 #include "AliAnalysisTaskSE.h"
58 #include "AliAnalysisDataSlot.h"
59 #include "AliAnalysisDataContainer.h"
62 #include "AliCFGridSparse.h"
65 #include "AliCounterCollection.h"
66 #include "AliMergeableCollection.h"
69 ClassImp(AliVAnalysisMuon) // Class implementation in ROOT context
73 //________________________________________________________________________
74 AliVAnalysisMuon::AliVAnalysisMuon() :
80 fTerminateOptions(0x0),
85 fCentralityClasses(0x0),
87 fMergeableCollection(0x0),
89 fSelectedTrigPattern(0x0),
90 fRejectedTrigPattern(0x0),
91 fSelectedTrigLevel(0x0),
92 fOutputPrototypeList(0x0)
97 //________________________________________________________________________
98 AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonTrackCuts& trackCuts, const AliMuonPairCuts& pairCuts) :
99 AliAnalysisTaskSE(name),
100 fMuonTrackCuts(trackCuts),
101 fMuonPairCuts(pairCuts),
104 fTerminateOptions(0x0),
108 fTriggerClasses(new THashList()),
109 fCentralityClasses(0x0),
111 fMergeableCollection(0x0),
113 fSelectedTrigPattern(new TObjArray()),
114 fRejectedTrigPattern(new TObjArray()),
115 fSelectedTrigLevel(new TObjArray()),
116 fOutputPrototypeList(0x0)
122 fTriggerClasses->SetOwner();
124 SetTrigClassPatterns();
125 SetCentralityClasses();
127 DefineOutput(1, TObjArray::Class());
130 //________________________________________________________________________
131 AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonTrackCuts& trackCuts) :
132 AliAnalysisTaskSE(name),
133 fMuonTrackCuts(trackCuts),
137 fTerminateOptions(0x0),
141 fTriggerClasses(new THashList()),
142 fCentralityClasses(0x0),
144 fMergeableCollection(0x0),
146 fSelectedTrigPattern(new TObjArray()),
147 fRejectedTrigPattern(new TObjArray()),
148 fSelectedTrigLevel(new TObjArray()),
149 fOutputPrototypeList(0x0)
155 fTriggerClasses->SetOwner();
157 SetTrigClassPatterns();
158 SetCentralityClasses();
160 DefineOutput(1, TObjArray::Class());
164 //________________________________________________________________________
165 AliVAnalysisMuon::AliVAnalysisMuon(const char *name, const AliMuonPairCuts& pairCuts) :
166 AliAnalysisTaskSE(name),
168 fMuonPairCuts(pairCuts),
171 fTerminateOptions(0x0),
175 fTriggerClasses(new THashList()),
176 fCentralityClasses(0x0),
178 fMergeableCollection(0x0),
180 fSelectedTrigPattern(new TObjArray()),
181 fRejectedTrigPattern(new TObjArray()),
182 fSelectedTrigLevel(new TObjArray()),
183 fOutputPrototypeList(0x0)
188 fTriggerClasses->SetOwner();
190 SetTrigClassPatterns();
191 SetCentralityClasses();
193 DefineOutput(1, TObjArray::Class());
197 //________________________________________________________________________
198 AliVAnalysisMuon::~AliVAnalysisMuon()
204 delete fTerminateOptions;
208 delete fTriggerClasses;
209 delete fCentralityClasses;
210 delete fSelectedTrigPattern;
211 delete fRejectedTrigPattern;
212 delete fSelectedTrigLevel;
213 delete fOutputPrototypeList;
216 // For proof: do not delete output containers
217 if ( ! AliAnalysisManager::GetAnalysisManager() || ! AliAnalysisManager::GetAnalysisManager()->IsProofMode() ) {
222 //___________________________________________________________________________
223 void AliVAnalysisMuon::FinishTaskOutput()
226 /// Remove empty histograms to reduce the number of histos to be merged
230 fMergeableCollection->PruneEmptyObjects();
232 TString objectName = "";
234 // Add stat. info from physics selection
235 // (usefull when running on AODs)
236 if ( fInputHandler ) {
237 for ( Int_t istat=0; istat<2; istat++ ) {
238 TString statType = ( istat == 0 ) ? "ALL" : "BIN0";
239 TH2* hStat = dynamic_cast<TH2*>(fInputHandler->GetStatistics(statType.Data()));
241 objectName = Form("%s_%s", hStat->GetName(), GetName());
242 TH2* cloneStat = static_cast<TH2*>(hStat->Clone(objectName.Data()));
243 cloneStat->SetDirectory(0);
244 fOutputList->Add(cloneStat);
247 AliWarning("Stat histogram not available");
250 } // loop on stat type
255 //___________________________________________________________________________
256 void AliVAnalysisMuon::NotifyRun()
258 /// Set run number for cuts
259 if ( fMuonTrackCuts.GetFilterMask() ) fMuonTrackCuts.SetRun(fCurrentRunNumber);
260 if ( fMuonPairCuts.GetFilterMask() ) fMuonPairCuts.SetRun(fCurrentRunNumber);
263 //___________________________________________________________________________
264 void AliVAnalysisMuon::UserCreateOutputObjects()
267 /// Create output objects
269 AliInfo(Form(" CreateOutputObjects of task %s\n", GetName()));
271 fOutputList = new TObjArray();
272 fOutputList->SetOwner();
274 fEventCounters = new AliCounterCollection("eventCounters");
276 if ( ! fCentralityClasses ) SetCentralityClasses();
277 TString centralityClasses = "";
278 for ( Int_t icent=1; icent<=fCentralityClasses->GetNbins(); ++icent ) {
279 if ( ! centralityClasses.IsNull() ) centralityClasses += "/";
280 centralityClasses += fCentralityClasses->GetBinLabel(icent);
282 fEventCounters->AddRubric("selected", "yes/no");
283 fEventCounters->AddRubric("trigger", 100);
284 fEventCounters->AddRubric("centrality", centralityClasses);
285 fEventCounters->Init();
286 fOutputList->Add(fEventCounters);
288 fMergeableCollection = new AliMergeableCollection("outputObjects");
289 fOutputList->Add(fMergeableCollection);
291 PostData(1, fOutputList);
293 MyUserCreateOutputObjects();
297 //________________________________________________________________________
298 void AliVAnalysisMuon::UserExec(Option_t * /*option*/)
302 /// Called for each event
305 fAODEvent = dynamic_cast<AliAODEvent*> (InputEvent());
307 fESDEvent = dynamic_cast<AliESDEvent*> (InputEvent());
309 if ( ! fAODEvent && ! fESDEvent ) {
310 AliError ("AOD or ESD event not found. Nothing done!");
314 Int_t physSel = ( fInputHandler->IsEventSelected() & AliVEvent::kAny ) ? kPhysSelPass : kPhysSelReject;
320 TString firedTrigClasses = ( fAODEvent ) ? fAODEvent->GetFiredTriggerClasses() : fESDEvent->GetFiredTriggerClasses();
321 firedTrigClasses.Prepend("ANY ");
322 AliDebug(2, Form("Fired classes %s", firedTrigClasses.Data()));
323 TObjArray* selectTrigClasses = BuildTriggerClasses(firedTrigClasses);
324 if ( selectTrigClasses->GetEntries() == 0 ) {
325 delete selectTrigClasses;
329 Double_t centrality = InputEvent()->GetCentrality()->GetCentralityPercentile("V0M");
330 Int_t centralityBin = fCentralityClasses->FindBin(centrality);
331 TString centralityBinLabel = fCentralityClasses->GetBinLabel(centralityBin);
333 TString selKey = ( physSel == kPhysSelPass ) ? "yes" : "no";
334 for ( Int_t itrig=0; itrig<selectTrigClasses->GetEntries(); ++itrig ) {
335 TString trigName = selectTrigClasses->At(itrig)->GetName();
336 fEventCounters->Count(Form("trigger:%s/selected:%s/centrality:%s", trigName.Data(), selKey.Data(), centralityBinLabel.Data()));
339 ProcessEvent(fPhysSelKeys->At(physSel)->GetName(), *selectTrigClasses, fCentralityClasses->GetBinLabel(centralityBin));
341 delete selectTrigClasses;
343 // Post final data. It will be written to a file with option "RECREATE"
344 PostData(1, fOutputList);
347 //________________________________________________________________________
348 void AliVAnalysisMuon::Terminate(Option_t *)
351 /// Draw some histogram at the end.
354 if ( gROOT->IsBatch() ) return;
356 fOutputList = dynamic_cast<TObjArray*>(GetOutputData(1));
357 if ( ! fOutputList ) return;
358 fEventCounters = static_cast<AliCounterCollection*>(fOutputList->FindObject("eventCounters"));
359 fMergeableCollection = static_cast<AliMergeableCollection*>(fOutputList->FindObject("outputObjects"));
361 if ( ! fTerminateOptions ) SetTerminateOptions();
362 if ( ! fMergeableCollection ) return;
363 AliInfo(Form("Histogram collection size %g MB", fMergeableCollection->EstimateSize()/1024.0/1024.0));
364 if ( fTerminateOptions->At(3) ) {
365 TString sopt = fTerminateOptions->At(3)->GetName();
366 if ( sopt.Contains("verbose") ) fMergeableCollection->Print("*");
372 //________________________________________________________________________
373 Int_t AliVAnalysisMuon::GetNTracks()
376 /// Return the number of tracks in event
378 return ( fAODEvent ) ? fAODEvent->GetNTracks() : fESDEvent->GetNumberOfMuonTracks();
382 //________________________________________________________________________
383 AliVParticle* AliVAnalysisMuon::GetTrack(Int_t itrack)
386 /// Get the current track
388 AliVParticle* track = 0x0;
389 if ( fAODEvent ) track = fAODEvent->GetTrack(itrack);
390 else track = fESDEvent->GetMuonTrack(itrack);
394 //________________________________________________________________________
395 Double_t AliVAnalysisMuon::MuonMass2() const
397 /// A usefull constant
398 static Double_t m2 = 1.11636129640000012e-02; // using a constant here as the line below is a problem for CINT...
402 //________________________________________________________________________
403 TLorentzVector AliVAnalysisMuon::GetTrackPair(AliVParticle* track1, AliVParticle* track2) const
409 AliVParticle* tracks[2] = {track1, track2};
411 TLorentzVector vec[2];
412 for ( Int_t itrack=0; itrack<2; ++itrack ) {
413 Double_t trackP = tracks[itrack]->P();
414 Double_t energy = TMath::Sqrt(trackP*trackP + MuonMass2());
415 vec[itrack].SetPxPyPzE(tracks[itrack]->Px(), tracks[itrack]->Py(), tracks[itrack]->Pz(), energy);
418 TLorentzVector vecPair = vec[0] + vec[1];
423 //________________________________________________________________________
424 Int_t AliVAnalysisMuon::GetNMCTracks()
427 /// Return the number of MC tracks in event
430 if ( fMCEvent ) nMCtracks = fMCEvent->GetNumberOfTracks();
431 else if ( fAODEvent ) {
432 TClonesArray* mcArray = (TClonesArray*)fAODEvent->GetList()->FindObject(AliAODMCParticle::StdBranchName());
433 if ( mcArray ) nMCtracks = mcArray->GetEntries();
438 //________________________________________________________________________
439 AliVParticle* AliVAnalysisMuon::GetMCTrack(Int_t trackLabel)
442 /// MC information can be provided by the MC input handler
443 /// (mostly when analyising ESDs) or can be found inside AODs
444 /// This method returns the correct one
446 AliVParticle* mcTrack = 0x0;
447 if ( fMCEvent ) mcTrack = fMCEvent->GetTrack(trackLabel);
448 else if ( fAODEvent ) {
449 TClonesArray* mcArray = (TClonesArray*)fAODEvent->FindListObject(AliAODMCParticle::StdBranchName());
450 if ( mcArray ) mcTrack = (AliVParticle*)mcArray->At(trackLabel);
452 if ( ! mcTrack ) AliWarning(Form("No track with label %i!", trackLabel));
456 //________________________________________________________________________
457 Bool_t AliVAnalysisMuon::IsMC()
462 return ( fMCEvent || ( fAODEvent && fAODEvent->FindListObject(AliAODMCParticle::StdBranchName()) ) );
466 //________________________________________________________________________
467 Int_t AliVAnalysisMuon::GetParticleType(AliVParticle* track)
470 /// Get particle type from mathced MC track
473 Int_t trackSrc = kUnidentified;
474 Int_t trackLabel = track->GetLabel();
475 if ( trackLabel >= 0 ) {
476 AliVParticle* matchedMCTrack = GetMCTrack(trackLabel);
477 if ( matchedMCTrack ) trackSrc = RecoTrackMother(matchedMCTrack);
478 } // track has MC label
483 //________________________________________________________________________
484 Int_t AliVAnalysisMuon::RecoTrackMother(AliVParticle* mcParticle)
487 /// Find track mother from kinematics
490 Int_t recoPdg = mcParticle->PdgCode();
492 // Track is not a muon
493 if ( TMath::Abs(recoPdg) != 13 ) return kRecoHadron;
495 Int_t imother = ( fMCEvent ) ? ((AliMCParticle*)mcParticle)->GetMother() : ((AliAODMCParticle*)mcParticle)->GetMother();
497 Int_t den[3] = {100, 1000, 1};
499 Int_t motherType = kDecayMu;
500 while ( imother >= 0 ) {
501 AliVParticle* part = GetMCTrack(imother);
502 //if ( ! part ) return motherType;
504 Int_t absPdg = TMath::Abs(part->PdgCode());
506 Bool_t isPrimary = ( fMCEvent ) ? ( imother < fMCEvent->GetNumberOfPrimaries() ) : ((AliAODMCParticle*)part)->IsPrimary();
509 for ( Int_t idec=0; idec<3; idec++ ) {
510 Int_t flv = (absPdg%100000)/den[idec];
511 if ( flv > 0 && flv < 4 ) return kDecayMu;
512 else if ( flv == 0 || flv > 5 ) continue;
514 if ( den[idec] == 100 ) motherType = kQuarkoniumMu;
515 else if ( flv == 4 ) motherType = kCharmMu;
516 else motherType = kBeautyMu;
517 break; // break loop on pdg code
518 // but continue the global loop to find higher mass HF
520 } // loop on pdg code
521 if ( absPdg < 10 ) break; // particle loop
524 if ( part->Zv() < -90. ) {
525 // If hadronic process => secondary
526 //if ( part->GetUniqueID() == kPHadronic ) {
532 imother = ( fMCEvent ) ? ((AliMCParticle*)part)->GetMother() : ((AliAODMCParticle*)part)->GetMother();
539 //________________________________________________________________________
540 Bool_t AliVAnalysisMuon::AddObjectToCollection(TObject* object, Int_t index)
543 /// Add object to collection
546 if ( ! fOutputPrototypeList ) {
547 fOutputPrototypeList = new TObjArray();
548 fOutputPrototypeList->SetOwner();
550 if ( fOutputPrototypeList->FindObject(object->GetName() ) ) {
551 AliWarning(Form("Object with name %s already in the list", object->GetName()));
554 if ( index < 0 ) fOutputPrototypeList->Add(object);
555 else fOutputPrototypeList->AddAtAndExpand(object, index);
560 //________________________________________________________________________
561 TObject* AliVAnalysisMuon::GetMergeableObject(TString physSel, TString trigClassName, TString centrality, TString objectName)
564 /// Get mergeable object
565 /// (create collection if necessary)
568 TString identifier = Form("/%s/%s/%s/", physSel.Data(), trigClassName.Data(), centrality.Data());
570 TObject* obj = fMergeableCollection->GetObject(identifier.Data(), objectName.Data());
572 CreateMergeableObjects(physSel, trigClassName, centrality);
573 obj = fMergeableCollection->GetObject(identifier.Data(), objectName.Data());
574 AliInfo(Form("Mergeable object collection size %g MB", fMergeableCollection->EstimateSize()/1024.0/1024.0));
579 //________________________________________________________________________
580 TObject* AliVAnalysisMuon::GetSum(TString physSel, TString trigClassNames, TString centrality, TString objectPattern)
584 /// - physSel, trigClassNames must be in the form: key1,key2
585 /// - centrality must be in the form minValue_maxValue
586 /// - objectPattern must be in the form match1&match2&match3,match4
587 /// meaning that the object name must contain match1 and match2 and either one of match3 and match4
589 if ( ! fMergeableCollection ) return 0x0;
591 // Get centrality range
592 Int_t firstCentrality = 1;
593 Int_t lastCentrality = fCentralityClasses->GetNbins();
595 TObjArray* centralityRange = centrality.Tokenize("_");
596 Float_t range[2] = {0., 100.};
597 if ( centralityRange->GetEntries() >= 2 ) {
598 for ( Int_t irange=0; irange<2; ++irange ) {
599 range[irange] = ((TObjString*)centralityRange->At(irange))->GetString().Atof();
601 firstCentrality = fCentralityClasses->FindBin(range[0]+0.0001);
602 lastCentrality = fCentralityClasses->FindBin(range[1]-0.0001);
604 delete centralityRange;
606 TString sumCentralityString = "";
607 for ( Int_t icent=firstCentrality; icent<=lastCentrality; ++icent ) {
608 if ( ! sumCentralityString.IsNull() ) sumCentralityString += ",";
609 sumCentralityString += fCentralityClasses->GetBinLabel(icent);
612 objectPattern.ReplaceAll(" ","");
613 TObjArray* objPatternList = objectPattern.Tokenize("&");
614 TObjArray objPatternMatrix(objPatternList->GetEntries());
615 objPatternMatrix.SetOwner();
616 for ( Int_t ikey=0; ikey<objPatternList->GetEntries(); ikey++ ) {
617 TObjArray* subKeyList = ((TObjString*)objPatternList->At(ikey))->GetString().Tokenize(",");
618 objPatternMatrix.AddAt(subKeyList, ikey);
620 delete objPatternList;
623 TObjArray objectNameInCollection;
624 objectNameInCollection.SetOwner();
625 TObjArray* physSelList = physSel.Tokenize(",");
626 TObjArray* trigClassList = trigClassNames.Tokenize(",");
627 TObjArray* centralityList = sumCentralityString.Tokenize(",");
628 for ( Int_t isel=0; isel<physSelList->GetEntries(); isel++ ) {
629 for ( Int_t itrig = 0; itrig<trigClassList->GetEntries(); itrig++ ) {
630 for ( Int_t icent=0; icent<centralityList->GetEntries(); icent++ ) {
631 TString currId = Form("/%s/%s/%s/", physSelList->At(isel)->GetName(), trigClassList->At(itrig)->GetName(),centralityList->At(icent)->GetName());
632 TList* objNameList = fMergeableCollection->CreateListOfObjectNames(currId.Data());
633 for ( Int_t iobj=0; iobj<objNameList->GetEntries(); iobj++ ) {
634 TString objName = objNameList->At(iobj)->GetName();
635 if ( ! objectNameInCollection.FindObject(objName.Data()) ) objectNameInCollection.Add(new TObjString(objName.Data()));
642 delete trigClassList;
643 delete centralityList;
645 TString matchingObjectNames = "";
646 for ( Int_t iobj=0; iobj<objectNameInCollection.GetEntries(); iobj++ ) {
647 TString objName = objectNameInCollection.At(iobj)->GetName();
648 Bool_t matchAnd = kTRUE;
649 for ( Int_t ikey=0; ikey<objPatternMatrix.GetEntries(); ikey++ ) {
650 TObjArray* subKeyList = (TObjArray*)objPatternMatrix.At(ikey);
651 Bool_t matchOr = kFALSE;
652 for ( Int_t isub=0; isub<subKeyList->GetEntries(); isub++ ) {
653 TString subKeyString = ((TObjString*)subKeyList->At(isub))->GetString();
654 if ( objName.Contains(subKeyString.Data()) ) {
664 if ( ! matchAnd ) continue;
665 if ( ! matchingObjectNames.IsNull() ) matchingObjectNames.Append(",");
666 matchingObjectNames += objName;
669 TString idPattern = Form("/%s/%s/%s/%s", physSel.Data(), trigClassNames.Data(), sumCentralityString.Data(), matchingObjectNames.Data());
670 idPattern.ReplaceAll(" ","");
672 AliDebug(1,Form("Sum pattern %s", idPattern.Data()));
674 return fMergeableCollection->GetSum(idPattern.Data());
677 //___________________________________________________________________________
678 void AliVAnalysisMuon::CreateMergeableObjects(TString physSel, TString trigClassName, TString centrality)
681 TString objectName = "";
682 TString identifier = Form("/%s/%s/%s/", physSel.Data(), trigClassName.Data(), centrality.Data());
683 for ( Int_t iobj=0; iobj<fOutputPrototypeList->GetEntries(); ++iobj ) {
684 objectName = fOutputPrototypeList->At(iobj)->GetName();
685 obj = fOutputPrototypeList->At(iobj)->Clone(objectName.Data());
686 fMergeableCollection->Adopt(identifier, obj);
691 //_______________________________________________________________________
692 Bool_t AliVAnalysisMuon::SetSparseRange(AliCFGridSparse* gridSparse,
693 Int_t ivar, TString labelName,
694 Double_t varMin, Double_t varMax,
698 /// Set range in a smart way.
699 /// Allows to select a bin from the label.
700 /// Check the bin limits.
704 Int_t minVarBin = -1, maxVarBin = -1;
705 TAxis* axis = gridSparse->GetAxis(ivar);
708 printf("Warning: Axis %i not found in %s", ivar, gridSparse->GetName());
712 if ( ! labelName.IsNull() ) {
713 minVarBin = axis->FindBin(labelName.Data());
714 maxVarBin = minVarBin;
715 if ( minVarBin < 1 ) {
716 printf("Warning: %s: label %s not found. Nothing done", gridSparse->GetName(), labelName.Data());
720 else if ( option.Contains( "USEBIN" ) ) {
721 minVarBin = (Int_t)varMin;
722 maxVarBin = (Int_t)varMax;
725 minVarBin = axis->FindBin(varMin);
726 maxVarBin = axis->FindBin(varMax);
729 if ( axis->GetFirst() == minVarBin && axis->GetLast() == maxVarBin ) return kFALSE;
731 gridSparse->SetRangeUser(ivar, axis->GetBinCenter(minVarBin), axis->GetBinCenter(maxVarBin));
736 //________________________________________________________________________
737 void AliVAnalysisMuon::SetTrigClassPatterns(TString pattern)
739 /// Set trigger classes
741 /// Classes are filled dynamically according to the pattern
742 /// - if name contains ! (without spaces): reject it
743 /// - in the matching pattern it is also possible to specify the
744 /// pt cut level associated to the trigger
746 /// SetTrigClassPatterns("CMBAC CPBI1MSL:Lpt CPBI1MSH:Hpt !ALLNOTRD")
747 /// keeps classes containing CMBAC, CPBI1MSL and CPBI1MSH and not containing ALLNOTRD.
748 /// In addition, it knows that the class matching CPBI1MSL requires an Lpt trigger
749 /// and the one with CPBI1MSH requires a Hpt trigger.
750 /// Hence, in the analysis, the function
751 /// TrackPtCutMatchTrigClass(track, "CPBIMSL") returns true if track match Lpt
752 /// TrackPtCutMatchTrigClass(track, "CPBIMSL") returns true if track match Hpt
753 /// TrackPtCutMatchTrigClass(track, "CMBAC") always returns true
755 /// CAVEAT: if you use an fCFContainer and you want an axis to contain the trigger classes,
756 /// please be sure that each pattern matches only 1 trigger class, or triggers will be mixed up
757 /// when merging different chuncks.
759 fSelectedTrigPattern->SetOwner();
760 if ( fSelectedTrigPattern->GetEntries() > 0 ) fSelectedTrigPattern->Delete();
761 fRejectedTrigPattern->SetOwner();
762 if ( fRejectedTrigPattern->GetEntries() > 0 ) fRejectedTrigPattern->Delete();
763 fSelectedTrigLevel->SetOwner();
764 if ( fSelectedTrigLevel->GetEntries() > 0 ) fSelectedTrigLevel->Delete();
766 pattern.ReplaceAll(" "," ");
767 pattern.ReplaceAll("! ","!");
768 pattern.ReplaceAll(" :",":");
770 TObjArray* fullList = pattern.Tokenize(" ");
772 for ( Int_t ipat=0; ipat<fullList->GetEntries(); ++ipat ) {
773 TString currPattern = fullList->At(ipat)->GetName();
774 if ( currPattern.Contains("!") ) {
775 currPattern.ReplaceAll("!","");
776 fRejectedTrigPattern->AddLast(new TObjString(currPattern));
779 TObjArray* arr = currPattern.Tokenize(":");
780 fSelectedTrigPattern->AddLast(new TObjString(arr->At(0)->GetName()));
781 TString selTrigLevel = ( arr->At(1) ) ? arr->At(1)->GetName() : "none";
782 selTrigLevel.ToUpper();
783 fSelectedTrigLevel->AddLast(new TObjString(selTrigLevel));
791 //________________________________________________________________________
792 void AliVAnalysisMuon::SetCentralityClasses(Int_t nCentralityBins, Double_t* centralityBins)
795 /// Set centrality classes
797 Double_t* bins = centralityBins;
798 Int_t nbins = nCentralityBins;
800 Double_t defaultCentralityBins[] = {-5., 0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 100., 105.};
801 if ( ! centralityBins ) {
802 bins = defaultCentralityBins;
803 nbins = sizeof(defaultCentralityBins)/sizeof(defaultCentralityBins[0])-1;
806 if ( fCentralityClasses ) delete fCentralityClasses;
807 fCentralityClasses = new TAxis(nbins, bins);
808 TString currClass = "";
809 for ( Int_t ibin=1; ibin<=fCentralityClasses->GetNbins(); ++ibin ){
810 currClass = Form("%.0f_%.0f",fCentralityClasses->GetBinLowEdge(ibin),fCentralityClasses->GetBinUpEdge(ibin));
811 fCentralityClasses->SetBinLabel(ibin, currClass.Data());
815 //________________________________________________________________________
816 void AliVAnalysisMuon::SetTerminateOptions(TString physSel, TString trigClass, TString centralityRange, TString furtherOpts)
819 /// Set terminate options
821 if ( ! fTerminateOptions ) {
822 fTerminateOptions = new TObjArray(4);
823 fTerminateOptions->SetOwner();
825 fTerminateOptions->AddAt(new TObjString(physSel), 0);
826 fTerminateOptions->AddAt(new TObjString(trigClass), 1);
827 fTerminateOptions->AddAt(new TObjString(centralityRange),2);
828 fTerminateOptions->AddLast(new TObjString(furtherOpts));
831 //________________________________________________________________________
832 void AliVAnalysisMuon::InitKeys()
834 TString chargeKeys = "MuMinus MuPlus";
835 fChargeKeys = chargeKeys.Tokenize(" ");
837 TString srcKeys = "CharmMu BeautyMu QuarkoniumMu DecayMu SecondaryMu Hadron Unidentified";
838 fSrcKeys = srcKeys.Tokenize(" ");
840 TString physSelKeys = "PhysSelPass PhysSelReject";
841 fPhysSelKeys = physSelKeys.Tokenize(" ");
844 //________________________________________________________________________
845 TObjArray* AliVAnalysisMuon::BuildTriggerClasses(TString firedTrigClasses)
848 /// Return the list of trigger classes to be considered
849 /// for current event. Update the global list if necessary
852 TObjArray* selectedTrigClasses = new TObjArray(0);
853 selectedTrigClasses->SetOwner();
855 TObjArray* firedTrigClassesList = firedTrigClasses.Tokenize(" ");
857 for ( Int_t itrig=0; itrig<firedTrigClassesList->GetEntries(); ++itrig ) {
858 TString trigName = ((TObjString*)firedTrigClassesList->At(itrig))->GetString();
859 Bool_t rejectTrig = kFALSE;
860 for ( Int_t ipat=0; ipat<fRejectedTrigPattern->GetEntries(); ++ipat ) {
861 if ( trigName.Contains(fRejectedTrigPattern->At(ipat)->GetName() ) ) {
865 } // loop on reject pattern
866 if ( rejectTrig ) continue;
868 Int_t matchPatternIndex = -1;
869 for ( Int_t ipat=0; ipat<fSelectedTrigPattern->GetEntries(); ++ipat ) {
870 if ( trigName.Contains(fSelectedTrigPattern->At(ipat)->GetName() ) ) {
871 matchPatternIndex = ipat;
874 } // loop on keep pattern
875 if ( matchPatternIndex < 0 ) continue;
877 selectedTrigClasses->AddLast(new TObjString(trigName));
878 if ( fTriggerClasses->FindObject(trigName.Data()) ) continue;
880 TString trigLevelString = fSelectedTrigLevel->At(matchPatternIndex)->GetName();
881 if ( trigLevelString.Contains("APT") ) trigLevel = 1;
882 else if ( trigLevelString.Contains("LPT") ) trigLevel = 2;
883 else if ( trigLevelString.Contains("HPT") ) trigLevel = 3;
884 AliInfo(Form("Adding %s to considered trigger classes",trigName.Data()));
885 TObjString* addTrig = new TObjString(trigName);
886 UInt_t uniqueId = trigLevel;
887 addTrig->SetUniqueID(uniqueId);
888 fTriggerClasses->Add(addTrig);
889 } // loop on trigger classes
891 delete firedTrigClassesList;
893 return selectedTrigClasses;
897 //________________________________________________________________________
898 Bool_t AliVAnalysisMuon::TrackPtCutMatchTrigClass(AliVParticle* track, TString trigClassName)
900 /// Check if track passes the trigger pt cut level used in the trigger class
901 Int_t matchTrig = ( fAODEvent ) ? ((AliAODTrack*)track)->GetMatchTrigger() : ((AliESDMuonTrack*)track)->GetMatchTrigger();
902 Int_t classMatchLevel = GetTrigClassPtCutLevel(trigClassName);
903 return matchTrig >= classMatchLevel;
907 //________________________________________________________________________
908 Int_t AliVAnalysisMuon::GetTrigClassPtCutLevel(TString trigClassName)
910 /// Get trigger class pt cut level for tracking/trigger matching
911 TObject* obj = fTriggerClasses->FindObject(trigClassName.Data());
913 AliWarning(Form("Class %s not in the list!", trigClassName.Data()));
917 return obj->GetUniqueID();