]>
Commit | Line | Data |
---|---|---|
f8b94231 | 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: AliAnalysisMuonUtility.cxx 47782 2011-02-24 18:37:31Z martinez $ */ | |
17 | ||
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 | |
23 | /// | |
24 | /// \author Diego Stocco | |
25 | //----------------------------------------------------------------------------- | |
26 | ||
27 | #include "AliAnalysisMuonUtility.h" | |
28 | ||
29 | // ROOT includes | |
30 | #include "TAxis.h" | |
31 | #include "TMath.h" | |
32 | #include "TLorentzVector.h" | |
68e9b988 | 33 | #include "TFile.h" |
f8b94231 | 34 | |
35 | // STEER includes | |
68e9b988 | 36 | #include "AliInputEventHandler.h" |
37 | #include "AliAODHeader.h" | |
f8b94231 | 38 | #include "AliAODEvent.h" |
39 | #include "AliAODTrack.h" | |
68e9b988 | 40 | #include "AliAODMCHeader.h" |
f8b94231 | 41 | #include "AliAODMCParticle.h" |
42 | #include "AliMCEvent.h" | |
43 | #include "AliMCParticle.h" | |
44 | #include "AliESDEvent.h" | |
45 | #include "AliESDMuonTrack.h" | |
46 | #include "AliVVertex.h" | |
f8b94231 | 47 | #include "AliLog.h" |
48 | ||
49 | // CORRFW includes | |
50 | #include "AliCFGridSparse.h" | |
51 | ||
52 | /// \cond CLASSIMP | |
53 | ClassImp(AliAnalysisMuonUtility) // Class implementation in ROOT context | |
54 | /// \endcond | |
55 | ||
56 | ||
57 | //________________________________________________________________________ | |
58 | Bool_t AliAnalysisMuonUtility::IsAODEvent ( const AliVEvent* event ) | |
59 | { | |
60 | /// Check if event is from ESD or AOD | |
61 | return ( event->IsA() == AliAODEvent::Class() ); | |
62 | } | |
63 | ||
64 | //________________________________________________________________________ | |
65 | Bool_t AliAnalysisMuonUtility::IsAODTrack ( const AliVParticle* track ) | |
66 | { | |
67 | /// Check if track is from ESD or AOD | |
68 | return ( track->IsA() == AliAODTrack::Class() ); | |
69 | } | |
70 | ||
71 | //________________________________________________________________________ | |
72 | Bool_t AliAnalysisMuonUtility::IsMuonTrack ( const AliVParticle* track ) | |
73 | { | |
74 | /// Check if track has muon tracker info | |
75 | return ( IsAODTrack(track) ) ? static_cast<const AliAODTrack*>(track)->IsMuonTrack() : static_cast<const AliESDMuonTrack*>(track)->ContainTrackerData(); | |
76 | } | |
77 | ||
78 | //________________________________________________________________________ | |
79 | Bool_t AliAnalysisMuonUtility::IsMuonGhost ( const AliVParticle* track ) | |
80 | { | |
81 | /// Check if track has trigger info | |
82 | return ( IsAODTrack(track) ) ? kFALSE : ( ! static_cast<const AliESDMuonTrack*>(track)->ContainTrackerData() ); | |
83 | } | |
84 | ||
85 | //________________________________________________________________________ | |
86 | Double_t AliAnalysisMuonUtility::GetRabs ( const AliVParticle* track ) | |
87 | { | |
88 | /// Get Rabs | |
89 | return ( IsAODTrack(track) ) ? static_cast<const AliAODTrack*>(track)->GetRAtAbsorberEnd() : static_cast<const AliESDMuonTrack*>(track)->GetRAtAbsorberEnd(); | |
90 | } | |
91 | ||
92 | //________________________________________________________________________ | |
93 | Double_t AliAnalysisMuonUtility::GetThetaAbsDeg ( const AliVParticle* track ) | |
94 | { | |
95 | /// Get Theta at absorber end (in deg) | |
96 | return TMath::ATan( GetRabs(track) / 505. ) * TMath::RadToDeg(); | |
97 | } | |
98 | ||
99 | //________________________________________________________________________ | |
100 | Int_t AliAnalysisMuonUtility::GetMatchTrigger ( const AliVParticle* track ) | |
101 | { | |
102 | /// Get match trigger | |
103 | return IsAODTrack(track) ? static_cast<const AliAODTrack*>(track)->GetMatchTrigger() : static_cast<const AliESDMuonTrack*>(track)->GetMatchTrigger(); | |
104 | } | |
105 | ||
106 | //________________________________________________________________________ | |
107 | Double_t AliAnalysisMuonUtility::GetChi2perNDFtracker ( const AliVParticle* track ) | |
108 | { | |
109 | /// Get Theta at absorber end (in deg) | |
110 | return IsAODTrack(track) ? static_cast<const AliAODTrack*>(track)->Chi2perNDF() : static_cast<const AliESDMuonTrack*>(track)->GetNormalizedChi2(); | |
111 | } | |
112 | ||
113 | //________________________________________________________________________ | |
114 | Double_t AliAnalysisMuonUtility::GetXatVertex ( const AliVParticle* track ) | |
115 | { | |
116 | /// Get X at vertex | |
117 | Double_t coor = 0.; | |
118 | if ( IsAODTrack(track) ) { | |
119 | Double_t vtxPos[3]; | |
120 | static_cast<const AliAODTrack*>(track)->GetXYZ(vtxPos); | |
121 | coor = vtxPos[0]; | |
122 | } | |
123 | else coor = static_cast<const AliESDMuonTrack*>(track)->GetNonBendingCoor(); | |
124 | ||
125 | return coor; | |
126 | } | |
127 | ||
128 | //________________________________________________________________________ | |
129 | Double_t AliAnalysisMuonUtility::GetYatVertex ( const AliVParticle* track ) | |
130 | { | |
131 | /// Get Y at vertex | |
132 | Double_t coor = 0.; | |
133 | if ( IsAODTrack(track) ) { | |
134 | Double_t vtxPos[3]; | |
135 | static_cast<const AliAODTrack*>(track)->GetXYZ(vtxPos); | |
136 | coor = vtxPos[1]; | |
137 | } | |
138 | else coor = static_cast<const AliESDMuonTrack*>(track)->GetBendingCoor(); | |
139 | ||
140 | return coor; | |
141 | } | |
142 | ||
143 | //________________________________________________________________________ | |
144 | Double_t AliAnalysisMuonUtility::GetZatVertex ( const AliVParticle* track ) | |
145 | { | |
146 | /// Get Z at vertex | |
147 | Double_t coor = 0.; | |
148 | if ( IsAODTrack(track) ) { | |
149 | Double_t vtxPos[3]; | |
150 | static_cast<const AliAODTrack*>(track)->GetXYZ(vtxPos); | |
151 | coor = vtxPos[2]; | |
152 | } | |
153 | else coor = static_cast<const AliESDMuonTrack*>(track)->GetZ(); | |
154 | ||
155 | return coor; | |
156 | } | |
157 | ||
158 | //________________________________________________________________________ | |
159 | Double_t AliAnalysisMuonUtility::GetXatDCA ( const AliVParticle* track ) | |
160 | { | |
161 | /// Get X at DCA | |
162 | return IsAODTrack(track) ? static_cast<const AliAODTrack*>(track)->XAtDCA() : static_cast<const AliESDMuonTrack*>(track)->GetNonBendingCoorAtDCA(); | |
163 | } | |
164 | ||
165 | //________________________________________________________________________ | |
166 | Double_t AliAnalysisMuonUtility::GetYatDCA ( const AliVParticle* track ) | |
167 | { | |
168 | /// Get Y at DCA | |
169 | return IsAODTrack(track) ? static_cast<const AliAODTrack*>(track)->YAtDCA() : static_cast<const AliESDMuonTrack*>(track)->GetBendingCoorAtDCA(); | |
170 | } | |
171 | ||
172 | //________________________________________________________________________ | |
173 | UInt_t AliAnalysisMuonUtility::GetMUONTrigHitsMapTrk ( const AliVParticle* track ) | |
174 | { | |
175 | /// Get hit pattern in trigger chambers from tracker track extrapolation | |
176 | return ( IsAODTrack(track) ) ? const_cast<AliAODTrack*>(static_cast<const AliAODTrack*>(track))->GetMUONTrigHitsMapTrk() : static_cast<const AliESDMuonTrack*>(track)->GetHitsPatternInTrigChTrk(); | |
177 | } | |
178 | ||
179 | //________________________________________________________________________ | |
180 | UInt_t AliAnalysisMuonUtility::GetMUONTrigHitsMapTrg ( const AliVParticle* track ) | |
181 | { | |
182 | /// Get hit pattern in trigger chambers from tracker track extrapolation | |
183 | return ( IsAODTrack(track) ) ? const_cast<AliAODTrack*>(static_cast<const AliAODTrack*>(track))->GetMUONTrigHitsMapTrg() : static_cast<const AliESDMuonTrack*>(track)->GetHitsPatternInTrigCh(); | |
184 | } | |
185 | ||
186 | //________________________________________________________________________ | |
187 | TString AliAnalysisMuonUtility::GetFiredTriggerClasses ( const AliVEvent* event ) | |
188 | { | |
189 | /// Check if track is from ESD or AOD | |
190 | return ( IsAODEvent(event) ) ? static_cast<const AliAODEvent*>(event)->GetFiredTriggerClasses() : static_cast<const AliESDEvent*>(event)->GetFiredTriggerClasses(); | |
191 | } | |
192 | ||
193 | //________________________________________________________________________ | |
194 | Int_t AliAnalysisMuonUtility::GetNTracks ( const AliVEvent* event ) | |
195 | { | |
196 | // | |
197 | /// Return the number of tracks in event | |
198 | // | |
199 | return ( IsAODEvent(event) ) ? static_cast<const AliAODEvent*>(event)->GetNTracks() : static_cast<const AliESDEvent*>(event)->GetNumberOfMuonTracks(); | |
200 | } | |
201 | ||
202 | ||
203 | //________________________________________________________________________ | |
204 | AliVParticle* AliAnalysisMuonUtility::GetTrack ( Int_t itrack, const AliVEvent* event ) | |
205 | { | |
206 | // | |
207 | /// Get the current track | |
208 | // | |
209 | AliVParticle* track = 0x0; | |
210 | if ( IsAODEvent(event) ) track = static_cast<const AliAODEvent*>(event)->GetTrack(itrack); | |
211 | else { | |
212 | AliESDEvent* esdEvent = const_cast<AliESDEvent*>(static_cast<const AliESDEvent*> (event)); | |
213 | track = esdEvent->GetMuonTrack(itrack); | |
214 | } | |
215 | return track; | |
216 | } | |
217 | ||
218 | //________________________________________________________________________ | |
219 | Double_t AliAnalysisMuonUtility::MuonMass2() | |
220 | { | |
221 | /// A usefull constant | |
222 | return 1.11636129640000012e-02; | |
223 | } | |
224 | ||
225 | //________________________________________________________________________ | |
226 | TLorentzVector AliAnalysisMuonUtility::GetTrackPair ( const AliVParticle* track1, const AliVParticle* track2 ) | |
227 | { | |
228 | // | |
229 | /// Get track pair | |
230 | // | |
231 | const AliVParticle* tracks[2] = {track1, track2}; | |
232 | ||
233 | TLorentzVector vec[2]; | |
234 | for ( Int_t itrack=0; itrack<2; ++itrack ) { | |
235 | Double_t trackP = tracks[itrack]->P(); | |
236 | Double_t energy = TMath::Sqrt(trackP*trackP + MuonMass2()); | |
237 | vec[itrack].SetPxPyPzE(tracks[itrack]->Px(), tracks[itrack]->Py(), tracks[itrack]->Pz(), energy); | |
238 | } | |
239 | ||
240 | TLorentzVector vecPair = vec[0] + vec[1]; | |
241 | return vecPair; | |
242 | } | |
243 | ||
244 | //________________________________________________________________________ | |
245 | Bool_t AliAnalysisMuonUtility::IsMCEvent ( const AliVEvent* event, const AliMCEvent* mcEvent ) | |
246 | { | |
247 | // | |
248 | /// Contains MC info | |
249 | // | |
250 | return ( mcEvent || ( IsAODEvent(event) && static_cast<const AliAODEvent*>(event)->FindListObject(AliAODMCParticle::StdBranchName()) ) ); | |
251 | } | |
252 | ||
253 | ||
254 | //________________________________________________________________________ | |
255 | Bool_t AliAnalysisMuonUtility::IsAODMCTrack( const AliVParticle* mcParticle ) | |
256 | { | |
257 | /// Check if track is from AOD MC | |
258 | return ( mcParticle->IsA() == AliAODMCParticle::Class() ); | |
259 | } | |
260 | ||
261 | ||
262 | //________________________________________________________________________ | |
263 | Int_t AliAnalysisMuonUtility::GetNMCTracks ( const AliVEvent* event, const AliMCEvent* mcEvent ) | |
264 | { | |
265 | // | |
266 | /// Return the number of MC tracks in event | |
267 | // | |
268 | Int_t nMCtracks = 0; | |
269 | if ( mcEvent ) nMCtracks = mcEvent->GetNumberOfTracks(); | |
270 | else if ( IsAODEvent(event) ) { | |
271 | TClonesArray* mcArray = (TClonesArray*)static_cast<const AliAODEvent*>(event)->GetList()->FindObject(AliAODMCParticle::StdBranchName()); | |
272 | if ( mcArray ) nMCtracks = mcArray->GetEntries(); | |
273 | } | |
274 | return nMCtracks; | |
275 | } | |
276 | ||
277 | //________________________________________________________________________ | |
278 | AliVParticle* AliAnalysisMuonUtility::GetMCTrack ( Int_t trackLabel, const AliVEvent* event, const AliMCEvent* mcEvent ) | |
279 | { | |
280 | // | |
281 | /// MC information can be provided by the MC input handler | |
282 | /// (mostly when analyising ESDs) or can be found inside AODs | |
283 | /// This method returns the correct one | |
284 | // | |
285 | AliVParticle* mcTrack = 0x0; | |
286 | if ( mcEvent ) mcTrack = mcEvent->GetTrack(trackLabel); | |
287 | else if ( IsAODEvent(event) ) { | |
288 | TClonesArray* mcArray = (TClonesArray*)static_cast<const AliAODEvent*>(event)->FindListObject(AliAODMCParticle::StdBranchName()); | |
289 | if ( mcArray ) mcTrack = (AliVParticle*)mcArray->At(trackLabel); | |
290 | } | |
291 | if ( ! mcTrack ) AliWarningClass(Form("No track with label %i!", trackLabel)); | |
292 | return mcTrack; | |
293 | } | |
294 | ||
295 | //________________________________________________________________________ | |
296 | Double_t AliAnalysisMuonUtility::GetMCVertexZ ( const AliVEvent* event, const AliMCEvent* mcEvent ) | |
297 | { | |
298 | /// Get MC vertex Z | |
299 | Double_t vz = 0.; | |
300 | if ( mcEvent ) vz = mcEvent->GetPrimaryVertex()->GetZ(); | |
301 | else if ( IsAODEvent(event) ) { | |
302 | AliAODMCHeader* aodMCHeader = static_cast<AliAODMCHeader*> (static_cast<const AliAODEvent*>(event)->FindListObject(AliAODMCHeader::StdBranchName())); | |
303 | vz = aodMCHeader->GetVtxZ(); | |
304 | } | |
305 | else AliErrorClass("No MC event found"); | |
306 | return vz; | |
307 | } | |
308 | ||
309 | //________________________________________________________________________ | |
310 | Int_t AliAnalysisMuonUtility::GetMotherIndex ( const AliVParticle* mcParticle ) | |
311 | { | |
312 | // | |
313 | /// Return the mother index | |
314 | // | |
315 | return ( IsAODMCTrack(mcParticle) ) ? static_cast<const AliAODMCParticle*>(mcParticle)->GetMother() : static_cast<const AliMCParticle*>(mcParticle)->GetMother(); | |
316 | } | |
317 | ||
318 | //________________________________________________________________________ | |
319 | Int_t AliAnalysisMuonUtility::GetDaughterIndex ( const AliVParticle* mcParticle, Int_t idaughter ) | |
320 | { | |
321 | // | |
322 | /// Return the daughter index | |
323 | /// idaughter can be: | |
324 | /// 0 -> first daughter | |
325 | /// 1 -> last daughter | |
326 | // | |
327 | if ( idaughter < 0 || idaughter > 1 ) { | |
328 | AliErrorClass(Form("Requested daughter %i Daughter index can be either 0 (first) or 1 (last)", idaughter)); | |
329 | return -1; | |
330 | } | |
331 | ||
332 | if ( IsAODMCTrack(mcParticle) ) return static_cast<const AliAODMCParticle*>(mcParticle)->GetDaughter(idaughter); | |
333 | ||
334 | if ( idaughter == 0 ) return static_cast<const AliMCParticle*>(mcParticle)->GetFirstDaughter(); | |
335 | else return static_cast<const AliMCParticle*>(mcParticle)->GetLastDaughter(); | |
336 | } | |
337 | ||
338 | //________________________________________________________________________ | |
339 | Bool_t AliAnalysisMuonUtility::IsPrimary ( const AliVParticle* mcParticle, const AliMCEvent* mcEvent ) | |
340 | { | |
341 | /// Check if the particle is primary | |
342 | ||
343 | Bool_t isPrimary = kFALSE; | |
344 | if ( mcEvent ) { | |
345 | // First get the index of the current particle in the stack. | |
346 | // For this: get the mother, and get its daughter. | |
347 | // Since the mother can have many daughters, you can come up to a "sister" | |
348 | // of the particle. Nevertheless, if it is primary, then also the particle itself should be. | |
349 | Int_t imother = static_cast<const AliMCParticle*> (mcParticle)->GetMother(); | |
350 | if ( imother < 0 ) isPrimary = kTRUE; | |
351 | else if ( static_cast<const AliMCParticle*>(mcEvent->GetTrack(imother))->GetFirstDaughter() < const_cast<AliMCEvent*>(mcEvent)->GetNumberOfPrimaries() ) isPrimary = kTRUE; | |
352 | } | |
353 | else isPrimary = static_cast<const AliAODMCParticle*>(mcParticle)->IsPrimary(); | |
354 | return isPrimary; | |
355 | } | |
356 | ||
357 | ||
358 | //________________________________________________________________________ | |
359 | AliVVertex* AliAnalysisMuonUtility::GetVertexSPD ( const AliVEvent* event ) | |
360 | { | |
361 | // | |
362 | /// Get vertex SPD | |
363 | // | |
364 | ||
365 | AliVVertex* primaryVertex = ( IsAODEvent(event) ) ? (AliVVertex*)static_cast<const AliAODEvent*>(event)->GetPrimaryVertexSPD() : (AliVVertex*)static_cast<const AliESDEvent*>(event)->GetPrimaryVertexSPD(); | |
366 | return primaryVertex; | |
367 | } | |
368 | ||
369 | ||
68e9b988 | 370 | //________________________________________________________________________ |
371 | Int_t AliAnalysisMuonUtility::GetPassNumber ( const AliInputEventHandler* eventHandler ) | |
372 | { | |
373 | /// Get pass number from event | |
374 | ||
375 | // At present there is no straightforward way to get the pass number. | |
376 | // The pass number is usually written in the path to the ESDs/AODs | |
377 | // but this won't work for: | |
378 | // - MC data (no pass info available) | |
379 | // - local ESDs/AODs | |
380 | ||
381 | TString filePath = ""; | |
382 | const AliVEvent* event = eventHandler->GetEvent(); | |
383 | if ( IsAODEvent(event) ) { | |
384 | // In AODs, the header contains the path to the input ESD event | |
385 | // However, sometimes there is not the FULL path of the ESDs. | |
386 | // In that case we cannot extract the pass number. | |
387 | // To increase the possibility of getting the pass number, | |
388 | // try first to find the info in the AOD header | |
389 | // (which is a priori safer because it works even on local copies of AODs) | |
390 | // and if it does not work, directly check the path to the AOD | |
391 | filePath = static_cast<const AliAODEvent*> (event)->GetHeader()->GetESDFileName(); | |
392 | Int_t passNumber = GetPassNumber(filePath.Data()); | |
393 | if ( passNumber < 0 ) AliWarningClass("Check again with the AOD path"); | |
394 | else return passNumber; | |
395 | } | |
396 | ||
397 | filePath = eventHandler->GetTree()->GetCurrentFile()->GetName(); | |
398 | return GetPassNumber(filePath.Data()); | |
399 | } | |
400 | ||
401 | ||
402 | //________________________________________________________________________ | |
403 | Int_t AliAnalysisMuonUtility::GetPassNumber ( const char* str ) | |
404 | { | |
405 | // | |
406 | /// Get pass number from string | |
407 | // | |
408 | ||
409 | TString currName(str); | |
410 | currName.ToUpper(); | |
411 | Int_t idx = currName.Index("PASS"); | |
412 | if ( idx >= 0 ) { | |
413 | // Remove all of the words before PASS (and remove the word PASS itself) | |
414 | currName.Remove(0,idx+4); | |
415 | // Cut the word from the end untill only the digits are left | |
416 | // (In this way we can extract the pass number even if it has more than one digit) | |
417 | while ( ! currName.IsDigit() && currName.Length() > 0 ) { | |
418 | currName.Remove(currName.Length()-1); | |
419 | } | |
420 | ||
421 | if ( currName.Length() > 0 ) return currName.Atoi(); | |
422 | } | |
423 | ||
424 | AliWarningClass(Form("Cannot find pass number in: %s", str)); | |
425 | return -1; | |
426 | } | |
427 | ||
428 | ||
f8b94231 | 429 | //_______________________________________________________________________ |
430 | Bool_t AliAnalysisMuonUtility::SetSparseRange(AliCFGridSparse* gridSparse, | |
431 | Int_t ivar, TString labelName, | |
432 | Double_t varMin, Double_t varMax, | |
433 | TString option) | |
434 | { | |
435 | // | |
436 | /// Set range in a smart way. | |
437 | /// Allows to select a bin from the label. | |
438 | /// Check the bin limits. | |
439 | // | |
440 | ||
441 | option.ToUpper(); | |
442 | Int_t minVarBin = -1, maxVarBin = -1; | |
443 | TAxis* axis = gridSparse->GetAxis(ivar); | |
444 | ||
445 | if ( ! axis ) { | |
446 | printf("Warning: Axis %i not found in %s", ivar, gridSparse->GetName()); | |
447 | return kFALSE; | |
448 | } | |
449 | ||
450 | if ( ! labelName.IsNull() ) { | |
451 | minVarBin = axis->FindBin(labelName.Data()); | |
452 | maxVarBin = minVarBin; | |
453 | if ( minVarBin < 1 ) { | |
454 | printf("Warning: %s: label %s not found. Nothing done", gridSparse->GetName(), labelName.Data()); | |
455 | return kFALSE; | |
456 | } | |
457 | } | |
458 | else if ( option.Contains( "USEBIN" ) ) { | |
459 | minVarBin = (Int_t)varMin; | |
460 | maxVarBin = (Int_t)varMax; | |
461 | } | |
462 | else { | |
463 | minVarBin = axis->FindBin(varMin); | |
464 | maxVarBin = axis->FindBin(varMax); | |
465 | } | |
466 | ||
467 | if ( axis->GetFirst() == minVarBin && axis->GetLast() == maxVarBin ) return kFALSE; | |
468 | ||
469 | gridSparse->SetRangeUser(ivar, axis->GetBinCenter(minVarBin), axis->GetBinCenter(maxVarBin)); | |
470 | ||
471 | return kTRUE; | |
472 | } |