ATLAS Offline Software
DiMuMon.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include <sstream>
6 #include "GaudiKernel/PhysicalConstants.h"
9 
10 #include "DiMuMon.h"
11 
13 
14 #include <cmath>
15 
16 #include "TF1.h"
17 #include "TCanvas.h"
18 #include "TStyle.h"
19 
20 #include "RooRealVar.h"
21 #include "RooDataHist.h"
22 #include "RooPlot.h"
23 #include "RooBreitWigner.h"
24 #include "RooCBShape.h"
25 #include "RooFFTConvPdf.h"
26 #include "RooGlobalFunc.h"
27 #include "RooArgList.h"
28 #include "RooFitResult.h"
29 
30 
31 //using namespace Analysis;
32 //using namespace Rec;
33 
34 DiMuMon::DiMuMon( const std::string & type, const std::string & name, const IInterface* parent )
36  , m_triggerChainName("NoTrig")
37 {
38  declareProperty( "resonName", m_resonName = "Zmumu" );
39  declareProperty( "triggerChainName", m_triggerChainName = "NoTrig" );
40  declareProperty( "setDebug", m_setDebug = false );
41  declareProperty( "minInvmass", m_minInvmass = 60.);
42  declareProperty( "maxInvmass", m_maxInvmass = 120.);
43  declareProperty( "regions", m_regions );
44  declareProperty( "nVarBins", m_nVarBins = 10);
45  declareProperty( "nPtBins", m_nPtBins = 100);
46  declareProperty( "nEtaBins", m_nEtaBins = 32);
47  declareProperty( "nPhiBins", m_nPhiBins = 36);
48  declareProperty( "nMassBins", m_nMassBins = 60);
49  declareProperty( "varsVSmean", m_varsVSmean);
50  declareProperty( "varsVSwidth", m_varsVSwidth);
51  declareProperty( "varsDistr", m_varsDistr);
52  declareProperty( "doSaveFits", m_doSaveFits = false );
53  declareProperty( "doFits", m_doFits = false );
54  declareProperty( "ptCut", m_ptCut = 0.);//GeV
55  declareProperty( "etaCut", m_etaCut = 2.5);
56 }
57 
58 
60 {
61 }
62 
64 
67 
68  if (m_regions.empty()) {
69  m_regions.emplace_back("All");
70  }
71  // m_variables[] = {"eta","etaAll","etaPos","etaNeg","phi","phiAll","phiPos","phiNeg","pt","ptAll","ptPos","ptNeg","etaDiff","etaSumm","phiDiff","phiSumm","crtDiff"};
72  m_varLabels["eta"] = "Dimuon #eta";
73  m_varLabels["etaAll"] = "#eta (all #mu)";
74  m_varLabels["etaPos"] = "#eta(+)";
75  m_varLabels["etaNeg"] = "#eta(-)";
76 
77  m_varLabels["phi"] = "Dimuon #phi";
78  m_varLabels["phiAll"] = "#phi (all #mu)";
79  m_varLabels["phiPos"] = "#phi(+)";
80  m_varLabels["phiNeg"] = "#phi(-)";
81 
82  m_varLabels["pt"] = "Dimuon p_{T}";
83  m_varLabels["ptAll"] = "p_{T} (all #mu)";
84  m_varLabels["ptPos"] = "p_{T}(+) [GeV]";
85  m_varLabels["ptNeg"] = "p_{T}(-) [GeV]";
86 
87  m_varLabels["etaDiff"] = "#eta(+)-#eta(-)";
88  m_varLabels["etaSumm"] = "#eta(+)+#eta(-)";
89  m_varLabels["phiDiff"] = "#phi(+)-#phi(-)";
90  m_varLabels["phiSumm"] = "#phi(+)+#phi(-)";
91  m_varLabels["crtDiff"] = "1/p_{T}(+) - 1/p_{T}(-) [GeV^{-1}]";
92 
93  //resonance independent
94  // for eta these are filled as the histograms are declared due to the dependence between region and eta
95  m_varRanges["phi"] = std::make_pair(-Gaudi::Units::pi,Gaudi::Units::pi);
96  m_varRanges["phiAll"] = std::make_pair(-Gaudi::Units::pi,Gaudi::Units::pi);
97  m_varRanges["phiPos"] = std::make_pair(-Gaudi::Units::pi,Gaudi::Units::pi);
98  m_varRanges["phiNeg"] = std::make_pair(-Gaudi::Units::pi,Gaudi::Units::pi);
99  m_varRanges["etaSumm"] = std::make_pair(-5.,5.);
100 
101  //resonance dependent
102  double ptMax = 0.;
103  if (m_resonName=="Jpsi" || m_resonName=="Upsi"){
104  m_varRanges["eta"] = std::make_pair(-3.,3.);
105  m_varRanges["phiDiff"] = std::make_pair(0.,1.);
106  m_varRanges["etaDiff"] = std::make_pair(-1.,1.);
107  m_varRanges["crtDiff"] = std::make_pair(-0.15,0.15);
108  m_varRanges["phiSumm"] = std::make_pair(-6.,6.);
109  if (m_ptCut == 0.) m_ptCut = 4.0;
110  ptMax = 18.;
111  } else if (m_resonName=="Zmumu") {
112  m_varRanges["eta"] = std::make_pair(-5.,5.);
113  m_varRanges["phiDiff"] = std::make_pair(0.,Gaudi::Units::pi);
114  m_varRanges["etaDiff"] = std::make_pair(-3.,3.);
115  m_varRanges["crtDiff"] = std::make_pair(-0.03,0.03);
116  m_varRanges["phiSumm"] = std::make_pair(-3.5,3.5);
117  if (m_ptCut == 0.) m_ptCut = 20.0;
118  ptMax = 100.;
119  }
120  m_varRanges["pt"] = std::make_pair(0.,ptMax);
121  m_varRanges["ptAll"] = std::make_pair(m_ptCut,ptMax);
122  m_varRanges["ptPos"] = std::make_pair(m_ptCut,ptMax);
123  m_varRanges["ptNeg"] = std::make_pair(m_ptCut,ptMax);
124 
125 
126  m_coneSize = 0.4;
127  m_isolationCut = 0.2;
128 
129  return StatusCode::SUCCESS;
130 
131 }
132 
134 {
135 
136 
137  MonGroup dimuMonObj_shift( this, "DiMuMon/"+m_resonName+"/" + m_triggerChainName, run );
138  MonGroup dimuMonObj_expert( this, "DiMuMon/"+m_resonName+"/" + m_triggerChainName + "_detail", run );
139 
141  // book histograms that are only made in the online environment...
142  }
143 
145  // book histograms that are only relevant for cosmics data...
146  }
147 
148 
149 
150 
151  if( newRunFlag() ) {
152 
153 
154  m_chi2 = new TH1F("chi2","chi2",100,0.,10.);
155  RegisterHisto(dimuMonObj_expert,m_chi2);
156 
157  const int nCuts = 8;
158  m_stat = new TH1F("statistics","Statistics",nCuts, 0., double(nCuts));
159  TString binLabels[] ={"MuonIdTrk","TrkIsoPt40/Pt<.2","CombMuon","MCPgoodTrk","MuPtOK","eta<2.5","OppChargePair","InvMassOK"};
160  for(int ilabel=0;ilabel<nCuts;ilabel++){
161  m_stat->GetXaxis()->SetBinLabel(ilabel+1,binLabels[ilabel]);
162  }
163  RegisterHisto(dimuMonObj_expert,m_stat);
164 
165  //create histos for each region
166  for (const std::string& reg : m_regions) {
167 
168  //declare region-dependent eta range
169  if (reg == "BB") {
170  m_varRanges["etaAll"] = std::make_pair(-1.05,1.05);
171  m_varRanges["etaPos"] = std::make_pair(-1.05,1.05);
172  m_varRanges["etaNeg"] = std::make_pair(-1.05,1.05);
173  } else if (reg == "EAEA") {
174  m_varRanges["etaAll"] = std::make_pair(1.05,2.5);
175  m_varRanges["etaPos"] = std::make_pair(1.05,2.5);
176  m_varRanges["etaNeg"] = std::make_pair(1.05,2.5);
177  } else if (reg == "ECEC") {
178  m_varRanges["etaAll"] = std::make_pair(-2.5,-1.05);
179  m_varRanges["etaPos"] = std::make_pair(-2.5,-1.05);
180  m_varRanges["etaNeg"] = std::make_pair(-2.5,-1.05);
181  } else {
182  m_varRanges["etaAll"] = std::make_pair(-2.5,2.5);
183  m_varRanges["etaPos"] = std::make_pair(-2.5,2.5);
184  m_varRanges["etaNeg"] = std::make_pair(-2.5,2.5);
185  }
186 
187  //mass plots
188  TString hname = m_resonName + "_invmass_" + reg;
189  TString htitle = hname + "; Invmass[GeV/c^{2}]";
190  m_invmass[reg] = new TH1F(hname, htitle, m_nMassBins, m_minInvmass, m_maxInvmass);
191  RegisterHisto(dimuMonObj_shift,m_invmass[reg]);
192 
193  //for each var vs mass plot
194  for (const std::string& varM : m_varsVSmean) {
195  hname = m_resonName + "_2DinvmassVS" + varM + "_" + reg;
196  htitle = hname + ";" + m_varLabels[varM] + ";Invmass[GeV/c^{2}]";
198  RegisterHisto(dimuMonObj_shift,m_2DinvmassVSx[reg][varM]);
199 
200  hname = m_resonName + "_invmassVS" + varM + "_" + reg;
201  htitle = hname + ";" + m_varLabels[varM] + ";Invmass[GeV/c^{2}]";
202  m_invmassVSx[reg][varM] = new TH1F(hname, htitle, m_nVarBins,m_varRanges[varM].first, m_varRanges[varM].second);
203  RegisterHisto(dimuMonObj_shift,m_invmassVSx[reg][varM]);
204  }
205 
206  //for each var vs width plot
207  for (const std::string& varW : m_varsVSwidth) {
208  //book the corresponding 2D histo if it hasn't already been booked
209  if (m_2DinvmassVSx[reg].find(varW)==m_2DinvmassVSx[reg].end()){
210  hname = m_resonName + "_2DinvmassVS" + varW + "_" + reg;
211  htitle = hname + ";" + m_varLabels[varW] + ";Invmass[GeV/c^{2}]";
213  RegisterHisto(dimuMonObj_shift,m_2DinvmassVSx[reg][varW]);
214  }
215 
216  hname = m_resonName + "_widthVS" + varW + "_" + reg;
217  htitle = hname + ";" + m_varLabels[varW] + ";Width[GeV/c^{2}]";
218  m_widthVSx[reg][varW] = new TH1F(hname,htitle ,m_nVarBins,m_varRanges[varW].first, m_varRanges[varW].second);
219  RegisterHisto(dimuMonObj_expert,m_widthVSx[reg][varW]);
220 
221  }
222 
223  //for the each variable's distribution
224  for (const std::string& varD: m_varsDistr) {
225  hname = m_resonName + "_" + varD + "_" + reg;
226  htitle = hname + ";" + m_varLabels[varD];
227  if (varD == "eta" || varD == "etaAll" || varD == "etaPos" || varD == "etaNeg" ){
228  m_xDistr[reg][varD] = new TH1F(hname, htitle, m_nEtaBins, m_varRanges[varD].first, m_varRanges[varD].second);
229  } else if (varD == "pt" || varD == "ptAll" || varD == "ptPos" || varD == "ptNeg" ){
230  m_xDistr[reg][varD] = new TH1F(hname, htitle, m_nPtBins, m_varRanges[varD].first, m_varRanges[varD].second);
231  } else if (varD == "phi" || varD == "phiAll" || varD == "phiPos" || varD == "phiNeg" ){
232  m_xDistr[reg][varD] = new TH1F(hname, htitle, m_nPhiBins, m_varRanges[varD].first, m_varRanges[varD].second);
233  } else {
234  m_xDistr[reg][varD] = new TH1F(hname, htitle, m_nVarBins, m_varRanges[varD].first, m_varRanges[varD].second);
235  }
236  RegisterHisto(dimuMonObj_expert,m_xDistr[reg][varD]);
237  }
238  }
239  }
240 
241  return StatusCode::SUCCESS;
242 }
243 
244 
246 {
247 
248  const double muonMass = ParticleConstants::muonMassInMeV;
249  //retrieve all muons
251  if(!muons.isValid()){
252  ATH_MSG_WARNING("Could not retrieve muon container");
253  return StatusCode::FAILURE;
254  } else ATH_MSG_DEBUG("Muon container successfully retrieved.");
255 
256  //make a new container
258 
259  //pick out the good muon tracks and store in the new container
260  for(const auto* muon : *muons ) {
261 
262  const xAOD::TrackParticle *idTrk = muon->trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
263  if (!idTrk) continue;
264  m_stat->Fill("MuonIdTrk",1);
265  double idTrkPt(0),ptSum(0);
266  float iso_pt40(0);
267  if( !muon->isolation(iso_pt40, xAOD::Iso::ptcone40) ) {
268  return StatusCode::FAILURE;
269  }
270  else {
271  idTrkPt = idTrk->pt();
272  ptSum = xAOD::Iso::ptcone40;
273  }
274  if(m_resonName=="Zmumu" && ptSum/idTrkPt > m_isolationCut) continue;
275  m_stat->Fill("TrkIsoPt40/Pt<.2",1);
276  if (!muon->trackParticle(xAOD::Muon::CombinedTrackParticle)) continue;
277  m_stat->Fill("CombMuon",1);
278 
279  if (!trackQuality(idTrk)) continue;
280  m_stat->Fill("MCPgoodTrk",1);
281 
282  if (idTrkPt < m_ptCut*1000) continue;
283  m_stat->Fill("MuPtOK",1);
284 
285  double idTrkEta = idTrk->eta();
286  if (std::abs(idTrkEta)>2.5) continue;
287  m_stat->Fill("eta<2.5",1);
288 
289  goodMuons.push_back(muon);
290  }
291 
292  //pair up the tracks of the good muons and fill histograms
293  int nMuons = goodMuons.size();
294 
295  if (nMuons>1){
296  xAOD::MuonContainer::const_iterator mu1 = goodMuons.begin();
297  xAOD::MuonContainer::const_iterator muEnd = goodMuons.end();
298  for (; mu1!=muEnd;++mu1){
299  const xAOD::TrackParticle *id1 = (*mu1)->trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
301  for (; mu2!=muEnd; ++mu2){
302  const xAOD::TrackParticle *id2 = (*mu2)->trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
303  //consider only opposite sign muons
304  double q1 = id1->charge();
305  double q2 = id2->charge();
306  if (q1*q2>0) continue;
307  m_stat->Fill("OppChargePair",1);
308  const xAOD::TrackParticle *idPos = id1;
309  const xAOD::TrackParticle *idNeg = id2;
310  if (q1<0){
311  idPos = id2;
312  idNeg = id1;
313  }
314 
315  //cut on the pair invariant mass
316  double invmass = getInvmass(id1,id2,muonMass);
317  if (invmass<m_minInvmass || invmass>m_maxInvmass) continue;
318  m_stat->Fill("InvMassOK",1);
319 
320  //compute variables
321  m_varValues["eta"] = getEta(idPos,idNeg);
322  double etaPos = idPos->eta();
323  m_varValues["etaPos"] = etaPos;
324  double etaNeg = idNeg->eta();
325  m_varValues["etaNeg"] = etaNeg;
326  m_varValues["phi"] = getPhi(idPos,idNeg);
327  double phiPos = idPos->phi();
328  m_varValues["phiPos"] = phiPos;
329  double phiNeg = idNeg->phi();
330  m_varValues["phiNeg"] = phiNeg;
331  m_varValues["pt"] = getPt(idPos,idNeg);
332  double ptPos = idPos->pt()/Gaudi::Units::GeV;
333  m_varValues["ptPos"] = ptPos;
334  double ptNeg = idNeg->pt()/Gaudi::Units::GeV;
335  m_varValues["ptNeg"] = ptNeg;
336 
337  m_varValues["crtDiff"] = getCrtDiff(idPos,idNeg);
338  m_varValues["etaDiff"] = etaPos - etaNeg;
339  double phiDiff = std::abs(phiPos - phiNeg);
340  if (phiDiff>Gaudi::Units::pi) phiDiff = 2*(Gaudi::Units::pi) - phiDiff;
341  m_varValues["phiDiff"] = phiDiff;
342  m_varValues["etaSumm"] = etaPos + etaNeg;
343  m_varValues["phiSumm"] = phiPos + phiNeg;
344 
345  //determine which region muons are in
346  std::string region = "";
347  if ((std::abs(etaPos)<1.05 || std::abs(etaPos)==1.05) && (std::abs(etaNeg)<1.05 || std::abs(etaNeg)==1.05)) region="BB";
348  else if ((etaPos>1.05 && etaPos<2.5) && (etaNeg>1.05 && etaNeg<2.5)) region="EAEA";
349  else if ((etaPos<-1.05 && etaPos>-2.5) && (etaNeg<-1.05 && etaNeg>-2.5)) region="ECEC";
350 
351  //do we care about hese muons?
352  bool fillAll = m_invmass.find("All")!=m_invmass.end();
353  bool fillReg = false;
354  if (region!=""){
355  if (m_invmass.find(region)!=m_invmass.end()) fillReg=true;
356  }
357  if (!fillAll && !fillReg) continue;
358 
359 
360  //fill invmass histos
361  if (fillAll) m_invmass["All"]->Fill(invmass);
362  if (fillReg) m_invmass[region]->Fill(invmass);
363 
364  //fill 2D histos
365  //first, retrieve the overlap of the width and mean variable lists which by construction is the list of vars in the 2D histos map
366  std::map<std::string, TH2F*>* allVars = nullptr;
367  if (fillAll){
368  allVars = &m_2DinvmassVSx["All"];
369  } else { //fillReg=true
370  allVars = &m_2DinvmassVSx[region];
371  }
372 
373  for (const std::pair<const std::string, TH2F*>& p : *allVars) {
374  if (p.first!="etaAll" && p.first!="phiAll" && p.first!="ptAll"){
375  if (fillAll) m_2DinvmassVSx["All"][p.first]->Fill(m_varValues[p.first],invmass);
376  if (fillReg) m_2DinvmassVSx[region][p.first]->Fill(m_varValues[p.first],invmass);
377  } else if (p.first=="etaAll"){
378  if (fillAll){
379  m_2DinvmassVSx["All"]["etaAll"]->Fill(etaPos,invmass);
380  m_2DinvmassVSx["All"]["etaAll"]->Fill(etaNeg,invmass);
381  }
382  if (fillReg){
383  m_2DinvmassVSx[region]["etaAll"]->Fill(etaPos,invmass);
384  m_2DinvmassVSx[region]["etaAll"]->Fill(etaNeg,invmass);
385  }
386  } else if (p.first=="phiAll"){
387  if (fillAll){
388  m_2DinvmassVSx["All"]["phiAll"]->Fill(phiPos,invmass);
389  m_2DinvmassVSx["All"]["phiAll"]->Fill(phiNeg,invmass);
390  }
391  if (fillReg){
392  m_2DinvmassVSx[region]["phiAll"]->Fill(phiPos,invmass);
393  m_2DinvmassVSx[region]["phiAll"]->Fill(phiNeg,invmass);
394  }
395  } else if (p.first=="ptAll"){
396  if (fillAll){
397  m_2DinvmassVSx["All"]["ptAll"]->Fill(ptPos,invmass);
398  m_2DinvmassVSx["All"]["ptAll"]->Fill(ptNeg,invmass);
399  }
400  if (fillReg){
401  m_2DinvmassVSx[region]["ptAll"]->Fill(ptPos,invmass);
402  m_2DinvmassVSx[region]["ptAll"]->Fill(ptNeg,invmass);
403  }
404  }
405  }
406 
407  //fill var distributions
408  //here we already know the list of variables so no need for gymnastics
409  for (const std::string& varD : m_varsDistr) {
410  if (varD!="etaAll" && varD!="phiAll" && varD!="ptAll"){
411  if (fillAll) m_xDistr["All"][varD]->Fill(m_varValues[varD]);
412  if (fillReg) m_xDistr[region][varD]->Fill(m_varValues[varD]);
413  } else if (varD=="etaAll"){
414  if (fillAll){
415  m_xDistr["All"]["etaAll"]->Fill(etaPos);
416  m_xDistr["All"]["etaAll"]->Fill(etaNeg);
417  }
418  if (fillReg){
419  m_xDistr[region]["etaAll"]->Fill(etaPos);
420  m_xDistr[region]["etaAll"]->Fill(etaNeg);
421  }
422  } else if (varD=="phiAll"){
423  if (fillAll){
424  m_xDistr["All"]["phiAll"]->Fill(phiPos);
425  m_xDistr["All"]["phiAll"]->Fill(phiNeg);
426  }
427  if (fillReg){
428  m_xDistr[region]["phiAll"]->Fill(phiPos);
429  m_xDistr[region]["phiAll"]->Fill(phiNeg);
430  }
431  } else if (varD=="ptAll"){
432  if (fillAll){
433  m_xDistr["All"]["ptAll"]->Fill(ptPos);
434  m_xDistr["All"]["ptAll"]->Fill(ptNeg);
435  }
436  if (fillReg){
437  m_xDistr[region]["ptAll"]->Fill(ptPos);
438  m_xDistr[region]["ptAll"]->Fill(ptNeg);
439  }
440  }
441  }
442 
443 
444  }// mu2 loop
445  }// mu1 loop
446  }// do we have more than 1 good muon?
447  return StatusCode::SUCCESS;
448 }
449 
450 
452 {
453 
454 
455  if(endOfRunFlag() && m_doFits) {
456  for (const std::string& reg : m_regions) {
457  for (const std::pair<const std::string, TH2F*>& p : m_2DinvmassVSx[reg]) {
458  int mode = 999.; //0 = both, 1 = mean only, 2 = wdth only
459  std::vector<TH1F*> hout;//1D histograms for fit results
460  if (m_invmassVSx[reg].find(p.first)!=m_invmassVSx[reg].end()){
461  if (m_widthVSx[reg].find(p.first)!=m_widthVSx[reg].end()) {
462  mode =0;
463  hout.push_back(m_invmassVSx[reg][p.first]);
464  hout.push_back(m_widthVSx[reg][p.first]);
465  } else {
466  mode = 1;
467  hout.push_back(m_invmassVSx[reg][p.first]);
468  }
469  } else {
470  mode = 2;
471  hout.push_back(m_widthVSx[reg][p.first]);
472  }
473  iterativeGausFit(m_2DinvmassVSx[reg][p.first],hout,mode);
474  } //variables
475  } //regions
476  } //isEndOfRun
477  return StatusCode::SUCCESS;
478 }
479 
480 
481 void DiMuMon::iterativeGausFit (TH2F* hin, const std::vector<TH1F*>& hout, int mode){
482  // a canvas may be needed when implmenting this into the post-processing file
483  TString hname = hin->GetName();
484  TString psName = hname + m_triggerChainName + ".ps";
485  TCanvas* ctemp = new TCanvas("ctemp","ctemp",500,500);
486  if (m_doSaveFits) ctemp->Print(psName+"[");
487  hin->SetMarkerSize(1.2);
488  hin->Draw();
489  if (m_doSaveFits) ctemp->Print(psName);
490  int nbins=hin->GetNbinsX();
491  for (int i=0; i<nbins;i++){
492  std::ostringstream o; o<<i;
493  TString projName = hname + o.str();
494  TH1D* htemp = (TH1D*) (hin->ProjectionY(projName,i+1,i+1)->Clone());
495  htemp->SetTitle(projName);
496  htemp->Sumw2();
497  if (htemp->GetEntries()>50){
498  double mean = 999., meanErr = 999., sigma = 999., sigmaErr = 999., chi2=0;
499  if (m_resonName == "Jpsi" || m_resonName == "Upsi"){
500  mean = htemp->GetMean();
501  sigma= htemp->GetRMS();
502  TF1* fn = new TF1("fn","gaus",mean-2*sigma,mean+2*sigma);
503  fn->SetParameters(float(htemp->GetEntries())/10.,mean,sigma);
504  htemp->Fit("fn","RMLQN");
505  mean = fn->GetParameter(1);
506  sigma= fn->GetParameter(2);
507  fn->SetRange(mean-1.2*sigma,mean+1.2*sigma);
508  fn->SetParameters(float(htemp->GetEntries())/10.,mean,sigma);
509  //gStyle->SetOptStat(1); // not thread-safe
510  if (m_doSaveFits) {
511  htemp->Fit("fn","RML");
512  ctemp->Print(psName);
513  } else htemp->Fit("fn","RMLQN");
514  double frange = 2.4*sigma;
515  double hrange = htemp->GetXaxis()->GetXmax()-htemp->GetXaxis()->GetXmin();
516  double ndf = frange/hrange*(htemp->GetNbinsX()) - 3;//substract the fit parameters
517  chi2 = (fn->GetChisquare())/ndf;
518  //fill results
519  mean = fn->GetParameter(1);
520  meanErr = fn->GetParError(1);
521  sigma = fn->GetParameter(2);
522  sigmaErr = fn->GetParError(2);
523  delete fn;
524  } else {
525  //fit Z peak with a convolution of BreitWigner and Crystal Ball fns, fit by Louise, implementation by Jike taken from IDPerfMon
526  RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL);
527  RooRealVar m("mass", "dimuon invariant mass", 91.2, 71., 111., "GeV");
528  RooDataHist *data = nullptr;
529  data = new RooDataHist("data", "data", m, htemp);
530  RooRealVar bwm0("bw_#mu", "bw_#mu", 91.2, 85.2, 97.2) ;
531  RooRealVar bwsg("bw_#sigma","bw_#sigma", 2.4952) ;
532  RooBreitWigner bw("bw","bw", m, bwm0, bwsg);
533 
534  RooRealVar cbm0("cb_#mu", "cb_#mu", 0 ) ;
535  RooRealVar cbsg("cb_#sigma", "cb_#sigma", 3., 1., 10.) ;
536  RooRealVar cbal("cb_#alpha", "cb_#alpha", 2.0) ;
537  RooRealVar cbn( "cb_n", "cb_n", 1., 0.05, 3.) ;
538  RooCBShape cb( "cb", "cb", m, cbm0, cbsg, cbal, cbn);
539 
540  m.setBins(5000);
541  RooFFTConvPdf bxc("bxc", "BW (X) CB", m, bw, cb) ;
542  bxc.fitTo(*data, RooFit::PrintLevel(-1), RooFit::PrintEvalErrors(-1));
543  RooPlot* frame = m.frame();
544  data->plotOn(frame, RooFit::MarkerSize(0.9));
545  bxc.paramOn(frame, RooFit::Format("NELU", RooFit::AutoPrecision(2)), RooFit::Layout(0.1,0.4,0.9));
546  bxc.plotOn (frame, RooFit::LineColor(kBlue));
547  if (m_doSaveFits) {
548  frame->Draw();
549  ctemp->Print(psName);
550  }
551  mean = bwm0.getVal();
552  meanErr = bwm0.getError();
553  sigma = cbsg.getVal();
554  sigmaErr = cbsg.getError();
555  chi2 = frame->chiSquare();
556  delete data;
557  }
558  //fill results
559  m_chi2->Fill(chi2);
560  if (mode == 0){//plot both invmass and width vs variable
561  hout.at(0)->SetBinContent(i+1,mean);
562  hout.at(0)->SetBinError(i+1,meanErr);
563  hout.at(1)->SetBinContent(i+1,sigma);
564  hout.at(1)->SetBinError(i+1,sigmaErr);
565  } else if (mode==1){//plot only invmass vs variable
566  hout.at(0)->SetBinContent(i+1,mean);
567  hout.at(0)->SetBinError(i+1,meanErr);
568  } else if (mode==2){//plot only width vs variable
569  hout.at(0)->SetBinContent(i+1,sigma);
570  hout.at(0)->SetBinError(i+1,sigmaErr);
571  }
572 
573  }// more than 50 events
574 
575  delete htemp;
576  }
577  hout.at(0)->Sumw2();
578  if (hout.size()==2) hout.at(1)->Sumw2();
579  if (m_doSaveFits) ctemp->Print(psName+"]");
580  delete ctemp;
581 }
582 
583 template<class T>
585 
586  StatusCode sc = mon.regHist(histo);
587  if (sc.isFailure() ) {
588  ATH_MSG_WARNING( "Cannot book histogram:" );
589  }
590 }
591 
593  int countPass = 0;
594  // https://twiki.cern.ch/twiki/bin/view/AtlasProtected/MCPAnalysisGuidelinesEPS2011
595  if (idTrk) {
596  uint8_t dummy(-1);
597  bool eBLhits = idTrk->summaryValue( dummy, xAOD::expectInnermostPixelLayerHit )? dummy :false;
598  int nBLhits = idTrk->summaryValue( dummy, xAOD::numberOfInnermostPixelLayerHits )? dummy :-1;
599  int nhitsPIX = idTrk->summaryValue( dummy, xAOD::numberOfPixelHits )? dummy :-1;
600  int nPIXDS = idTrk->summaryValue( dummy, xAOD::numberOfPixelDeadSensors )? dummy :-1;
601  int nhitsSCT = idTrk->summaryValue( dummy, xAOD::numberOfSCTHits )? dummy :-1;
602  int nSCTDS = idTrk->summaryValue( dummy, xAOD::numberOfSCTDeadSensors )? dummy :-1;
603  int nPIXH = idTrk->summaryValue( dummy, xAOD::numberOfPixelHoles )? dummy :-1;
604  int nSCTH = idTrk->summaryValue( dummy, xAOD::numberOfSCTHoles )? dummy :-1;
605 
606  if (nBLhits>0 || !(eBLhits)) countPass+=1;
607  if ((nhitsPIX+nPIXDS)>1) countPass+=1;
608  if ((nhitsSCT+nSCTDS)>5) countPass+=1;
609  if ((nPIXH+nSCTH)<3) countPass+=1;
610  int nTRTout = idTrk->summaryValue( dummy, xAOD::numberOfTRTOutliers )? dummy :-1;
611  int nTRThits = idTrk->summaryValue( dummy, xAOD::numberOfTRTHits )? dummy :-1;
612  int n = nTRTout + nTRThits;
613  if (std::abs(idTrk->eta())<1.9){
614  if (n>5 && nTRTout<(0.9*n)) countPass+=1;
615  } else {
616  if (n>5){
617  if (nTRTout<(0.9*n)) countPass+=1;
618  } else countPass+=1;
619  }
620  }
621  else{
622  ATH_MSG_WARNING("Trying to check trackquality but no xAOD::TrackParticle available!");
623  }
624  return countPass==5;
625 }
626 
627 //methods from IDPerformanceMoniroting by Weina
628 double DiMuMon::getInvmass(const xAOD::TrackParticle* id1, const xAOD::TrackParticle* id2, double Mass) const {
629  TLorentzVector particle1,particle2,v;
630  particle1.SetPtEtaPhiE(id1->pt(),id1->eta(),id1->phi(),sqrt(pow(Mass,2)+pow(id1->p4().Px(),2)+pow(id1->p4().Py(),2)+pow(id1->p4().Pz(),2)));
631  particle2.SetPtEtaPhiE(id2->pt(),id2->eta(),id2->phi(),sqrt(pow(Mass,2)+pow(id2->p4().Px(),2)+pow(id2->p4().Py(),2)+pow(id2->p4().Pz(),2)));
632  v=particle1+particle2;
633  double invmass = v.Mag()/Gaudi::Units::GeV;
634  return invmass;
635 }
636 
637 double DiMuMon::getPt(const xAOD::TrackParticle* id1, const xAOD::TrackParticle* id2 ) const {
638  double transmom;
639  double px = id1->p4().Px()+id2->p4().Px();
640  double py = id1->p4().Py()+id2->p4().Py();
641  transmom=sqrt(px*px+py*py);
642  return transmom/Gaudi::Units::GeV; //Gev
643 }
644 
645 double DiMuMon::getEta(const xAOD::TrackParticle* id1, const xAOD::TrackParticle* id2 ) const {
646  double eta;
647  double px=id1->p4().Px()+id2->p4().Px();
648  double py = id1->p4().Py()+id2->p4().Py();
649  double pz = id1->p4().Pz()+id2->p4().Pz();
650  double p=sqrt(px*px+py*py+pz*pz);
651  eta=0.5*log((p+pz)/(p-pz));
652  return eta;
653 }
654 
655 double DiMuMon::getPhi(const xAOD::TrackParticle* id1, const xAOD::TrackParticle* id2 ) const {
656  double px=id1->p4().Px()+id2->p4().Px();
657  double py = id1->p4().Py()+id2->p4().Py();
658  double p=sqrt(px*px+py*py);
659  double phi=acos(px/p);
660  if (py<0.) phi=-1.*phi;
661  return phi;
662 }
663 //curvature difference unit 1/GeV
665  double qoverpt1=id1->charge()/id1->pt();
666  double qoverpt2=id2->charge()/id2->pt();
667  double asym;
668  asym=std::abs(qoverpt1)-std::abs(qoverpt2);
669  return asym*1000;
670 }
671 
672 
covarianceTool.ndf
ndf
Definition: covarianceTool.py:678
xAOD::TrackParticle_v1::pt
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition: TrackParticle_v1.cxx:74
xAOD::numberOfPixelHoles
@ numberOfPixelHoles
number of pixel layers on track with absence of hits [unit8_t].
Definition: TrackingPrimitives.h:262
DiMuMon::procHistograms
virtual StatusCode procHistograms()
An inheriting class should either override this function or finalHists().
Definition: DiMuMon.cxx:451
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:196
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
GeV
#define GeV
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/Root/HelperFunctions.cxx:18
DiMuMon::m_varRanges
std::map< std::string, std::pair< double, double > > m_varRanges
Definition: DiMuMon.h:77
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
DiMuMon::fillHistograms
virtual StatusCode fillHistograms()
An inheriting class should either override this function or fillHists().
Definition: DiMuMon.cxx:245
pdg_comparison.sigma
sigma
Definition: pdg_comparison.py:324
mean
void mean(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
Definition: dependence.cxx:254
test_pyathena.px
px
Definition: test_pyathena.py:18
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
python.Constants.FATAL
int FATAL
Definition: Control/AthenaCommon/python/Constants.py:18
DiMuMon::getEta
double getEta(const xAOD::TrackParticle *id1, const xAOD::TrackParticle *id2) const
Definition: DiMuMon.cxx:645
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:558
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
DiMuMon::m_varsVSmean
std::vector< std::string > m_varsVSmean
Definition: DiMuMon.h:74
DiMuMon::m_varsVSwidth
std::vector< std::string > m_varsVSwidth
Definition: DiMuMon.h:75
ManagedMonitorToolBase
Provides functionality for users to implement and save histograms, ntuples, and summary data,...
Definition: ManagedMonitorToolBase.h:73
SG::VIEW_ELEMENTS
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Definition: OwnershipPolicy.h:18
ConstDataVector::end
iterator end() noexcept
Return an iterator pointing past the end of the collection.
xAOD::TrackParticle_v1::charge
float charge() const
Returns the charge.
Definition: TrackParticle_v1.cxx:151
dqt_zlumi_pandas.hname
string hname
Definition: dqt_zlumi_pandas.py:280
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:83
ConstDataVector.h
DataVector adapter that acts like it holds const pointers.
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
xAOD::TrackParticle_v1::eta
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
Definition: TrackParticle_v1.cxx:78
StateLessPT_NewConfig.Format
Format
Definition: StateLessPT_NewConfig.py:149
ParticleConstants::PDG2011::muonMassInMeV
constexpr double muonMassInMeV
the mass of the muon (in MeV)
Definition: ParticleConstants.h:29
DiMuMon::m_chi2
TH1F * m_chi2
Definition: DiMuMon.h:81
xAOD::TrackParticle_v1::summaryValue
bool summaryValue(uint8_t &value, const SummaryType &information) const
Accessor for TrackSummary values.
Definition: TrackParticle_v1.cxx:737
AthenaMonManager::cosmics
@ cosmics
Definition: AthenaMonManager.h:58
DiMuMon.h
python.SystemOfUnits.second
float second
Definition: SystemOfUnits.py:135
DiMuMon::getPt
double getPt(const xAOD::TrackParticle *id1, const xAOD::TrackParticle *id2) const
Definition: DiMuMon.cxx:637
DiMuMon::m_resonName
std::string m_resonName
Definition: DiMuMon.h:64
xAOD::numberOfPixelHits
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
Definition: TrackingPrimitives.h:260
DiMuMon::m_isolationCut
double m_isolationCut
Definition: DiMuMon.h:58
xAOD::expectInnermostPixelLayerHit
@ expectInnermostPixelLayerHit
Do we expect a 0th-layer barrel hit for this track?
Definition: TrackingPrimitives.h:237
xAOD::numberOfTRTHits
@ numberOfTRTHits
number of TRT hits [unit8_t].
Definition: TrackingPrimitives.h:276
DiMuMon::m_nVarBins
int m_nVarBins
Definition: DiMuMon.h:52
DiMuMon::~DiMuMon
virtual ~DiMuMon()
Definition: DiMuMon.cxx:59
DiMuMon::m_nEtaBins
int m_nEtaBins
Definition: DiMuMon.h:54
python.TrigEgammaMonitorHelper.TH2F
def TH2F(name, title, nxbins, bins_par2, bins_par3, bins_par4, bins_par5=None, bins_par6=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:45
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
pi
#define pi
Definition: TileMuonFitter.cxx:65
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:92
DiMuMon::m_xDistr
std::map< std::string, std::map< std::string, TH1F * > > m_xDistr
Definition: DiMuMon.h:87
AthenaMonManager::environment
static Environment_t environment()
Returns the running environment of the monitoring application to help ManagedMonitorToolBase objects ...
Definition: AthenaMonManager.cxx:297
DiMuMon::m_invmass
std::map< std::string, TH1F * > m_invmass
Definition: DiMuMon.h:83
instance
std::map< std::string, double > instance
Definition: Run_To_Get_Tags.h:8
DiMuMon::m_etaCut
double m_etaCut
Definition: DiMuMon.h:62
xAOD::TrackParticle_v1::p4
virtual FourMom_t p4() const override final
The full 4-momentum of the particle.
Definition: TrackParticle_v1.cxx:130
DiMuMon::m_setDebug
bool m_setDebug
Definition: DiMuMon.h:70
ManagedMonitorToolBase::MonGroup
A container of information describing a monitoring object.
Definition: ManagedMonitorToolBase.h:137
DiMuMon::m_stat
TH1F * m_stat
Definition: DiMuMon.h:82
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
python.getCurrentFolderTag.fn
fn
Definition: getCurrentFolderTag.py:79
AthenaMonManager::dataType
static DataType_t dataType()
Returns the data type that the monitoring application is running over to help ManagedMonitorToolBase ...
Definition: AthenaMonManager.cxx:314
ManagedMonitorToolBase::initialize
virtual StatusCode initialize()
Definition: ManagedMonitorToolBase.cxx:616
id2
HWIdentifier id2
Definition: LArRodBlockPhysicsV0.cxx:562
ParticleConstants.h
lumiFormat.i
int i
Definition: lumiFormat.py:85
DiMuMon::m_2DinvmassVSx
std::map< std::string, std::map< std::string, TH2F * > > m_2DinvmassVSx
Definition: DiMuMon.h:84
DiMuMon::m_invmassVSx
std::map< std::string, std::map< std::string, TH1F * > > m_invmassVSx
Definition: DiMuMon.h:85
beamspotman.n
n
Definition: beamspotman.py:729
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
AthenaMonManager::online
@ online
Definition: AthenaMonManager.h:49
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
Definition: AthCommonDataStore.h:145
CalibDbCompareRT.dummy
dummy
Definition: CalibDbCompareRT.py:59
chi2
double chi2(TH1 *h0, TH1 *h1)
Definition: comparitor.cxx:525
Amg::pz
@ pz
Definition: GeoPrimitives.h:40
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Preparation.mode
mode
Definition: Preparation.py:107
jet::CompScaleVar::Mass
@ Mass
Definition: UncertaintyEnum.h:98
run
Definition: run.py:1
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
xAOD::numberOfSCTHoles
@ numberOfSCTHoles
number of SCT holes [unit8_t].
Definition: TrackingPrimitives.h:271
DiMuMon::m_coneSize
double m_coneSize
Definition: DiMuMon.h:57
DiMuMon::m_minInvmass
double m_minInvmass
Definition: DiMuMon.h:59
DiMuMon::m_nPtBins
int m_nPtBins
Definition: DiMuMon.h:53
DiMuMon::m_muonCollection
SG::ReadHandleKey< xAOD::MuonContainer > m_muonCollection
Definition: DiMuMon.h:66
DiMuMon::m_widthVSx
std::map< std::string, std::map< std::string, TH1F * > > m_widthVSx
Definition: DiMuMon.h:86
DiMuMon::m_maxInvmass
double m_maxInvmass
Definition: DiMuMon.h:60
Amg::py
@ py
Definition: GeoPrimitives.h:39
DiMuMon::m_doFits
bool m_doFits
Definition: DiMuMon.h:68
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
DiMuMon::m_triggerChainName
std::string m_triggerChainName
Definition: DiMuMon.h:65
ConstDataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
DiMuMon::getPhi
double getPhi(const xAOD::TrackParticle *id1, const xAOD::TrackParticle *id2) const
Definition: DiMuMon.cxx:655
DiMuMon::m_varValues
std::map< std::string, double > m_varValues
Definition: DiMuMon.h:78
DiMuMon::getCrtDiff
double getCrtDiff(const xAOD::TrackParticle *id1, const xAOD::TrackParticle *id2) const
Definition: DiMuMon.cxx:664
SCT_CalibAlgs::nbins
@ nbins
Definition: SCT_CalibNumbers.h:10
DiMuMon::m_doSaveFits
bool m_doSaveFits
Definition: DiMuMon.h:69
DiMuMon::bookHistograms
virtual StatusCode bookHistograms()
An inheriting class should either override this function or bookHists().
Definition: DiMuMon.cxx:133
xAOD::Iso::ptcone40
@ ptcone40
Definition: IsolationType.h:42
xAOD::numberOfTRTOutliers
@ numberOfTRTOutliers
number of TRT outliers [unit8_t].
Definition: TrackingPrimitives.h:277
python.PyAthena.v
v
Definition: PyAthena.py:154
DiMuMon::trackQuality
bool trackQuality(const xAOD::TrackParticle *idTrk)
Definition: DiMuMon.cxx:592
DiMuMon::m_regions
std::vector< std::string > m_regions
Definition: DiMuMon.h:73
DiMuMon::initialize
virtual StatusCode initialize()
Definition: DiMuMon.cxx:63
DiMuMon::iterativeGausFit
void iterativeGausFit(TH2F *hin, const std::vector< TH1F * > &hout, int mode)
Definition: DiMuMon.cxx:481
DiMuMon::DiMuMon
DiMuMon(const std::string &type, const std::string &name, const IInterface *parent)
Definition: DiMuMon.cxx:34
StateLessPT_NewConfig.Layout
Layout
Definition: StateLessPT_NewConfig.py:162
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
xAOD::numberOfSCTDeadSensors
@ numberOfSCTDeadSensors
number of dead SCT sensors crossed [unit8_t].
Definition: TrackingPrimitives.h:274
ConstDataVector
DataVector adapter that acts like it holds const pointers.
Definition: ConstDataVector.h:76
ManagedMonitorToolBase::endOfRunFlag
bool endOfRunFlag() const
Definition: ManagedMonitorToolBase.h:797
DeMoScan.first
bool first
Definition: DeMoScan.py:534
plotBeamSpotMon.mon
mon
Definition: plotBeamSpotMon.py:66
DiMuMon::RegisterHisto
void RegisterHisto(MonGroup &mon, T *histo)
Definition: DiMuMon.cxx:584
DiMuMon::m_nPhiBins
int m_nPhiBins
Definition: DiMuMon.h:55
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
xAOD::numberOfSCTHits
@ numberOfSCTHits
number of hits in SCT [unit8_t].
Definition: TrackingPrimitives.h:269
DiMuMon::m_ptCut
double m_ptCut
Definition: DiMuMon.h:61
xAOD::numberOfPixelDeadSensors
@ numberOfPixelDeadSensors
number of dead pixel sensors crossed [unit8_t].
Definition: TrackingPrimitives.h:267
python.TrigEgammaMonitorHelper.TH1F
def TH1F(name, title, nxbins, bins_par2, bins_par3=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:24
DiMuMon::m_varsDistr
std::vector< std::string > m_varsDistr
Definition: DiMuMon.h:76
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
plotBeamSpotCompare.histo
histo
Definition: plotBeamSpotCompare.py:414
checker_macros.h
Define macros for attributes used to control the static checker.
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
ConstDataVector::begin
iterator begin() noexcept
Return an iterator pointing at the beginning of the collection.
DiMuMon::m_nMassBins
int m_nMassBins
Definition: DiMuMon.h:51
DiMuMon::getInvmass
double getInvmass(const xAOD::TrackParticle *track1, const xAOD::TrackParticle *track2, double Mass) const
Definition: DiMuMon.cxx:628
TSU::T
unsigned long long T
Definition: L1TopoDataTypes.h:35
xAOD::TrackParticle_v1::phi
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .)
xAOD::numberOfInnermostPixelLayerHits
@ numberOfInnermostPixelLayerHits
these are the hits in the 0th pixel barrel layer
Definition: TrackingPrimitives.h:238
python.SystemOfUnits.m
float m
Definition: SystemOfUnits.py:106
ManagedMonitorToolBase::newRunFlag
bool newRunFlag() const
Definition: ManagedMonitorToolBase.h:792
DiMuMon::m_varLabels
std::map< std::string, std::string > m_varLabels
Definition: DiMuMon.h:79