1 /**************************************************************************
2 * Copyright(c) 1998-1999, 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 **************************************************************************/
18 #include "AliAnalysisMuMuFromAOD.h"
20 #include "AliAODEvent.h"
21 #include "AliAODHeader.h"
22 #include "AliAODMCHeader.h"
23 #include "AliAODMCParticle.h"
24 #include "AliAODTrack.h"
25 #include "AliAnalysisManager.h"
26 #include "AliCentrality.h"
27 #include "AliCodeTimer.h"
28 #include "AliCounterCollection.h"
29 #include "AliHistogramCollection.h"
31 #include "AliMCEvent.h"
32 #include "AliVParticle.h"
33 #include "Riostream.h"
35 #include "TDatabasePDG.h"
36 #include "TDirectory.h"
39 #include "THashList.h"
40 #include "TLorentzVector.h"
43 #include "TObjArray.h"
44 #include "TPaveText.h"
49 /// AliAnalysisMuMuFromAOD
51 /// The list of cut considered is entered using the AddSingleCut and
52 /// AddPairCut methods.
56 ClassImp(AliAnalysisMuMuFromAOD)
58 //_____________________________________________________________________________
59 AliAnalysisMuMuFromAOD::AliAnalysisMuMuFromAOD()
60 : AliAnalysisMuMu(), fVertex(0), fGlobalEventSelectionName("ALL")
65 //_____________________________________________________________________________
66 AliAnalysisMuMuFromAOD::AliAnalysisMuMuFromAOD(Bool_t aa)
67 : AliAnalysisMuMu(kFALSE,aa), fVertex(0), fGlobalEventSelectionName("ALL")
70 // Must define here the single track and track pair cuts,
71 // and also the global event selection "names"
72 Ctor(fGlobalEventSelectionName);
75 //_____________________________________________________________________________
76 AliAnalysisMuMuFromAOD::AliAnalysisMuMuFromAOD(TList* triggerClasses)
77 : AliAnalysisMuMu(kFALSE,triggerClasses), fVertex(0), fGlobalEventSelectionName("ALL")
80 // Must define here the single track and track pair cuts,
81 // and also the global event selection "names"
83 Ctor(fGlobalEventSelectionName);
86 //_____________________________________________________________________________
87 void AliAnalysisMuMuFromAOD::Ctor(const char* globaleventselectionname)
93 fGlobalEventSelectionName="SD2";
97 AddGlobalEventSelection(globaleventselectionname);
101 //_____________________________________________________________________________
102 AliAnalysisMuMuFromAOD::~AliAnalysisMuMuFromAOD()
107 //_____________________________________________________________________________
108 void AliAnalysisMuMuFromAOD::DumpMC(const AliAODEvent& aod)
110 // dump mc part (if present)
113 AliAODMCHeader *mcHeader = static_cast<AliAODMCHeader*>(aod.FindListObject(AliAODMCHeader::StdBranchName()));
116 AliInfo(Form("================================ Generator %s x %e y %e z %e",
117 mcHeader->GetGeneratorName(),
120 mcHeader->GetVtxZ()));
124 TClonesArray* mcParticles = static_cast<TClonesArray*>(aod.FindListObject(AliAODMCParticle::StdBranchName()));
127 AliInfo(Form("%d mcparticles in that event",mcParticles->GetEntries()));
129 // loop on muon tracks are find back their decay chain
131 TIter next(aod.GetTracks());
135 // AliInfo("Muon tracks");
137 // while ( ( t = static_cast<AliAODTrack*>(next()) ) )
139 // if ( t->IsMuonTrack() )
141 // AliInfo(Form("mutrack #%2d Pt %e Eta %e Charge %d Label %d",
142 // nmu,t->Pt(),t->Eta(),t->Charge(),t->GetLabel()));
147 // AliInfo("MC particles...");
148 TIter nextMC(mcParticles);
152 // while ( ( p = static_cast<AliAODMCParticle*>(nextMC()) ) )
154 // AliInfo(Form("mcpart #%4d",nmc));
160 AliInfo("Muon track ancestors...");
162 while ( ( t = static_cast<AliAODTrack*>(next()) ) )
164 if ( t->IsMuonTrack() )
166 AliInfo(Form("Track label %d",t->GetLabel()));
167 Int_t label = t->GetLabel();
171 p = static_cast<AliAODMCParticle*>(mcParticles->At(label));
175 label = p->GetMother();
189 //_____________________________________________________________________________
190 void AliAnalysisMuMuFromAOD::MuUserExec(Option_t*)
193 // Called for each event
195 AliAODEvent* aod = dynamic_cast<AliAODEvent*>(InputEvent());
200 // consider only events with OSM2 fired
201 UInt_t trigger = aod->GetHeader()->GetL0TriggerInputs();
202 UInt_t sd2 = (1<<12);
203 Bool_t ok = ( ( trigger & sd2 ) == sd2);
207 if ( IsDynamicTriggerClasses() ) AddTriggerClasses(aod->GetFiredTriggerClasses());
209 TObjArray* a = aod->GetFiredTriggerClasses().Tokenize(" ");
214 TString centrality(DefaultCentralityName());
218 AliCentrality* acent = aod->GetCentrality();
222 if (acent) fcent = acent->GetCentralityPercentile("V0M");
228 for ( std::vector<double>::size_type i = 0 ; i < fCentralityLimits.size() && cent < 0 ; ++i )
230 if ( fcent < fCentralityLimits[i] )
232 cent = fCentralityLimits[i];
239 centrality = CentralityName(cent);
243 fVertex = aod->GetPrimaryVertex();
245 // Bool_t hasPileUp = aod->IsPileupFromSPD(3,0.8);
246 // Bool_t hasPileUp2 = aod->IsPileupFromSPD(5,0.8);
247 // Bool_t isIsolated = ( aod->GetBunchCrossNumber() > 1000 && aod->GetBunchCrossNumber() < 2900 );
249 // Bool_t hasPileUp2 = aod->IsPileupFromSPDInMultBins();
251 // TIter nextV(aod->GetVertices());
253 // while ( ( v = static_cast<AliAODVertex*>(nextV())) && !hasPileUp2 )
255 // if ( v->GetType() == AliAODVertex::kPileupSPD ) hasPileUp2 = kTRUE;
258 TString eventtype(fGlobalEventSelectionName);
261 while ( ( tname = static_cast<TObjString*>(next()) ) )
263 if ( !fTriggerClasses->FindObject(tname->GetName()) )
266 // skip the trigger classes we're not supposed to analyse
270 fEventCounters->Count(Form("event:%s/trigger:%s/run:%d", eventtype.Data(), tname->GetName(), fCurrentRunNumber));
272 AssertHistogramCollection(fGlobalEventSelectionName.Data(),tname->String().Data());
274 FillHistos(fGlobalEventSelectionName.Data(),tname->String().Data(),centrality.Data(),*aod);
278 // fEventCounters->Count(Form("event:PILEUP/trigger:%s/run:%d", tname->GetName(), fCurrentRunNumber));
280 // AssertHistogramCollection("PILEUP",tname->String().Data());
282 // FillHistos("PILEUP",tname->String().Data(),centrality.Data(),*aod);
287 // fEventCounters->Count(Form("event:PILEUP2/trigger:%s/run:%d", tname->GetName(), fCurrentRunNumber));
289 // AssertHistogramCollection("PILEUP2",tname->String().Data());
291 // FillHistos("PILEUP2",tname->String().Data(),centrality.Data(),*aod);
299 //_____________________________________________________________________________
300 Bool_t AliAnalysisMuMuFromAOD::TrackChi2(const AliAODTrack& track) const
302 /// Whether the track pass the chi2 cut
303 return track.Chi2perNDF() < 3.5;
306 //_____________________________________________________________________________
307 Bool_t AliAnalysisMuMuFromAOD::TrackEtaCut(const AliAODTrack& track) const
309 /// Whether the track pass the eta cut
310 return track.Eta() < -2.5 && track.Eta() > -4;
313 //_____________________________________________________________________________
314 Bool_t AliAnalysisMuMuFromAOD::TrackMatchCut(const AliAODTrack& track) const
316 /// Whether the track matched the trigger (any pt)
318 return track.GetMatchTrigger() > 0;
321 //_____________________________________________________________________________
322 Bool_t AliAnalysisMuMuFromAOD::TrackMatchLowCut(const AliAODTrack& track) const
324 /// Whether the track matched the trigger (low pt)
325 return track.GetMatchTrigger() > 1;
328 //_____________________________________________________________________________
329 Bool_t AliAnalysisMuMuFromAOD::TrackMatchHighCut(const AliAODTrack& track) const
331 /// Whether the track matched the trigger (high pt)
333 return track.GetMatchTrigger() > 2;
336 //_____________________________________________________________________________
337 Bool_t AliAnalysisMuMuFromAOD::TrackRabsCut(const AliAODTrack& track) const
339 /// Cut between 2 and 10 degrees
341 Double_t angle = TMath::ATan(track.GetRAtAbsorberEnd()/AbsZEnd());
343 return ( angle > Deg2() && angle < Deg10() );
346 //_____________________________________________________________________________
347 Bool_t AliAnalysisMuMuFromAOD::TrackPtCut(const AliAODTrack& track) const
349 /// Whether the track is above pt cut
350 return track.Pt() > 1.0;
353 //_____________________________________________________________________________
354 Bool_t AliAnalysisMuMuFromAOD::TrackBelowPtCut(const AliAODTrack& track) const
356 /// Whether the track is below pt cut
357 return track.Pt() < 4.0;
360 //_____________________________________________________________________________
361 Bool_t AliAnalysisMuMuFromAOD::TrackDCACut(const AliAODTrack& track) const
363 /// Whether the track pass the P x DCA cut
365 if (!fVertex) return kFALSE;
367 TLorentzVector p(track.Px(),track.Py(),track.Pz(),
368 TMath::Sqrt(MuonMass2()+track.P()*track.P()));
370 Double_t theta = TMath::ATan(track.GetRAtAbsorberEnd()/AbsZEnd());
372 Double_t meanPcorr = ( theta < ( 180. - 3. ) * TMath::DegToRad() ) ? 1.2 : 1.49;
373 Double_t pTotMean = p.P() - meanPcorr;
375 TVector3 eventVertex(fVertex->GetX(),fVertex->GetY(),fVertex->GetZ());
377 TVector3 trackDcaAtVz(track.XAtDCA(), track.YAtDCA(), fVertex->GetZ());
378 TVector3 meanDca(-0.46, -0.92, 0.); // LHC10h1
379 TVector3 dcaAtVz = trackDcaAtVz - eventVertex - meanDca;
380 Double_t correctedDca = dcaAtVz.Mag(); // it should also be equal to dcaAtVz.Pt().
381 Double_t cutVariable = pTotMean * correctedDca;
383 Double_t cutValue = (theta > Deg3()) ? 63. : 120.;
384 cutValue = TMath::Sqrt(cutValue*cutValue + 0.4*0.4*p.P()*p.P());
386 return ( cutVariable < 5*cutValue );
389 //_____________________________________________________________________________
390 UInt_t AliAnalysisMuMuFromAOD::GetTrackMask(const AliAODTrack& track) const
392 /// Get the mask of all the cuts this track pass
396 if ( TrackRabsCut(track) ) m |= kRabs;
398 if ( TrackPtCut(track) ) m |= kPt;
400 if ( TrackMatchCut(track) ) m |= kMatched;
402 if ( TrackMatchLowCut(track) ) m |= kMatchedLow;
404 if ( TrackMatchHighCut(track) ) m |= kMatchedHigh;
406 if ( TrackEtaCut(track) ) m |= kEta;
408 if ( TrackChi2(track) ) m |= kChi2;
410 if ( TrackDCACut(track) ) m |= kDCA;
412 if ( TrackBelowPtCut(track) ) m |= kBelowPt;
417 //_____________________________________________________________________________
418 Bool_t AliAnalysisMuMuFromAOD::PairRapidityCut(const AliAODTrack& t1, const AliAODTrack& t2) const
420 /// Whether the pair passes the rapidity cut
422 TLorentzVector p1(t1.Px(),t1.Py(),t1.Pz(),TMath::Sqrt(MuonMass2()+t1.P()*t1.P()));
423 TLorentzVector p2(t2.Px(),t2.Py(),t2.Pz(),TMath::Sqrt(MuonMass2()+t2.P()*t2.P()));
425 TLorentzVector total(p1+p2);
427 Double_t y = total.Rapidity();
429 Bool_t ok = ( y < -2.5 && y > -4.0 );
434 //_____________________________________________________________________________
435 void AliAnalysisMuMuFromAOD::GetPairMask(const AliAODTrack& t1, const AliAODTrack& t2,
436 UInt_t& mask1, UInt_t& mask2,
437 UInt_t& mask12) const
439 /// Get the mask of the track pair
441 mask1 = GetTrackMask(t1);
442 mask2 = GetTrackMask(t2);
444 mask12 = mask1 | mask2;
446 if ( PairRapidityCut(t1,t2) ) mask12 |= kPairRapidity;
449 //_____________________________________________________________________________
450 void AliAnalysisMuMuFromAOD::FillHistosForTrack(const char* physics,
451 const char* triggerClassName,
452 const char* centrality,
453 const AliAODTrack& track)
455 /// Fill histograms for one track
457 TLorentzVector p(track.Px(),track.Py(),track.Pz(),
458 TMath::Sqrt(MuonMass2()+track.P()*track.P()));
461 TString charge("Plus");
463 if ( track.Charge() < 0 ) charge = "Minus";
465 UInt_t mask = GetTrackMask(track);
467 Double_t xdca = track.XAtDCA();
468 Double_t ydca = track.YAtDCA();
469 Double_t dca = TMath::Sqrt(xdca*xdca+ydca*ydca);
470 Double_t theta = TMath::ATan(track.GetRAtAbsorberEnd()/AbsZEnd());
472 TIter next(fSingleTrackCutNames);
475 while ( ( str = static_cast<TObjString*>(next()) ) )
477 Bool_t test = ( ( str->GetUniqueID() & mask ) == str->GetUniqueID() );
481 Histo(physics,triggerClassName,centrality,str->String().Data(),Form("PtEtaMu%s",charge.Data()))->Fill(p.Eta(),p.Pt());
483 Histo(physics,triggerClassName,centrality,str->String().Data(),Form("PEtaMu%s",charge.Data()))->Fill(p.Eta(),p.P());
486 Histo(physics,triggerClassName,centrality,str->String().Data(),Form("XYdcaMu%s",charge.Data()))->Fill(ydca,xdca);
488 Histo(physics,triggerClassName,centrality,str->String().Data(),Form("Chi2Mu%s",charge.Data()))->Fill(track.Chi2perNDF());
490 if ( theta >= Deg2() && theta < Deg3() )
492 Histo(physics,triggerClassName,centrality,str->String().Data(),Form("dcaP23Mu%s",charge.Data()))->Fill(p.P(),dca);
495 Histo(physics,triggerClassName,centrality,str->String().Data(),Form("dcaPwPtCut23Mu%s",charge.Data()))->Fill(p.P(),dca);
498 else if ( theta >= Deg3() && theta < Deg10() )
500 Histo(physics,triggerClassName,centrality,str->String().Data(),Form("dcaP310Mu%s",charge.Data()))->Fill(p.P(),dca);
503 Histo(physics,triggerClassName,centrality,str->String().Data(),Form("dcaPwPtCut310Mu%s",charge.Data()))->Fill(p.P(),dca);
512 //_____________________________________________________________________________
513 void AliAnalysisMuMuFromAOD::FillHistos(const char* physics, const char* triggerClassName,
514 const char* centrality, const AliAODEvent& aod)
516 /// Fill histograms for /physics/triggerClassName/centrality
518 Histo(physics,triggerClassName,centrality,"BCX")->Fill(1.0*aod.GetBunchCrossNumber());
520 Histo(physics,triggerClassName,centrality,"Nevents")->Fill(1.0);
524 Histo(physics,triggerClassName,centrality,"Xvertex")->Fill(fVertex->GetX());
525 Histo(physics,triggerClassName,centrality,"Yvertex")->Fill(fVertex->GetY());
526 Histo(physics,triggerClassName,centrality,"Zvertex")->Fill(fVertex->GetZ());
528 Histo(physics,triggerClassName,centrality,"YXvertex")->Fill(fVertex->GetX(),fVertex->GetY());
530 // TIter nextV(aod.GetVertices());
532 // while ( ( v = static_cast<AliAODVertex*>(nextV())) )
534 // if ( v->GetType() == AliAODVertex::kPileupSPD )
536 // Histo(physics,triggerClassName,centrality,"PileUpXvertex")->Fill(v->GetX());
537 // Histo(physics,triggerClassName,centrality,"PileUpYvertex")->Fill(v->GetY());
539 // Histo(physics,triggerClassName,centrality,"PileUpZvertex")->Fill(v->GetZ() - fVertex->GetZ());
541 // Histo(physics,triggerClassName,centrality,"PileUpYXvertex")->Fill(v->GetX(),v->GetY());
550 for (Int_t i = 0; i < aod.GetNumberOfTracks(); ++i)
552 AliAODTrack* tracki = aod.GetTrack(i);
554 if (!tracki->IsMuonTrack()) continue;
556 FillHistosForTrack(physics,triggerClassName,centrality,*tracki);
558 TLorentzVector pi(tracki->Px(),tracki->Py(),tracki->Pz(),
559 TMath::Sqrt(MuonMass2()+tracki->P()*tracki->P()));
561 for (Int_t j = i+1; j < aod.GetNumberOfTracks(); ++j)
563 AliAODTrack* trackj = aod.GetTrack(j);
565 if (!trackj->IsMuonTrack()) continue;
567 TLorentzVector pj(trackj->Px(),trackj->Py(),trackj->Pz(),
568 TMath::Sqrt(MuonMass2()+trackj->P()*trackj->P()));
572 TIter next(fPairTrackCutNames);
575 UInt_t maski(0),maskj(0),maskij(0);
577 GetPairMask(*trackj,*tracki,maski,maskj,maskij);
579 while ( ( str = static_cast<TObjString*>(next()) ) )
581 UInt_t singleTrackMask(0);
584 DecodePairCutMask(str->GetUniqueID(),singleTrackMask,pairMask);
586 Bool_t testi = ( ( maski & singleTrackMask ) == singleTrackMask ) ;
587 Bool_t testj = ( ( maskj & singleTrackMask ) == singleTrackMask ) ;
588 Bool_t testij(kTRUE);
590 if (pairMask>0) testij = ( ( maskij & pairMask ) == pairMask ) ;
592 if ( testi && testj && testij )
594 if ( tracki->Charge() != trackj->Charge() )
596 Histo(physics,triggerClassName,centrality,str->String().Data(),"MinvUSPt")->Fill(pj.Pt(),pj.M());
598 else if ( tracki->Charge() > 0 && trackj->Charge() > 0 )
600 Histo(physics,triggerClassName,centrality,str->String().Data(),"MinvPPPt")->Fill(pj.Pt(),pj.M());
604 Histo(physics,triggerClassName,centrality,str->String().Data(),"MinvMMPt")->Fill(pj.Pt(),pj.M());