ATLAS Offline Software
Loading...
Searching...
No Matches
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
34DiMuMon::DiMuMon( const std::string & type, const std::string & name, const IInterface* parent )
35 : ManagedMonitorToolBase( type, name, 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
62
64
66 ATH_CHECK( m_muonCollection.initialize() );
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}]";
197 m_2DinvmassVSx[reg][varM] = new TH2F(hname, htitle ,m_nVarBins,m_varRanges[varM].first, m_varRanges[varM].second, m_nMassBins, m_minInvmass, m_maxInvmass);
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}]";
212 m_2DinvmassVSx[reg][varW] = new TH2F(hname, htitle ,m_nVarBins, m_varRanges[varW].first, m_varRanges[varW].second, m_nMassBins, m_minInvmass, m_maxInvmass);
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){
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
481void 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
583template<class T>
584void DiMuMon::RegisterHisto(MonGroup& mon, T* histo) {
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
628double 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
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
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
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
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
DataVector adapter that acts like it holds const pointers.
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t sc
HWIdentifier id2
A number of constexpr particle constants to avoid hardcoding them directly in various places.
constexpr int pow(int base, int exp) noexcept
Define macros for attributes used to control the static checker.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
static Environment_t environment()
Returns the running environment of the monitoring application to help ManagedMonitorToolBase objects ...
static DataType_t dataType()
Returns the data type that the monitoring application is running over to help ManagedMonitorToolBase ...
DataVector adapter that acts like it holds const pointers.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
iterator begin() noexcept
Return an iterator pointing at the beginning of the collection.
iterator end() noexcept
Return an iterator pointing past the end of the collection.
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
std::map< std::string, std::map< std::string, TH2F * > > m_2DinvmassVSx
Definition DiMuMon.h:84
double m_maxInvmass
Definition DiMuMon.h:60
std::map< std::string, std::pair< double, double > > m_varRanges
Definition DiMuMon.h:77
std::string m_resonName
Definition DiMuMon.h:64
std::map< std::string, double > m_varValues
Definition DiMuMon.h:78
int m_nVarBins
Definition DiMuMon.h:52
std::map< std::string, std::map< std::string, TH1F * > > m_xDistr
Definition DiMuMon.h:87
std::map< std::string, std::map< std::string, TH1F * > > m_invmassVSx
Definition DiMuMon.h:85
void iterativeGausFit(TH2F *hin, const std::vector< TH1F * > &hout, int mode)
Definition DiMuMon.cxx:481
bool m_doFits
Definition DiMuMon.h:68
virtual StatusCode bookHistograms()
An inheriting class should either override this function or bookHists().
Definition DiMuMon.cxx:133
double m_coneSize
Definition DiMuMon.h:57
int m_nPhiBins
Definition DiMuMon.h:55
std::map< std::string, std::map< std::string, TH1F * > > m_widthVSx
Definition DiMuMon.h:86
virtual ~DiMuMon()
Definition DiMuMon.cxx:59
virtual StatusCode initialize()
Definition DiMuMon.cxx:63
bool trackQuality(const xAOD::TrackParticle *idTrk)
Definition DiMuMon.cxx:592
double m_etaCut
Definition DiMuMon.h:62
std::map< std::string, TH1F * > m_invmass
Definition DiMuMon.h:83
int m_nMassBins
Definition DiMuMon.h:51
double getCrtDiff(const xAOD::TrackParticle *id1, const xAOD::TrackParticle *id2) const
Definition DiMuMon.cxx:664
int m_nEtaBins
Definition DiMuMon.h:54
std::string m_triggerChainName
Definition DiMuMon.h:65
int m_nPtBins
Definition DiMuMon.h:53
double m_isolationCut
Definition DiMuMon.h:58
std::vector< std::string > m_varsVSwidth
Definition DiMuMon.h:75
virtual StatusCode fillHistograms()
An inheriting class should either override this function or fillHists().
Definition DiMuMon.cxx:245
virtual StatusCode procHistograms()
An inheriting class should either override this function or finalHists().
Definition DiMuMon.cxx:451
std::vector< std::string > m_regions
Definition DiMuMon.h:73
bool m_setDebug
Definition DiMuMon.h:70
void RegisterHisto(MonGroup &mon, T *histo)
Definition DiMuMon.cxx:584
double getEta(const xAOD::TrackParticle *id1, const xAOD::TrackParticle *id2) const
Definition DiMuMon.cxx:645
double getPhi(const xAOD::TrackParticle *id1, const xAOD::TrackParticle *id2) const
Definition DiMuMon.cxx:655
TH1F * m_stat
Definition DiMuMon.h:82
SG::ReadHandleKey< xAOD::MuonContainer > m_muonCollection
Definition DiMuMon.h:66
DiMuMon(const std::string &type, const std::string &name, const IInterface *parent)
Definition DiMuMon.cxx:34
TH1F * m_chi2
Definition DiMuMon.h:81
double m_ptCut
Definition DiMuMon.h:61
double getPt(const xAOD::TrackParticle *id1, const xAOD::TrackParticle *id2) const
Definition DiMuMon.cxx:637
double getInvmass(const xAOD::TrackParticle *track1, const xAOD::TrackParticle *track2, double Mass) const
Definition DiMuMon.cxx:628
bool m_doSaveFits
Definition DiMuMon.h:69
std::vector< std::string > m_varsDistr
Definition DiMuMon.h:76
std::map< std::string, std::string > m_varLabels
Definition DiMuMon.h:79
double m_minInvmass
Definition DiMuMon.h:59
std::vector< std::string > m_varsVSmean
Definition DiMuMon.h:74
A container of information describing a monitoring object.
ManagedMonitorToolBase(const std::string &type, const std::string &name, const IInterface *parent)
virtual bool isValid() override final
Can the handle be successfully dereferenced?
virtual FourMom_t p4() const override final
The full 4-momentum of the particle.
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .)
bool summaryValue(uint8_t &value, const SummaryType &information) const
Accessor for TrackSummary values.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
float charge() const
Returns the charge.
double chi2(TH1 *h0, TH1 *h1)
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="")
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
constexpr double muonMassInMeV
the mass of the muon (in MeV)
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Definition run.py:1
TrackParticle_v1 TrackParticle
Reference the current persistent version:
@ expectInnermostPixelLayerHit
Do we expect a 0th-layer barrel hit for this track?
@ numberOfPixelHoles
number of pixel layers on track with absence of hits [unit8_t].
@ numberOfTRTHits
number of TRT hits [unit8_t].
@ numberOfSCTDeadSensors
number of dead SCT sensors crossed [unit8_t].
@ numberOfSCTHits
number of hits in SCT [unit8_t].
@ numberOfInnermostPixelLayerHits
these are the hits in the 0th pixel barrel layer
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
@ numberOfTRTOutliers
number of TRT outliers [unit8_t].
@ numberOfPixelDeadSensors
number of dead pixel sensors crossed [unit8_t].
@ numberOfSCTHoles
number of SCT holes [unit8_t].