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: AliAnalysisMuonUtility.cxx 47782 2011-02-24 18:37:31Z martinez $ */
18 //-----------------------------------------------------------------------------
19 /// \class AliAnalysisMuonUtility
20 /// Static tilities for muon analysis
21 /// The class allows to treat AODs and ESDs
22 /// as well as MC AODs and MC in a transparent way
24 /// \author Diego Stocco
25 //-----------------------------------------------------------------------------
27 #include "AliAnalysisMuonUtility.h"
32 #include "TLorentzVector.h"
35 #include "AliAODEvent.h"
36 #include "AliAODTrack.h"
37 #include "AliAODMCParticle.h"
38 #include "AliMCEvent.h"
39 #include "AliMCParticle.h"
40 #include "AliESDEvent.h"
41 #include "AliESDMuonTrack.h"
42 #include "AliVVertex.h"
43 #include "AliAODMCHeader.h"
47 #include "AliCFGridSparse.h"
50 ClassImp(AliAnalysisMuonUtility) // Class implementation in ROOT context
54 //________________________________________________________________________
55 Bool_t AliAnalysisMuonUtility::IsAODEvent ( const AliVEvent* event )
57 /// Check if event is from ESD or AOD
58 return ( event->IsA() == AliAODEvent::Class() );
61 //________________________________________________________________________
62 Bool_t AliAnalysisMuonUtility::IsAODTrack ( const AliVParticle* track )
64 /// Check if track is from ESD or AOD
65 return ( track->IsA() == AliAODTrack::Class() );
68 //________________________________________________________________________
69 Bool_t AliAnalysisMuonUtility::IsMuonTrack ( const AliVParticle* track )
71 /// Check if track has muon tracker info
72 return ( IsAODTrack(track) ) ? static_cast<const AliAODTrack*>(track)->IsMuonTrack() : static_cast<const AliESDMuonTrack*>(track)->ContainTrackerData();
75 //________________________________________________________________________
76 Bool_t AliAnalysisMuonUtility::IsMuonGhost ( const AliVParticle* track )
78 /// Check if track has trigger info
79 return ( IsAODTrack(track) ) ? kFALSE : ( ! static_cast<const AliESDMuonTrack*>(track)->ContainTrackerData() );
82 //________________________________________________________________________
83 Double_t AliAnalysisMuonUtility::GetRabs ( const AliVParticle* track )
86 return ( IsAODTrack(track) ) ? static_cast<const AliAODTrack*>(track)->GetRAtAbsorberEnd() : static_cast<const AliESDMuonTrack*>(track)->GetRAtAbsorberEnd();
89 //________________________________________________________________________
90 Double_t AliAnalysisMuonUtility::GetThetaAbsDeg ( const AliVParticle* track )
92 /// Get Theta at absorber end (in deg)
93 return TMath::ATan( GetRabs(track) / 505. ) * TMath::RadToDeg();
96 //________________________________________________________________________
97 Int_t AliAnalysisMuonUtility::GetMatchTrigger ( const AliVParticle* track )
100 return IsAODTrack(track) ? static_cast<const AliAODTrack*>(track)->GetMatchTrigger() : static_cast<const AliESDMuonTrack*>(track)->GetMatchTrigger();
103 //________________________________________________________________________
104 Double_t AliAnalysisMuonUtility::GetChi2perNDFtracker ( const AliVParticle* track )
106 /// Get Theta at absorber end (in deg)
107 return IsAODTrack(track) ? static_cast<const AliAODTrack*>(track)->Chi2perNDF() : static_cast<const AliESDMuonTrack*>(track)->GetNormalizedChi2();
110 //________________________________________________________________________
111 Double_t AliAnalysisMuonUtility::GetXatVertex ( const AliVParticle* track )
115 if ( IsAODTrack(track) ) {
117 static_cast<const AliAODTrack*>(track)->GetXYZ(vtxPos);
120 else coor = static_cast<const AliESDMuonTrack*>(track)->GetNonBendingCoor();
125 //________________________________________________________________________
126 Double_t AliAnalysisMuonUtility::GetYatVertex ( const AliVParticle* track )
130 if ( IsAODTrack(track) ) {
132 static_cast<const AliAODTrack*>(track)->GetXYZ(vtxPos);
135 else coor = static_cast<const AliESDMuonTrack*>(track)->GetBendingCoor();
140 //________________________________________________________________________
141 Double_t AliAnalysisMuonUtility::GetZatVertex ( const AliVParticle* track )
145 if ( IsAODTrack(track) ) {
147 static_cast<const AliAODTrack*>(track)->GetXYZ(vtxPos);
150 else coor = static_cast<const AliESDMuonTrack*>(track)->GetZ();
155 //________________________________________________________________________
156 Double_t AliAnalysisMuonUtility::GetXatDCA ( const AliVParticle* track )
159 return IsAODTrack(track) ? static_cast<const AliAODTrack*>(track)->XAtDCA() : static_cast<const AliESDMuonTrack*>(track)->GetNonBendingCoorAtDCA();
162 //________________________________________________________________________
163 Double_t AliAnalysisMuonUtility::GetYatDCA ( const AliVParticle* track )
166 return IsAODTrack(track) ? static_cast<const AliAODTrack*>(track)->YAtDCA() : static_cast<const AliESDMuonTrack*>(track)->GetBendingCoorAtDCA();
169 //________________________________________________________________________
170 UInt_t AliAnalysisMuonUtility::GetMUONTrigHitsMapTrk ( const AliVParticle* track )
172 /// Get hit pattern in trigger chambers from tracker track extrapolation
173 return ( IsAODTrack(track) ) ? const_cast<AliAODTrack*>(static_cast<const AliAODTrack*>(track))->GetMUONTrigHitsMapTrk() : static_cast<const AliESDMuonTrack*>(track)->GetHitsPatternInTrigChTrk();
176 //________________________________________________________________________
177 UInt_t AliAnalysisMuonUtility::GetMUONTrigHitsMapTrg ( const AliVParticle* track )
179 /// Get hit pattern in trigger chambers from tracker track extrapolation
180 return ( IsAODTrack(track) ) ? const_cast<AliAODTrack*>(static_cast<const AliAODTrack*>(track))->GetMUONTrigHitsMapTrg() : static_cast<const AliESDMuonTrack*>(track)->GetHitsPatternInTrigCh();
183 //________________________________________________________________________
184 TString AliAnalysisMuonUtility::GetFiredTriggerClasses ( const AliVEvent* event )
186 /// Check if track is from ESD or AOD
187 return ( IsAODEvent(event) ) ? static_cast<const AliAODEvent*>(event)->GetFiredTriggerClasses() : static_cast<const AliESDEvent*>(event)->GetFiredTriggerClasses();
190 //________________________________________________________________________
191 Int_t AliAnalysisMuonUtility::GetNTracks ( const AliVEvent* event )
194 /// Return the number of tracks in event
196 return ( IsAODEvent(event) ) ? static_cast<const AliAODEvent*>(event)->GetNTracks() : static_cast<const AliESDEvent*>(event)->GetNumberOfMuonTracks();
200 //________________________________________________________________________
201 AliVParticle* AliAnalysisMuonUtility::GetTrack ( Int_t itrack, const AliVEvent* event )
204 /// Get the current track
206 AliVParticle* track = 0x0;
207 if ( IsAODEvent(event) ) track = static_cast<const AliAODEvent*>(event)->GetTrack(itrack);
209 AliESDEvent* esdEvent = const_cast<AliESDEvent*>(static_cast<const AliESDEvent*> (event));
210 track = esdEvent->GetMuonTrack(itrack);
215 //________________________________________________________________________
216 Double_t AliAnalysisMuonUtility::MuonMass2()
218 /// A usefull constant
219 return 1.11636129640000012e-02;
222 //________________________________________________________________________
223 TLorentzVector AliAnalysisMuonUtility::GetTrackPair ( const AliVParticle* track1, const AliVParticle* track2 )
228 const AliVParticle* tracks[2] = {track1, track2};
230 TLorentzVector vec[2];
231 for ( Int_t itrack=0; itrack<2; ++itrack ) {
232 Double_t trackP = tracks[itrack]->P();
233 Double_t energy = TMath::Sqrt(trackP*trackP + MuonMass2());
234 vec[itrack].SetPxPyPzE(tracks[itrack]->Px(), tracks[itrack]->Py(), tracks[itrack]->Pz(), energy);
237 TLorentzVector vecPair = vec[0] + vec[1];
241 //________________________________________________________________________
242 Bool_t AliAnalysisMuonUtility::IsMCEvent ( const AliVEvent* event, const AliMCEvent* mcEvent )
247 return ( mcEvent || ( IsAODEvent(event) && static_cast<const AliAODEvent*>(event)->FindListObject(AliAODMCParticle::StdBranchName()) ) );
251 //________________________________________________________________________
252 Bool_t AliAnalysisMuonUtility::IsAODMCTrack( const AliVParticle* mcParticle )
254 /// Check if track is from AOD MC
255 return ( mcParticle->IsA() == AliAODMCParticle::Class() );
259 //________________________________________________________________________
260 Int_t AliAnalysisMuonUtility::GetNMCTracks ( const AliVEvent* event, const AliMCEvent* mcEvent )
263 /// Return the number of MC tracks in event
266 if ( mcEvent ) nMCtracks = mcEvent->GetNumberOfTracks();
267 else if ( IsAODEvent(event) ) {
268 TClonesArray* mcArray = (TClonesArray*)static_cast<const AliAODEvent*>(event)->GetList()->FindObject(AliAODMCParticle::StdBranchName());
269 if ( mcArray ) nMCtracks = mcArray->GetEntries();
274 //________________________________________________________________________
275 AliVParticle* AliAnalysisMuonUtility::GetMCTrack ( Int_t trackLabel, const AliVEvent* event, const AliMCEvent* mcEvent )
278 /// MC information can be provided by the MC input handler
279 /// (mostly when analyising ESDs) or can be found inside AODs
280 /// This method returns the correct one
282 AliVParticle* mcTrack = 0x0;
283 if ( mcEvent ) mcTrack = mcEvent->GetTrack(trackLabel);
284 else if ( IsAODEvent(event) ) {
285 TClonesArray* mcArray = (TClonesArray*)static_cast<const AliAODEvent*>(event)->FindListObject(AliAODMCParticle::StdBranchName());
286 if ( mcArray ) mcTrack = (AliVParticle*)mcArray->At(trackLabel);
288 if ( ! mcTrack ) AliWarningClass(Form("No track with label %i!", trackLabel));
292 //________________________________________________________________________
293 Double_t AliAnalysisMuonUtility::GetMCVertexZ ( const AliVEvent* event, const AliMCEvent* mcEvent )
297 if ( mcEvent ) vz = mcEvent->GetPrimaryVertex()->GetZ();
298 else if ( IsAODEvent(event) ) {
299 AliAODMCHeader* aodMCHeader = static_cast<AliAODMCHeader*> (static_cast<const AliAODEvent*>(event)->FindListObject(AliAODMCHeader::StdBranchName()));
300 vz = aodMCHeader->GetVtxZ();
302 else AliErrorClass("No MC event found");
306 //________________________________________________________________________
307 Int_t AliAnalysisMuonUtility::GetMotherIndex ( const AliVParticle* mcParticle )
310 /// Return the mother index
312 return ( IsAODMCTrack(mcParticle) ) ? static_cast<const AliAODMCParticle*>(mcParticle)->GetMother() : static_cast<const AliMCParticle*>(mcParticle)->GetMother();
315 //________________________________________________________________________
316 Int_t AliAnalysisMuonUtility::GetDaughterIndex ( const AliVParticle* mcParticle, Int_t idaughter )
319 /// Return the daughter index
320 /// idaughter can be:
321 /// 0 -> first daughter
322 /// 1 -> last daughter
324 if ( idaughter < 0 || idaughter > 1 ) {
325 AliErrorClass(Form("Requested daughter %i Daughter index can be either 0 (first) or 1 (last)", idaughter));
329 if ( IsAODMCTrack(mcParticle) ) return static_cast<const AliAODMCParticle*>(mcParticle)->GetDaughter(idaughter);
331 if ( idaughter == 0 ) return static_cast<const AliMCParticle*>(mcParticle)->GetFirstDaughter();
332 else return static_cast<const AliMCParticle*>(mcParticle)->GetLastDaughter();
335 //________________________________________________________________________
336 Bool_t AliAnalysisMuonUtility::IsPrimary ( const AliVParticle* mcParticle, const AliMCEvent* mcEvent )
338 /// Check if the particle is primary
340 Bool_t isPrimary = kFALSE;
342 // First get the index of the current particle in the stack.
343 // For this: get the mother, and get its daughter.
344 // Since the mother can have many daughters, you can come up to a "sister"
345 // of the particle. Nevertheless, if it is primary, then also the particle itself should be.
346 Int_t imother = static_cast<const AliMCParticle*> (mcParticle)->GetMother();
347 if ( imother < 0 ) isPrimary = kTRUE;
348 else if ( static_cast<const AliMCParticle*>(mcEvent->GetTrack(imother))->GetFirstDaughter() < const_cast<AliMCEvent*>(mcEvent)->GetNumberOfPrimaries() ) isPrimary = kTRUE;
350 else isPrimary = static_cast<const AliAODMCParticle*>(mcParticle)->IsPrimary();
355 //________________________________________________________________________
356 AliVVertex* AliAnalysisMuonUtility::GetVertexSPD ( const AliVEvent* event )
362 AliVVertex* primaryVertex = ( IsAODEvent(event) ) ? (AliVVertex*)static_cast<const AliAODEvent*>(event)->GetPrimaryVertexSPD() : (AliVVertex*)static_cast<const AliESDEvent*>(event)->GetPrimaryVertexSPD();
363 return primaryVertex;
367 //_______________________________________________________________________
368 Bool_t AliAnalysisMuonUtility::SetSparseRange(AliCFGridSparse* gridSparse,
369 Int_t ivar, TString labelName,
370 Double_t varMin, Double_t varMax,
374 /// Set range in a smart way.
375 /// Allows to select a bin from the label.
376 /// Check the bin limits.
380 Int_t minVarBin = -1, maxVarBin = -1;
381 TAxis* axis = gridSparse->GetAxis(ivar);
384 printf("Warning: Axis %i not found in %s", ivar, gridSparse->GetName());
388 if ( ! labelName.IsNull() ) {
389 minVarBin = axis->FindBin(labelName.Data());
390 maxVarBin = minVarBin;
391 if ( minVarBin < 1 ) {
392 printf("Warning: %s: label %s not found. Nothing done", gridSparse->GetName(), labelName.Data());
396 else if ( option.Contains( "USEBIN" ) ) {
397 minVarBin = (Int_t)varMin;
398 maxVarBin = (Int_t)varMax;
401 minVarBin = axis->FindBin(varMin);
402 maxVarBin = axis->FindBin(varMax);
405 if ( axis->GetFirst() == minVarBin && axis->GetLast() == maxVarBin ) return kFALSE;
407 gridSparse->SetRangeUser(ivar, axis->GetBinCenter(minVarBin), axis->GetBinCenter(maxVarBin));