1 #include "AliAnalysisMuMuMinv.h"
5 * \ingroup pwg-muon-mumu
7 * \class AliAnalysisMuMuMinv
9 * Analysis which fills a bunch of histograms for invariant mass analysis of J/psi
11 * Can be used on real data and/or simulated (for instance to get Acc x Eff)
13 * Can optionally use as input an already computed Acc x Eff matrix that will be applied
14 * when filling the invariant mass histograms.
20 #include "TObjArray.h"
21 #include "AliAnalysisMuMuBinning.h"
23 #include "TLorentzVector.h"
25 #include "AliMCEvent.h"
26 #include "AliMergeableCollection.h"
27 #include "AliAnalysisMuonUtility.h"
28 #include "TParameter.h"
31 ClassImp(AliAnalysisMuMuMinv)
33 //_____________________________________________________________________________
34 AliAnalysisMuMuMinv::AliAnalysisMuMuMinv()
35 : AliAnalysisMuMuBase(),
38 // FIXME : find the AccxEff histogram from HistogramCollection()->Histo("/EXCHANGE/JpsiAccEff")
42 // fAccEffHisto = static_cast<TH2F*>(accEff->Clone());
43 // fAccEffHisto->SetDirectory(0);
47 //_____________________________________________________________________________
48 AliAnalysisMuMuMinv::~AliAnalysisMuMuMinv()
54 //_____________________________________________________________________________
56 AliAnalysisMuMuMinv::DefineHistogramCollection(const char* eventSelection,
57 const char* triggerClassName,
58 const char* centrality)
60 /// Define the histograms this analysis will use
62 if ( Histo(eventSelection,triggerClassName,centrality,"AliAnalysisMuMuMinv") )
67 // dummy histogram to signal that we already defined all our histograms (see above)
68 CreateEventHistos(kHistoForData | kHistoForMCInput,eventSelection,triggerClassName,centrality,"AliAnalysisMuMuMinv","Dummy semaphore",1,0,1);
70 /// Create invariant mass histograms
73 Double_t minvMax = 16;
74 Int_t nMinvBins = GetNbins(minvMin,minvMax,0.025);
76 Int_t nMCMinvBins = GetNbins(minvMin,minvMax,0.1);
78 // TObjArray* bins = fBinning->CreateBinObjArray("psi","y vs pt,integrated,pt,y,phi","");
79 TObjArray* bins = Binning()->CreateBinObjArray("psi");
81 CreatePairHistos(eventSelection,triggerClassName,centrality,"Pt","#mu+#mu- Pt distribution",
88 CreatePairHistos(eventSelection,triggerClassName,centrality,"y","#mu+#mu- y distribution",nbinsy,ymin,ymax);
90 // CreatePairHistos(eventSelection,triggerClassName,centrality,"BinFlowPt","#mu+#mu- BinFlowPt distribution",
93 CreatePairHistos(eventSelection,triggerClassName,centrality,"PtRecVsSim","#mu+#mu- Pt distribution rec vs sim",
96 if (!Histo("INPUT","ALL","Pt"))
98 HistogramCollection()->Adopt("/INPUT/ALL",new TH1F("Pt","Pt",200,0,20));
99 HistogramCollection()->Adopt("/INPUT/INYRANGE",new TH1F("Pt","Pt",200,0,20));
100 HistogramCollection()->Adopt("/INPUT/ALL",new TH1F("Y","Y",nbinsy,ymin,ymax));
101 HistogramCollection()->Adopt("/INPUT/INYRANGE",new TH1F("Y","Y",nbinsy,ymin,ymax));
105 AliAnalysisMuMuBinning::Range* r;
108 while ( ( r = static_cast<AliAnalysisMuMuBinning::Range*>(next()) ) )
110 TString minvName(GetMinvHistoName(*r,ShouldCorrectDimuonForAccEff()));
112 if ( IsHistogramDisabled(minvName.Data()) ) continue;
116 AliDebug(1,Form("bin %d %s histoname = %s",nb,r->AsString().Data(),minvName.Data()));
118 CreatePairHistos(eventSelection,triggerClassName,centrality,minvName.Data(),
119 Form("#mu+#mu- inv. mass %s %s;M_{#mu^+#mu^-} (GeV/c^2)",
120 ShouldCorrectDimuonForAccEff() ? "(AccxEff corrected)":"",
121 r->AsString().Data()),
122 nMinvBins,minvMin,minvMax);
124 TString hname(GetMinvHistoName(*r,kFALSE));
126 TH1* h = HistogramCollection()->Histo("/INPUT/ALL",hname.Data());
129 h = new TH1F(hname.Data(),Form("MC #mu+#mu- inv. mass %s",r->AsString().Data()),
130 nMCMinvBins,minvMin,minvMax);
132 HistogramCollection()->Adopt("/INPUT/ALL",h);
134 HistogramCollection()->Adopt("/INPUT/INYRANGE",static_cast<TH1*>(h->Clone()));
141 //_____________________________________________________________________________
142 void AliAnalysisMuMuMinv::FillHistosForPair(const char* eventSelection, const char* triggerClassName,
143 const char* centrality, const char* pairCutName,
144 const AliVParticle& tracki,
145 const AliVParticle& trackj)
147 /** Fill histograms for muon track pairs
150 if (!AliAnalysisMuonUtility::IsMuonTrack(&tracki) ) return;
151 if (!AliAnalysisMuonUtility::IsMuonTrack(&trackj) ) return;
153 TLorentzVector pi(tracki.Px(),tracki.Py(),tracki.Pz(),
154 TMath::Sqrt(AliAnalysisMuonUtility::MuonMass2()+tracki.P()*tracki.P()));
157 TLorentzVector pair4Momentum(trackj.Px(),trackj.Py(),trackj.Pz(),
158 TMath::Sqrt(AliAnalysisMuonUtility::MuonMass2()+trackj.P()*trackj.P()));
163 if (!IsHistogramDisabled("Chi12"))
165 Histo(eventSelection,triggerClassName,centrality,pairCutName,"Chi12")
167 AliAnalysisMuonUtility::GetChi2perNDFtracker(&tracki),
168 AliAnalysisMuonUtility::GetChi2perNDFtracker(&trackj));
171 if (!IsHistogramDisabled("Rabs12"))
173 Histo(eventSelection,triggerClassName,centrality,pairCutName,"Rabs12")
174 ->Fill(AliAnalysisMuonUtility::GetRabs(&tracki),
175 AliAnalysisMuonUtility::GetRabs(&trackj));
178 if ( ( tracki.Charge() != trackj.Charge() ) )
180 if ( !IsHistogramDisabled("Pt") )
182 Histo(eventSelection,triggerClassName,centrality,pairCutName,"Pt")->Fill(pair4Momentum.Pt());
185 if ( !IsHistogramDisabled("y") )
187 Histo(eventSelection,triggerClassName,centrality,pairCutName,"y")->Fill(pair4Momentum.Y());
192 Int_t labeli = tracki.GetLabel();
193 Int_t labelj = trackj.GetLabel();
195 if ( labeli < 0 || labelj < 0 )
197 AliError("Got negative labels!");
201 AliVParticle* mcTracki = MCEvent()->GetTrack(labeli);
202 AliVParticle* mcTrackj = MCEvent()->GetTrack(labelj);
204 TLorentzVector mcpi(mcTracki->Px(),mcTracki->Py(),mcTracki->Pz(),
205 TMath::Sqrt(AliAnalysisMuonUtility::MuonMass2()+mcTracki->P()*mcTracki->P()));
206 TLorentzVector mcpj(mcTrackj->Px(),mcTrackj->Py(),mcTrackj->Pz(),
207 TMath::Sqrt(AliAnalysisMuonUtility::MuonMass2()+mcTrackj->P()*mcTrackj->P()));
211 Histo(eventSelection,triggerClassName,centrality,pairCutName,"PtRecVsSim")->Fill(mcpj.Pt(),pair4Momentum.Pt());
217 TObjArray* bins = Binning()->CreateBinObjArray("psi","ptvsy,yvspt,pt,y,phi","");
219 AliAnalysisMuMuBinning::Range* r;
221 while ( ( r = static_cast<AliAnalysisMuMuBinning::Range*>(nextBin()) ) )
225 if ( r->IsIntegrated() )
229 else if ( r->Is2D() )
231 if ( r->AsString().BeginsWith("PTVSY") )
233 ok = r->IsInRange(pair4Momentum.Rapidity(),pair4Momentum.Pt());
235 else if ( r->AsString().BeginsWith("YVSPT") )
237 ok = r->IsInRange(pair4Momentum.Pt(),pair4Momentum.Rapidity());
241 AliError(Form("Don't know how to deal with 2D bin %s",r->AsString().Data()));
246 if ( r->Quantity() == "PT" )
248 ok = r->IsInRange(pair4Momentum.Pt());
250 else if ( r->Quantity() == "Y" )
252 ok = r->IsInRange(pair4Momentum.Rapidity());
254 else if ( r->Quantity() == "PHI" )
256 ok = r->IsInRange(pair4Momentum.Phi());
258 else if ( r->Quantity() == "NCH" )
260 TList* list = static_cast<TList*>(Event()->FindListObject("NCH"));
264 TParameter<Double_t>* p;
266 while ( ( p = static_cast<TParameter<Double_t>*>(next())) )
268 if (TString(eventSelection).Contains(p->GetName()))
270 ok = r->IsInRange(p->GetVal());
280 TString minvName = GetMinvHistoName(*r,kFALSE);
282 if (!IsHistogramDisabled(minvName.Data()))
284 TH1* h = Histo(eventSelection,triggerClassName,centrality,pairCutName,minvName.Data());
288 AliError(Form("Could not get %s",minvName.Data()));
291 h->Fill(pair4Momentum.M());
295 // FIXME : fill Minv with weight = 1/AccxEff
305 //_____________________________________________________________________________
306 void AliAnalysisMuMuMinv::FillHistosForMCEvent(const char* /*eventSelection*/,
307 const char* /*triggerClassName*/,
308 const char* /*centrality*/)
310 /** Fill histograms for MC event
312 * FIXME: this is here we should streamline a bit the code to carefully
313 * compute the measured and truth values for Pt, Y, and (Pt,Y), in order
314 * to be able to investigate unfolding techniques later on...
317 Int_t nMCTracks = MCEvent()->GetNumberOfTracks();
319 for ( Int_t i = 0; i < nMCTracks; ++i )
321 AliVParticle* part = MCEvent()->GetTrack(i);
323 if ( AliAnalysisMuonUtility::IsPrimary(part,MCEvent()) &&
324 AliAnalysisMuonUtility::GetMotherIndex(part)==-1 )
326 Histo("INPUT","ALL","Pt")->Fill(part->Pt());
327 Histo("INPUT","ALL","Y")->Fill(part->Y());
328 if ( part->Y() < -2.5 && part->Y() > -4.0 )
330 Histo("INPUT","INYRANGE","Pt")->Fill(part->Pt());
331 Histo("INPUT","INYRANGE","Y")->Fill(part->Y());
338 // Int_t nTracks = AliAnalysisMuonUtility::GetNTracks(Event());
340 // Double_t measuredY(0.0);
342 // for (Int_t i = 0; i < nTracks; ++i)
344 // AliVParticle* tracki = AliAnalysisMuonUtility::GetTrack(i,Event());
346 // if (!AliAnalysisMuonUtility::IsMuonTrack(tracki) ) continue;
348 // for (Int_t j = i+1; j < nTracks; ++j )
350 // AliVParticle* trackj = AliAnalysisMuonUtility::GetTrack(j,Event());
352 // if (!AliAnalysisMuonUtility::IsMuonTrack(trackj) ) continue;
354 // TLorentzVector pi(tracki->Px(),tracki->Py(),tracki->Pz(),
355 // TMath::Sqrt(AliAnalysisMuonUtility::MuonMass2()+tracki->P()*tracki->P()));
357 // TLorentzVector pair4Momentum(trackj->Px(),trackj->Py(),trackj->Pz(),
358 // TMath::Sqrt(AliAnalysisMuonUtility::MuonMass2()+trackj->P()*trackj->P()));
360 // pair4Momentum += pi;
362 // measuredY = pi.Y();
364 // rur->Fill(measuredY,trueY); // FIXME : is this working if more than one pair is found in the reconstructed tracks ???
365 // // should we try to find the closest one in minv and assign the other(s)
366 // // to rur->Fake() ?
371 // if ( ! ( measuredY < 0.0 ) )
377 ////_____________________________________________________________________________
378 //void AliAnalysisMuMuMinv::FillMC()
380 // // Fill the input Monte-Carlo histograms related to muons
382 // // Specific things for MC
383 // if (!Histo("INPUT","ALL","Pt"))
385 // HistogramCollection()->Adopt("/INPUT/ALL",new TH1F("Pt","Pt",200,0,20));
386 // HistogramCollection()->Adopt("/INPUT/INYRANGE",new TH1F("Pt","Pt",200,0,20));
388 // Double_t rapidityMin = -5;
389 // Double_t rapidityMax = -2;
390 // Int_t nbinsRapidity = GetNbins(rapidityMin,rapidityMax,0.05);
392 // HistogramCollection()->Adopt("/INPUT/ALL",new TH1F("Y","Y",nbinsRapidity,rapidityMin,rapidityMax));
393 // HistogramCollection()->Adopt("/INPUT/INYRANGE",new TH1F("Y","Y",nbinsRapidity,rapidityMin,rapidityMax));
395 // Double_t etaMin = -5;
396 // Double_t etaMax = -2;
397 // Int_t nbinsEta = GetNbins(etaMin,etaMax,0.05);
399 // HistogramCollection()->Adopt("/INPUT/ALL",new TH1F("Eta","Eta",nbinsEta,etaMin,etaMax));
400 // HistogramCollection()->Adopt("/INPUT/INYRANGE",new TH1F("Eta","Eta",nbinsEta,etaMin,etaMax));
403 // Int_t nMCTracks = MCEvent()->GetNumberOfTracks();
405 // TObjArray* bins = Binning()->CreateBinObjArray("psi","ptvsy,yvspt,pt,y,phi","");
406 // TIter nextBin(bins);
407 // AliAnalysisMuMuBinning::Range* r;
409 // for ( Int_t i = 0; i < nMCTracks; ++i )
411 // AliVParticle* part = MCEvent()->GetTrack(i);
413 // // std::cout << "part " << i << " isprimary=" << AliAnalysisMuonUtility::IsPrimary(part,MCEvent()) << " motherindex=" << AliAnalysisMuonUtility::GetMotherIndex(part) << std::endl;
417 // if (AliAnalysisMuonUtility::IsPrimary(part,MCEvent()) &&
418 // AliAnalysisMuonUtility::GetMotherIndex(part)==-1)
421 // Histo("INPUT","ALL","Pt")->Fill(part->Pt());
422 // Histo("INPUT","ALL","Y")->Fill(part->Y());
423 // Histo("INPUT","ALL","Eta")->Fill(part->Eta());
425 // if ( part->Y() < -2.5 && part->Y() > -4.0 )
427 // Histo("INPUT","INYRANGE","Pt")->Fill(part->Pt());
428 // Histo("INPUT","INYRANGE","Y")->Fill(part->Y());
429 // Histo("INPUT","INYRANGE","Eta")->Fill(part->Eta());
434 // while ( ( r = static_cast<AliAnalysisMuMuBinning::Range*>(nextBin()) ) )
436 // Bool_t ok(kFALSE);
438 // if ( r->IsIntegrated() )
442 // else if ( r->Is2D() )
444 // if ( r->AsString().BeginsWith("PTVSY") )
446 // ok = r->IsInRange(part->Y(),part->Pt());
448 // else if ( r->AsString().BeginsWith("YVSPT") )
450 // ok = r->IsInRange(part->Pt(),part->Y());
454 // AliError(Form("Don't know how to deal with 2D bin %s",r->AsString().Data()));
459 // if ( r->Quantity() == "PT" )
461 // ok = r->IsInRange(part->Pt());
463 // else if ( r->Quantity() == "Y" )
465 // ok = r->IsInRange(part->Y());
467 // else if ( r->Quantity() == "PHI" )
469 // ok = r->IsInRange(part->Phi());
475 // TString hname = GetMinvHistoName(*r,kFALSE);
477 // if (!IsHistogramDisabled(hname.Data()))
480 // TH1* h = Histo("INPUT","ALL",hname.Data());
484 // AliError(Form("Could not get ALL %s",hname.Data()));
488 // h->Fill(part->M());
490 // if ( part->Y() < -2.5 && part->Y() > -4.0 )
492 // h = Histo("INPUT","INYRANGE",hname.Data());
495 // AliError(Form("Could not get INYRANGE %s",hname.Data()));
498 // h->Fill(part->M());
512 //_____________________________________________________________________________
513 TString AliAnalysisMuMuMinv::GetMinvHistoName(const AliAnalysisMuMuBinning::Range& r, Bool_t accEffCorrected) const
515 /// Get the invariant mass histogram name
516 return TString::Format("MinvUS%s%s",r.AsString().Data(),
517 accEffCorrected ? "_AccEffCorr" : "");
520 //_____________________________________________________________________________
521 Bool_t AliAnalysisMuMuMinv::IsRapidityInRange(const AliVParticle& t1, const AliVParticle& t2, Double_t& ymin, Double_t& ymax) const
523 /// Whether the particle pair has its rapidity within [ymin,ymax[
525 TLorentzVector p1(t1.Px(),t1.Py(),t1.Pz(),TMath::Sqrt(AliAnalysisMuonUtility::MuonMass2()+t1.P()*t1.P()));
526 TLorentzVector p2(t2.Px(),t2.Py(),t2.Pz(),TMath::Sqrt(AliAnalysisMuonUtility::MuonMass2()+t2.P()*t2.P()));
528 TLorentzVector total(p1+p2);
530 Double_t y = total.Rapidity();
532 return ( y < ymax && y > ymin );
535 //_____________________________________________________________________________
536 void AliAnalysisMuMuMinv::NameOfIsRapidityInRange(TString& name, Double_t& ymin, Double_t& ymax) const
538 /** Get the name of the rapidity range (making the IsRapidityInRange method useable as an
539 * AliAnalysisMuMuCutElement
542 name.Form("PAIRYIN%2.1f-%2.1f",ymin,ymax);