ATLAS Offline Software
Loading...
Searching...
No Matches
FourMuonEvent.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//==================================================================================
6// Include files...
7//==================================================================================
8
9// This files header
11
12// Standard headers
13
14// Package Headers
16
17// ATLAS headers
20
21//#include "muonEvent/MuonParamDefs.h"
22
23#include "CLHEP/Random/RandFlat.h"
24
25//==================================================================================
26// Public Methods
27//==================================================================================
28
30{
31 m_xSampleName = "FourMuon";
32
33 m_container = PerfMonServices::MUON_COLLECTION; //PerfMonServices::ELECTRON_COLLECTION
34
35 m_doDebug = false;
36 m_workAsFourMuons = false;
39
40 // Setup the muon tags
41 m_uMuonTags = 4;
42 m_LeadingMuonPtCut = 20.;
44 m_MassWindowLow = 10.0;
45 m_MassWindowHigh = 125.0;
46 m_deltaXYcut = 0.1; // in mm
47 m_Z0GapCut = 5.0; // in mm
48 m_SelectMuonByIso = true;
49 m_SelectMuonByIP = true;
50 m_eventCount = 0;
54
55 m_msgStream = new MsgStream(Athena::getMessageSvc(), "InDetPerformanceMonitoring" );
56}
57
58//==================================================================================
63
64//==================================================================================
66{
67 (*m_msgStream) << MSG::DEBUG << " * FourMuonEvent::Init * START *" << endmsg;
68
69 (*m_msgStream) << MSG::DEBUG << " * FourMuonEvent::Init * initializing muon selector *" << endmsg;
70 m_xMuonID.Init();
71 (*m_msgStream) << MSG::DEBUG << " * FourMuonEvent::Init * initializing electron selector *" << endmsg;
72 m_xElecID.Init();
73
74 if (m_workAsFourMuons) {(*m_msgStream) << MSG::INFO << " * FourMuonEvent::Init * working mode: 4 muons" << endmsg; }
75 if (m_workAsFourElectrons) {(*m_msgStream) << MSG::INFO << " * FourMuonEvent::Init * working mode: 4 electrons" << endmsg; }
76 if (m_workAsFourLeptons) {(*m_msgStream) << MSG::INFO << " * FourMuonEvent::Init * working mode: 4 leptons" << endmsg; }
77
79 (*m_msgStream) << MSG::DEBUG << " * FourMuonEvent::Init * Completed * " << endmsg;
80
81 return;
82}
83
84//==================================================================================
86{
88 (*m_msgStream) << MSG::DEBUG << " * FourMuonEvent::Reco * STARTING ** New event ** eventCount " << m_eventCount << endmsg;
89
90 // Clear out the previous events record.
91 this->Clear();
92
93 // if muons are requested
95 (*m_msgStream) << MSG::DEBUG << " * FourMuonEvent::Reco * retrieving xAOD::MuonContainer " << m_container << " of eventCount " << m_eventCount << std::endl;
96
98
99 // check if muon container does exist
100 if (pxMuonContainer != nullptr) {
101 (*m_msgStream) << MSG::DEBUG << " * FourMuonEvent::Reco * eventCount " << m_eventCount
102 << " track list has "<< pxMuonContainer->size()
103 << " combined muons in container " << m_container
104 << " container name: " << PerfMonServices::getContainerName ( m_container )
105 << endmsg;
106
107 xAOD::MuonContainer::const_iterator xMuonItr = pxMuonContainer->begin();
108 xAOD::MuonContainer::const_iterator xMuonItrE = pxMuonContainer->end();
109 int theCount = 0;
110 while ( xMuonItr != xMuonItrE ){ // start loop on muons
111 const xAOD::Muon* pxCMuon = *xMuonItr;
112 theCount++;
113 // Apply muon cuts
114 if ( m_xMuonID.passSelection( pxCMuon)) {
115 RecordMuon( pxCMuon );
116 (*m_msgStream) << MSG::DEBUG << " * FourMuonEvent::Reco ** muon " << theCount << " is accepted " << endmsg;
117 }
118 ++xMuonItr;
119 } // end loop on muons
120
121 // ordering of muons
122 this->OrderMuonList();
123 } // end muon container exists
124 if (!pxMuonContainer) {
125 std::cout << " * FourMuonEvent::Reco * Can't retrieve combined muon collection (container: " << m_container <<") " << std::endl;
126 return false;
127 } // end muon container does not exist
128 } // end requesting muons
129
130 //
131 // Electron selection (in case electrons are requested)
133 // Get the electron AOD container
134 const xAOD::ElectronContainer* pxElecContainer = nullptr;
135 if (m_doDebug){ std::cout << " * FourMuonEvent::Reco * retrieving xAOD::ElectronContainer " << PerfMonServices::ELECTRON_COLLECTION << std::endl; }
137
138 //pxElecContainer = evtStore()->retrieve( pxElecContainer, "Electrons" );
139
140 if (pxElecContainer != nullptr) {
141 (*m_msgStream) << MSG::DEBUG << " * FourMuonEvent::Reco * retrieving xAOD::ElectronContainer SUCCESS. "
143 << " size: " << pxElecContainer->size()
144 << endmsg;
145 if (pxElecContainer->size() > 0 ){
146 m_xElecID.PrepareElectronList (pxElecContainer);
147 m_numberOfFullPassElectrons = m_xElecID.GetElectronCollectionSize();
149 }
150 }
151 else { // no pxElecContainer
152 (*m_msgStream) << MSG::DEBUG << " * FourMuonEvent::Reco * retrieving xAOD::ElectronContainer -- FAILED -- eventcount: " << m_eventCount << endmsg;
153 }
154 }
155
157 // reached this point one has the list of muons and electrons in this event
159
160 // now check if the particles in the event make them to satisfy the event selection
161 if (m_workAsFourMuons) {
162 m_passedFourMuonSelection = false; // unless the event has 4 muons, assume it is not good
163
164 if (m_numberOfFullPassMuons == 4) {
168
170 m_FourMuonInvMass = m_fInvariantMass[ID]; // store invariant mass
171 if (m_doDebug) std::cout << " * FourMuonEvent::Reco * === Event " << m_eventCount << " is a GOOD 4-muon event " << std::endl;
172 }
173 else {
174 if (m_doDebug) std::cout << " * FourMuonEvent::Reco * === Event " << m_eventCount << " FAILS the 4-muon event selection " << std::endl;
175 }
176 }
177 } // end of workAsFourMuons
178
180 if (m_doDebug) std::cout << " * FourMuonEvent::Reco * applying 4 electron selection " << std::endl;
181 m_passedFourElectronSelection = false; // unless the event has 4 muons, assume it is not good
182
186
188 m_FourMuonInvMass = m_fInvariantMass[ID]; // store invariant mass
189 if (m_doDebug) std::cout << " * FourMuonEvent::Reco * === Event " << m_eventCount << " is a GOOD 4-electrom event " << std::endl;
190 }
191 else {
192 if (m_doDebug) std::cout << " * FourMuonEvent::Reco * === Event " << m_eventCount << " FAILS the 4-electron event selection " << std::endl;
193 }
194 }
195 else {
196 if (m_doDebug) std::cout << " * FourMuonEvent::Reco * === Event " << m_eventCount << " is not a 4-electron event " << std::endl;
197 }
198 } // end of workAsFourElectrons
199
200
202 if (m_doDebug) std::cout << " * FourMuonEvent::Reco * applying 4 lepton selection " << std::endl;
204
205 bool enoughleptons = false;
206 if (m_numberOfFullPassMuons == 4) enoughleptons = true;
207 if (m_numberOfFullPassElectrons == 4) enoughleptons = true;
208 if (m_numberOfFullPassMuons >= 2 && m_numberOfFullPassElectrons >= 2) enoughleptons = true;
209
210 if ( enoughleptons) {
211 if (m_doDebug) {
212 std::cout << " * FourMuonEvent::Reco * Global statistics: Total number of accepted muons so far: " << m_acceptedMuonCount
213 << " & electrons: " << m_acceptedElecCount << " integrated over all events "
214 << std::endl;
215 std::cout << " * FourMuonEvent::Reco * This event has " << m_numberOfFullPassMuons
216 << " muons & " << m_numberOfFullPassElectrons << " electrons --> try kinematics, vertex and event selection"
217 << std::endl;
218 }
222
224 m_FourMuonInvMass = m_fInvariantMass[ID]; // store invariant mass
225 (*m_msgStream) << MSG::INFO << " * FourMuonEvent::Reco * === Event " << m_eventCount << " is a GOOD 4-lepton event with inv mass: " << m_FourMuonInvMass << endmsg;
226 }
227 else {
228 (*m_msgStream) << MSG::DEBUG << " * FourMuonEvent::Reco * === Event " << m_eventCount << " -- FAILS -- the 4-lepton event selection " << endmsg;
229 }
230 }
231 else {
232 (*m_msgStream) << MSG::DEBUG << " * FourMuonEvent::Reco * 4lepton selection FAILURE. Not enough muons or electrons. Event has " << m_numberOfFullPassMuons
233 << " muons & " << m_numberOfFullPassElectrons << " electrons"
234 << endmsg;
235 }
236 }
237
238 m_passedSelectionCuts = false; // assume event is not good, but check the selection according to the use case
242
244
245 (*m_msgStream) << MSG::DEBUG << " * FourMuonEvent::Reco * COMPLETED * Event has " << m_numberOfFullPassMuons << " muons & "
246 << m_numberOfFullPassElectrons << " electrons. "
247 << " So far: " << m_acceptedEventCount << " events were accepted out of " << m_eventCount << " tested" << endmsg;
248
250}
251
252//==================================================================================
253// Protected Methods
254//==================================================================================
258
259//==================================================================================
260// Private Methods
261//==================================================================================
263{
264 bool inputdebug = m_doDebug;
265 //m_doDebug = true;
266
267 bool eventisgood = true;
268 (*m_msgStream) << MSG::DEBUG << " * FourMuonEvent::EventSelection( type= " << eType << ") ** started ** " << std::endl
269 << " event count: " << m_eventCount << std::endl
270 << " m_NumberOfFullPassMuons: " << m_numberOfFullPassMuons << std::endl
271 << " m_NumberOfFullPassElectrons: " << m_numberOfFullPassElectrons
272 << endmsg;
273
274
275 // Depending on mode: require a minimum of electrons or muons
276 if ( eventisgood && m_workAsFourMuons) {
277 if (m_numberOfFullPassMuons < 4) {
278 eventisgood = false;
279 if(m_doDebug) {std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") * Failing number of good muons == 4 :( "
280 <<" m_numberOfFullPassMuons= " << m_numberOfFullPassMuons << std::endl;
281 }
282 }
283 }
284
285 if ( eventisgood && m_workAsFourElectrons) {
287 eventisgood = false;
288 if(m_doDebug) {std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") * Failing number of good electrons == 4 :( "
289 <<" m_numberOfFullPassElectrons= " << m_numberOfFullPassElectrons << std::endl;
290 }
291 }
292 }
293
294 if ( eventisgood && m_workAsFourLeptons) {
295 bool thisselection = false;
296 if (m_numberOfFullPassMuons == 4) thisselection = true;
297 if (m_numberOfFullPassElectrons == 4) thisselection = true;
298 if (m_numberOfFullPassMuons >= 2 && m_numberOfFullPassElectrons >= 2) thisselection = true;
299 if (!thisselection) {
300 if(m_doDebug) {std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") * Failing number of good muons >= 2 && electrons >= 2 :( "
301 <<" m_numberOfFullPassMuons= " << m_numberOfFullPassMuons
302 <<" m_numberOfFullPassElectrons= " << m_numberOfFullPassElectrons << std::endl;
303 }
304 }
305 eventisgood = thisselection;
306 }
307
308 //
309 // momentum of the leptons
310 // loop over the muons and electrons and count how many pass the leadingPt and secondPt cut
311 unsigned int npassleadingpt = 0;
312 unsigned int npasssecondpt = 0;
313 if ( eventisgood && (m_workAsFourMuons || m_workAsFourLeptons) ) {
314 if (m_numberOfFullPassMuons >= 2) { // electrons pt cuts if there are some electrons
315 //for (unsigned int i=0; i < m_numberOfFullPassMuons; i++) {
316 for (unsigned int i=0; i < NUM_MUONS; i++) {
317 if (m_pxIDTrack[i] == nullptr) continue;
318 if(m_doDebug) {std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") * using muon " << i << " with pt: " << m_pxIDTrack[i]->pt() << std::endl;}
319 if (m_pxIDTrack[i]->pt() > m_LeadingMuonPtCut*CLHEP::GeV) npassleadingpt++;
320 if (m_pxIDTrack[i]->pt() > m_SecondMuonPtCut*CLHEP::GeV) npasssecondpt++;
321 }
322 if(m_doDebug) {std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") * #muons with pt > leading pt: " << m_LeadingMuonPtCut*CLHEP::GeV << " = " << npassleadingpt << std::endl;}
323 if(m_doDebug) {std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") * #muons with pt > second pt: " << m_SecondMuonPtCut*CLHEP::GeV << " = " << npasssecondpt << std::endl;}
324 if (npassleadingpt == 0) { // at least 1 muon must pass the leading pt cut
325 eventisgood = false;
326 if(m_doDebug) {std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") * Failing leading muon pt cut " << m_LeadingMuonPtCut*CLHEP::GeV << std::endl;}
327 }
328 if (npasssecondpt < m_numberOfFullPassMuons) { // all muons must pass the second pt cut
329 eventisgood = false;
330 if(m_doDebug) {std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") * Failing second muon pt cut " << m_LeadingMuonPtCut*CLHEP::GeV << std::endl;}
331 }
332 }
333 }
334
335 // four electrons case
336 if ( eventisgood && (m_workAsFourElectrons || m_workAsFourLeptons) ) {
337 npassleadingpt = 0;
338 npasssecondpt = 0;
339 if (m_numberOfFullPassElectrons >= 2) { // electrons pt cuts if there are some electrons
340 for (unsigned int i=0; i < NUM_MUONS; i++) {
341 if (m_pxELTrack[i] == nullptr) continue;
342 if (m_doDebug) {std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") * using electron " << i << " with pt: " << m_pxELTrack[i]->pt() << std::endl;}
343 if (m_pxELTrack[i]->pt() > m_LeadingMuonPtCut*CLHEP::GeV) npassleadingpt++;
344 if (m_pxELTrack[i]->pt() > m_SecondMuonPtCut*CLHEP::GeV) npasssecondpt++;
345 }
346 if(m_doDebug) {std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") * #elecs with pt > leading pt: " << m_LeadingMuonPtCut*CLHEP::GeV << " = " << npassleadingpt << std::endl;}
347 if(m_doDebug) {std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") * #elecs with pt > second pt: " << m_SecondMuonPtCut*CLHEP::GeV << " = " << npasssecondpt << std::endl;}
348 if (npassleadingpt == 0) { // at least 1 electron must pass the leading pt cut
349 eventisgood = false;
350 if(m_doDebug) {std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") * Failing leading electron pt cut " << m_LeadingMuonPtCut*CLHEP::GeV << std::endl;}
351 }
352 if (npasssecondpt < m_numberOfFullPassElectrons) { // all electrons must pass the second pt cut
353 eventisgood = false;
354 if(m_doDebug) {std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") * Failing second electrons pt cut " << m_LeadingMuonPtCut*CLHEP::GeV << std::endl;}
355 }
356 } // electron pt cuts apply if there are some electrons
357 }
358
359 // Invariant mass window
360 if (eventisgood) {
361 if ( m_fInvariantMass[eType] < m_MassWindowLow ) {
362 if(m_doDebug) {
363 std::cout <<" * FourMuonEvent::EventSelection * Failing mass window low cut: reco m= " << m_fInvariantMass[eType] << " > " << m_MassWindowLow << std::endl;
364 }
365 eventisgood = false;
366 }
367 if ( m_fInvariantMass[eType] > m_MassWindowHigh ) {
368 if(m_doDebug) {
369 std::cout <<" * FourMuonEvent::EventSelection * Failing mass window high cut: reco m= " << m_fInvariantMass[eType] << " > " << m_MassWindowHigh << std::endl;
370 }
371 eventisgood = false;
372 }
373 }
374
375 // check on vertices
376 if (eventisgood) {
377 bool vertexstatus = false;
378
379 std::vector <float> vtxListX; // coordinates of the vertex
380 std::vector <float> vtxListY;
381 std::vector <float> vtxListZ;
382 std::vector <int> vtxNpart; // count how many particles are in vertex
383
384 int noVertexCountMuon = 0;
385 int noVertexCountElec = 0;
386 if ( m_workAsFourMuons || m_workAsFourLeptons ) { // till here we have the muon vertices list
387 // loop on muons first
388 for (unsigned int imu = 0; imu < NUM_MUONS; imu++) {
389 if (m_pxMUTrack[imu] != nullptr) {
390 /* R21 SALVA --> vertex is not available in R22 --> A FIX IS NEEDED */
391 /*
392 if (m_pxMUTrack[imu]->vertex()) {
393 if (vtxListX.size()==0) { // this is the first vertex found
394 vtxListX.push_back(m_pxMUTrack[imu]->vertex()->x());
395 vtxListY.push_back(m_pxMUTrack[imu]->vertex()->y());
396 vtxListZ.push_back(m_pxMUTrack[imu]->vertex()->z());
397 vtxNpart.push_back(0); // initialize particle count to 0
398 }
399 // loop on existing vertices. Check if this particle shares one of the existing ones. If not, add a new vertex to the list
400 for (size_t ivtx=0; ivtx < vtxListX.size(); ivtx++) {
401 float deltaX = fabs(m_pxMUTrack[imu]->vertex()->x() - vtxListX.at(ivtx));
402 float deltaY = fabs(m_pxMUTrack[imu]->vertex()->y() - vtxListY.at(ivtx));
403 float deltaZ = fabs(m_pxMUTrack[imu]->vertex()->z() - vtxListZ.at(ivtx));
404
405 if (deltaX < m_deltaXYcut && deltaY < m_deltaXYcut && deltaZ < m_Z0GapCut) {
406 // this is an existing vertex
407 int npartinvtx = vtxNpart.at(ivtx);
408 npartinvtx++;
409 vtxNpart.at(ivtx) = npartinvtx;
410 // fill the variables that tells to which vertex is associated each muon // not very nice piece of code :(
411 m_muon_vtx[imu] = ivtx+1;
412 }
413 }
414 } // vertex exist
415
416 else { // no vertex
417 noVertexCountMuon++;
418 }
419 */
420 } // muon exist
421 } // end of loop on muons
422 } // end of using muons
423
424 if ( m_workAsFourElectrons || m_workAsFourLeptons ) { // till here we have the muon vertices list
425 // now loop on electrons
426 for (unsigned int iel = 0; iel < NUM_MUONS; iel++) {
427 if (m_pxELTrack[iel] != nullptr) {
428 /* R21 SALVA --> vertex is not available in R22 --> A FIX IS NEEDED */
429 /*
430 if (m_pxELTrack[iel]->vertex()) {
431 if (vtxListX.size()==0) { // this is the first vertex found
432 vtxListX.push_back(m_pxELTrack[iel]->vertex()->x());
433 vtxListY.push_back(m_pxELTrack[iel]->vertex()->y());
434 vtxListZ.push_back(m_pxELTrack[iel]->vertex()->z());
435 vtxNpart.push_back(0); // initialize particle count to 0
436 }
437 bool vertexmatchfound = false;
438 // loop on existing vertices. Check if this particle shares one of the existing ones. If not, add a new vertex to the list
439 for (unsigned int ivtx=0; ivtx < vtxListX.size(); ivtx++) {
440 float deltaX = fabs( m_pxELTrack[iel]->vertex()->x() - vtxListX.at(ivtx) );
441 float deltaY = fabs( m_pxELTrack[iel]->vertex()->y() - vtxListY.at(ivtx) );
442 float deltaZ = fabs( m_pxELTrack[iel]->vertex()->z() - vtxListZ.at(ivtx) );
443
444 if (deltaX < m_deltaXYcut && deltaY < m_deltaXYcut && deltaZ < m_Z0GapCut) {
445 // this is an existing vertex
446 int npartinvtx = vtxNpart.at(ivtx);
447 npartinvtx++;
448 vtxNpart.at(ivtx) = npartinvtx;
449 // fill the variables that tells to which vertex is associated each muon
450 m_elec_vtx[iel] = ivtx+1;
451 vertexmatchfound = true;
452 }
453 }
454 if (!vertexmatchfound) { // the electron is not in any of the previous listed vertices
455 // this is a new vertex
456 vtxListX.push_back(m_pxELTrack[iel]->vertex()->x());
457 vtxListY.push_back(m_pxELTrack[iel]->vertex()->y());
458 vtxListZ.push_back(m_pxELTrack[iel]->vertex()->z());
459 vtxNpart.push_back(1); // initialize particle count to 1
460 m_elec_vtx[iel] = vtxListX.size(); // this electron is in this new vertex
461 }
462 } // vertex exist
463 else { // no vertex
464 noVertexCountElec++;
465 }
466 */
467 } // electron exists
468 } // end of loop on electrons
469 } // end of using electrons
470
471 if ( m_workAsFourMuons ) { // till here we have the muon vertices list
472 m_nVertex = vtxListX.size();
473 if (vtxListX.size()>0) vertexstatus = true;
474 // check that the muons are not split into too many vertices
475 if (vtxListX.size() >= m_numberOfFullPassMuons - 1) vertexstatus = false;
476 // allow no muon without vertex
477 if (noVertexCountMuon > 0) vertexstatus = false;
478 if (m_doDebug || true) {
479 std::cout << " * FourMuonEvent::EventSelection(" << eType <<") * vertices ID of the muons = " << std::endl
480 << " mu- 1 " << m_muon_vtx[0] << " pt: " << m_pxMUTrack[0]->pt() << std::endl
481 << " mu- 2 " << m_muon_vtx[1] << " pt: " << m_pxMUTrack[1]->pt() << std::endl
482 << " mu+ 1 " << m_muon_vtx[2] << " pt: " << m_pxMUTrack[2]->pt() << std::endl
483 << " mu+ 2 " << m_muon_vtx[3] << " pt: " << m_pxMUTrack[3]->pt()
484 << std::endl;
485 } // end debug
486 } // end m_workAsFourMuons
487
488 if ( m_workAsFourElectrons ) { // till here we have the electrons vertices list
489 m_nVertex = vtxListX.size();
490 if (vtxListX.size()>0) vertexstatus = true;
491 // check that the electrons are not split into too many vertices
492 if (vtxListX.size() >= m_numberOfFullPassElectrons - 1) vertexstatus = false;
493 // and allow no electron without vertex
494 if (noVertexCountElec > 0) vertexstatus = false;
495 if (m_doDebug || true) {
496 std::cout << " * FourMuonEvent::EventSelection(" << eType <<") * vertices ID of the electrons = " << std::endl
497 << " el- 1 " << m_elec_vtx[0] << " pt: " << m_pxELTrack[0]->pt() << std::endl
498 << " el- 2 " << m_elec_vtx[1] << " pt: " << m_pxELTrack[1]->pt() << std::endl
499 << " el+ 1 " << m_elec_vtx[2] << " pt: " << m_pxELTrack[2]->pt() << std::endl
500 << " el+ 2 " << m_elec_vtx[3] << " pt: " << m_pxELTrack[3]->pt()
501 << std::endl;
502 } // end debug
503 }
504
505 if ( m_workAsFourLeptons ) { // till here we have the muons and electrons vertices list
506 m_nVertex = vtxListX.size();
507 if (vtxListX.size()>0) vertexstatus = true;
508 // check that the electrons are not split into too many vertices
509 // if (vtxListX.size() >= m_numberOfFullPassElectrons - 1) vertexstatus = false;
510 // and allow no electron without vertex
511 if (m_doDebug) {
512 std::cout << " * FourMuonEvent::EventSelection(" << eType <<") * vertices in event = " << vtxListX.size() << std::endl;
513 for (size_t imu=0; imu < NUM_MUONS; imu++) {
514 if (m_pxMUTrack[imu]) std::cout << " mu " << m_muon_vtx[imu] << " pt: " << m_pxMUTrack[imu]->pt() << std::endl;
515 }
516 for (size_t iel=0; iel < NUM_MUONS; iel++) {
517 if (m_pxELTrack[iel]) std::cout << " el " << m_elec_vtx[iel] << " pt: " << m_pxELTrack[iel]->pt() << std::endl;
518 }
519 }
520 }
521
522 vertexstatus = true; // Temporary fix to work on R22
523
524 if(m_doDebug) {
525 std::cout <<" * FourMuonEvent::EventSelection(" << eType <<") * Number of vertex found = " << vtxListX.size()
526 << " and mu without vertex: " << noVertexCountMuon
527 << " and elec without vertex: " << noVertexCountElec << std::endl;
528 for (unsigned int ivtx=0; ivtx < vtxListX.size(); ivtx++) {
529 std::cout << " vtx[" << ivtx << "]= "
530 << "( " << vtxListX.at(ivtx)
531 << ", " << vtxListY.at(ivtx)
532 << ", " << vtxListZ.at(ivtx)
533 << ") nparticles: " << vtxNpart.at(ivtx)
534 << std::endl;
535 }
536 }
537 //
538 if (!vertexstatus && m_doDebug) {
539 std::cout <<" * FourMuonEvent::EventSelection * FAILED * number of vertex found = " << vtxListX.size()
540 << " mu without vertex: " << noVertexCountMuon
541 << " elec without vertex: " << noVertexCountElec << std::endl;
542 }
543
544 eventisgood = vertexstatus;
545 }
546
547 //
548 if(m_doDebug){ std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") ** completed ** result= " << eventisgood << std::endl;}
549
550 m_doDebug = inputdebug;
551
552 return eventisgood;
553}
554//==================================================================================
556{
557 if(m_doDebug){ std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") ** started ** " << std::endl
558 << " event count: " << m_eventCount << std::endl
559 << " m_NumberOfFullPassMuons: " << m_numberOfFullPassMuons << std::endl
560 << " m_NumberOfFullPassElectrons: " << m_numberOfFullPassElectrons
561 << std::endl;
562 }
563
564 // First require two muon-id's with cuts pre-applied.
566 if(m_doDebug) {std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") * Failing number of good muons and electrons == 4 :( "
568 << " = " << m_numberOfFullPassMuons << " + " << m_numberOfFullPassElectrons << std::endl;}
569 return false;
570 }
571
572 if ( m_numberOfFullPassMuons > 4 ) {
573 if(m_doDebug) {std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") * Too many muons !! Failing number of good muons == 4 :( "
574 << m_numberOfFullPassMuons << std::endl;}
575 return false;
576 }
577
578 if ( m_numberOfFullPassElectrons > 4 ) {
579 if(m_doDebug) {std::cout <<" * FourMuonEvent::EventSelection(" << eType << ") * Too many electrons !! Failing number of good electrons == 4 :( "
580 << m_numberOfFullPassElectrons << std::endl;}
581 return false;
582 }
583
584 // momentum of the muons
585 double leadingMuonPt = -1., secondMuonPt=-1., thirdMuonPt=-1, fourthMuonPt=-1.; // negative pt, means not computed yet
586 switch ( eType ) {
587 case MS :
588 {
589 if (m_muonpos1 >= 0) leadingMuonPt = m_pxMSTrack[m_muonpos1]->pt();
590 if (m_muonpos2 >= 0) secondMuonPt = m_pxMSTrack[m_muonpos2]->pt();
591 if (m_muonneg1 >= 0) thirdMuonPt = m_pxMSTrack[m_muonneg1]->pt();
592 if (m_muonneg2 >= 0) fourthMuonPt = m_pxMSTrack[m_muonneg2]->pt();
593 break;
594 }
595 case ME:
596 {
597 if (m_muonpos1 >= 0) leadingMuonPt = m_pxMETrack[m_muonpos1]->pt();
598 if (m_muonpos2 >= 0) secondMuonPt = m_pxMETrack[m_muonpos2]->pt();
599 if (m_muonneg1 >= 0) thirdMuonPt = m_pxMETrack[m_muonneg1]->pt();
600 if (m_muonneg2 >= 0) fourthMuonPt = m_pxMETrack[m_muonneg2]->pt();
601 break;
602 }
603 case CB:
604 {
605 if (m_muonpos1 >= 0) leadingMuonPt = m_pxRecMuon[m_muonpos1]->pt();
606 if (m_muonpos2 >= 0) secondMuonPt = m_pxRecMuon[m_muonpos2]->pt();
607 if (m_muonneg1 >= 0) thirdMuonPt = m_pxRecMuon[m_muonneg1]->pt();
608 if (m_muonneg2 >= 0) fourthMuonPt = m_pxRecMuon[m_muonneg2]->pt();
609 break;
610 }
611 case ID:
612 {
613 if (m_muonpos1 >= 0) leadingMuonPt = m_pxIDTrack[m_muonpos1]->pt();
614 if (m_muonpos2 >= 0) secondMuonPt = m_pxIDTrack[m_muonpos2]->pt();
615 if (m_muonneg1 >= 0) thirdMuonPt = m_pxIDTrack[m_muonneg1]->pt();
616 if (m_muonneg2 >= 0) fourthMuonPt = m_pxIDTrack[m_muonneg2]->pt();
617 break;
618 }
619
620 default:
621 if (m_muonpos1 >= 0) leadingMuonPt = m_pxIDTrack[m_muonpos1]->pt();
622 if (m_muonpos2 >= 0) secondMuonPt = m_pxIDTrack[m_muonpos2]->pt();
623 if (m_muonneg1 >= 0) thirdMuonPt = m_pxIDTrack[m_muonneg1]->pt();
624 if (m_muonneg2 >= 0) fourthMuonPt = m_pxIDTrack[m_muonneg2]->pt();
625 } // end switch
626
627 // up to here the leading and second pt are not really in the right order.
628 // order the muon pt:
629 double theLeadingPt = leadingMuonPt;
630 if (secondMuonPt > theLeadingPt) { theLeadingPt = secondMuonPt;}
631 if (thirdMuonPt > theLeadingPt) { theLeadingPt = thirdMuonPt;}
632 if (fourthMuonPt > theLeadingPt) { theLeadingPt = fourthMuonPt;}
633
634 double theTrailingPt = leadingMuonPt;
635 if (secondMuonPt < theTrailingPt && secondMuonPt > 0) { theTrailingPt = secondMuonPt;}
636 if (thirdMuonPt < theTrailingPt && thirdMuonPt > 0) { theTrailingPt = thirdMuonPt;}
637 if (fourthMuonPt < theTrailingPt && fourthMuonPt > 0) { theTrailingPt = fourthMuonPt;}
638
639 if (m_doDebug || true) {
640 std::cout << " * FourMuonEvent::EventSelection * muon pt selection -- cuts: Leading: " << m_LeadingMuonPtCut*CLHEP::GeV << std::endl
641 << " 2nd: " << m_SecondMuonPtCut*CLHEP::GeV << std::endl;
642 std::cout << " Pt of muons in this event 1: " << leadingMuonPt << std::endl
643 << " 2: " << secondMuonPt << std::endl
644 << " 3: " << thirdMuonPt << std::endl
645 << " 4: " << fourthMuonPt << std::endl
646 << " leading Pt: " << theLeadingPt << std::endl
647 << " trailing Pt: " << theTrailingPt << std::endl;
648 }
649
650 // muon pt cut
651 if ( !(theLeadingPt > m_LeadingMuonPtCut*CLHEP::GeV && theTrailingPt > m_SecondMuonPtCut*CLHEP::GeV ) ) {
652 if(m_doDebug){
653 std::cout <<" * FourMuonEvent::EventSelection * Failing pt cut * Reco Pt: leading " << theLeadingPt << " --> trailing " << theTrailingPt << std::endl;
654 }
655 return false;
656 }
657 if(m_doDebug){
658 std::cout << " * FourMuonEvent::EventSelection * Event passed the pt cuts: leading muon pt: " << leadingMuonPt << std::endl;
659 std::cout << " trailing muon pt: " << theTrailingPt << std::endl;
660 }
661
662
663 // Invariant mass window
664 if ( m_fInvariantMass[eType] < m_MassWindowLow ) {
665 if(m_doDebug) {
666 std::cout <<" * FourMuonEvent::EventSelection * Failing mass window low cut: reco m= " << m_fInvariantMass[eType] << " > " << m_MassWindowLow << std::endl;
667 }
668 return false;
669 }
670 if ( m_fInvariantMass[eType] > m_MassWindowHigh ) {
671 if(m_doDebug) {
672 std::cout <<" * FourMuonEvent * Failing mass window high cut: reco m= " << m_fInvariantMass[eType] << " > " << m_MassWindowHigh << std::endl;
673 }
674 return false;
675 }
676 if(m_doDebug){
677 std::cout <<" * FourMuonEvent::EventSelection * Event passed the mass window: " << m_fInvariantMass[eType] << std::endl;
678 }
679
680
681 // All muons should come from the same vertex
682 // if the vertex information is used, that is already guaranteed, but if not, one has to check the z0
683
684 /* R21 SALVA --> vertex is not available in R22 --> A FIX IS NEEDED */
685 /*
686 if (eType == ID) {
687 bool vertexstatus = true;
688 if (m_pxIDTrack[m_muonpos1]->vertex() != nullptr) {
689 if(m_doDebug) {
690 std::cout <<" * FourMuonEvent::EventSelection * vertex of the muons -- ID Tracks --" << std::endl;
691 std::cout << " vertex muonpos_1 (x,y,z): (" << m_pxIDTrack[m_muonpos1]->vertex()->x()
692 << ", " << m_pxIDTrack[m_muonpos1]->vertex()->y()
693 << ", " << m_pxIDTrack[m_muonpos1]->vertex()->z()
694 << ") --> pt: " << m_pxIDTrack[m_muonpos1]->pt()
695 << std::endl;
696 }
697 }
698 else {
699 vertexstatus = false;
700 if(m_doDebug) std::cout <<" * FourMuonEvent::EventSelection * WARNING muonpos_1 (" << m_muonpos1 << ") has no vertex " << std::endl;
701 }
702 if (m_pxIDTrack[m_muonpos2]->vertex() != nullptr) {
703 if(m_doDebug) {
704 std::cout << " vertex muonpos_2 (x,y,z): (" << m_pxIDTrack[m_muonpos2]->vertex()->x()
705 << ", " << m_pxIDTrack[m_muonpos2]->vertex()->y()
706 << ", " << m_pxIDTrack[m_muonpos2]->vertex()->z()
707 << ") --> pt: " << m_pxIDTrack[m_muonpos2]->pt()
708 << std::endl;
709 }
710 }
711 else{
712 vertexstatus = false;
713 if(m_doDebug) std::cout <<" * FourMuonEvent::EventSelection * WARNING muonpos_2 (" << m_muonpos2 << ") has no vertex " << std::endl;
714 }
715 if (m_pxIDTrack[m_muonneg1]->vertex() != nullptr) {
716 if(m_doDebug) {
717 std::cout << " vertex muonneg_1 (x,y,z): (" << m_pxIDTrack[m_muonneg1]->vertex()->x()
718 << ", " << m_pxIDTrack[m_muonneg1]->vertex()->y()
719 << ", " << m_pxIDTrack[m_muonneg1]->vertex()->z()
720 << ") --> pt: " << m_pxIDTrack[m_muonneg1]->pt()
721 << std::endl;
722 }
723 }
724 else{
725 vertexstatus = false;
726 if(m_doDebug) std::cout <<" * FourMuonEvent::EventSelection * WARNING muonneg_1 (" << m_muonneg1 << ") has no vertex " << std::endl;
727 }
728
729 if (m_pxIDTrack[m_muonneg2]->vertex() != nullptr) {
730 if(m_doDebug) {
731 std::cout << " vertex muonneg_2 (x,y,z): (" << m_pxIDTrack[m_muonneg2]->vertex()->x()
732 << ", " << m_pxIDTrack[m_muonneg2]->vertex()->y()
733 << ", " << m_pxIDTrack[m_muonneg2]->vertex()->z()
734 << ") --> pt: " << m_pxIDTrack[m_muonneg2]->pt()
735 << std::endl;
736 }
737 }
738 else{
739 vertexstatus = false;
740 if(m_doDebug) std::cout <<" * FourMuonEvent::EventSelection * WARNING muonneg_2 (" << m_muonneg2 << ") has no vertex " << std::endl;
741 }
742 if (vertexstatus) { // this means: all muons have vertex associated. Let's check it is the same.
743 if(m_doDebug) std::cout << " -- debug -- * FourMuonEvent::EventSelection * let's find the number of muon-vertices... " << std::endl;
744
745 std::vector <float> vtxListX;
746 std::vector <float> vtxListZ;
747 float rGapCut = 0.1;
748 // add the vertex of the 1st in the list (the muonneg1)
749 vtxListX.push_back(m_pxIDTrack[m_muonneg1]->vertex()->x());
750 vtxListZ.push_back(m_pxIDTrack[m_muonneg1]->vertex()->z());
751 m_nVertex = 1; // for the time being there is just one vertex
752 m_muonneg1_vtx = m_nVertex; // and the muonneg1 is in that one
753 if(m_doDebug) {
754 std::cout << " * FourMuonEvent::EventSelection * muonneg1 in vertex: " << m_muonneg1_vtx << std::endl;
755 }
756
757 // m_muonneg 2
758 bool thisMuonIsInExistingVertex = false;
759 for (int ivtx=0; ivtx < (int) vtxListX.size(); ivtx++) {
760 if ( fabs(vtxListX.at(ivtx) - m_pxIDTrack[m_muonneg2]->vertex()->x()) < rGapCut &&
761 fabs(vtxListZ.at(ivtx) - m_pxIDTrack[m_muonneg2]->vertex()->z()) < m_Z0GapCut) {
762 // muonneg2 in an already listed vertex
763 m_muonneg2_vtx = ivtx+1;
764 thisMuonIsInExistingVertex = true;
765 }
766 }
767 if (thisMuonIsInExistingVertex) {
768 if(m_doDebug) {
769 std::cout << " * FourMuonEvent::EventSelection * muonneg2 in vertex: " << m_muonneg2_vtx << std::endl;
770 }
771 }
772 else {
773 m_nVertex += 1; // add new vertex
774 m_muonneg2_vtx = m_nVertex;
775 vtxListX.push_back(m_pxIDTrack[m_muonneg2]->vertex()->x());
776 vtxListZ.push_back(m_pxIDTrack[m_muonneg2]->vertex()->z());
777 if(m_doDebug) {
778 std::cout << " * FourMuonEvent::EventSelection * Add a new vertex to the list. Current size: " << vtxListX.size()
779 << " vtx.x= " << m_pxIDTrack[m_muonneg2]->vertex()->x()
780 << " vtx.y= " << m_pxIDTrack[m_muonneg2]->vertex()->y()
781 << " vtx.z= " << m_pxIDTrack[m_muonneg2]->vertex()->z()
782 << std::endl;
783 std::cout << " * FourMuonEvent::EventSelection * muonneg2 in vertex: " << m_muonneg2_vtx << std::endl;
784 }
785 }
786
787 // m_muonpos 1
788 thisMuonIsInExistingVertex = false;
789 for (int ivtx=0; ivtx < (int) vtxListX.size(); ivtx++) {
790 if ( fabs(vtxListX.at(ivtx) - m_pxIDTrack[m_muonpos1]->vertex()->x()) < rGapCut &&
791 fabs(vtxListZ.at(ivtx) - m_pxIDTrack[m_muonpos1]->vertex()->z()) < m_Z0GapCut) {
792 // muonneg2 in an already listed vertex
793 m_muonpos1_vtx = ivtx+1;
794 thisMuonIsInExistingVertex = true;
795 }
796 }
797 if (thisMuonIsInExistingVertex) {
798 if(m_doDebug) {
799 std::cout << " * FourMuonEvent::EventSelection * muonpos1 in vertex: " << m_muonpos1_vtx << std::endl;
800 }
801 }
802 else {
803 m_nVertex += 1; // add new vertex
804 m_muonpos1_vtx = m_nVertex;
805 vtxListX.push_back(m_pxIDTrack[m_muonpos1]->vertex()->x());
806 vtxListZ.push_back(m_pxIDTrack[m_muonpos1]->vertex()->z());
807 if(m_doDebug) {
808 std::cout << " * FourMuonEvent::EventSelection * Add a new vertex to the list. Current size: " << vtxListX.size()
809 << " vtx.x= " << m_pxIDTrack[m_muonpos1]->vertex()->x()
810 << " vtx.y= " << m_pxIDTrack[m_muonpos1]->vertex()->y()
811 << " vtx.z= " << m_pxIDTrack[m_muonpos1]->vertex()->z()
812 << std::endl;
813 std::cout << " * FourMuonEvent::EventSelection * muonpos1 in vertex: " << m_muonpos1_vtx << std::endl;
814 }
815 }
816
817 // m_muonpos 2
818 thisMuonIsInExistingVertex = false;
819 for (int ivtx=0; ivtx < (int) vtxListX.size(); ivtx++) {
820 if ( fabs(vtxListX.at(ivtx) - m_pxIDTrack[m_muonpos2]->vertex()->x()) < rGapCut &&
821 fabs(vtxListZ.at(ivtx) - m_pxIDTrack[m_muonpos2]->vertex()->z()) < m_Z0GapCut) {
822 // muonneg2 in an already listed vertex
823 m_muonpos2_vtx = ivtx+1;
824 thisMuonIsInExistingVertex = true;
825 }
826 }
827 if (thisMuonIsInExistingVertex) {
828 if(m_doDebug) {
829 std::cout << " * FourMuonEvent::EventSelection * muonpos2 in vertex: " << m_muonpos1_vtx << std::endl;
830 }
831 }
832 else {
833 m_nVertex += 1; // add new vertex
834 m_muonpos2_vtx = m_nVertex;
835 vtxListX.push_back(m_pxIDTrack[m_muonpos2]->vertex()->x());
836 vtxListZ.push_back(m_pxIDTrack[m_muonpos2]->vertex()->z());
837 if(m_doDebug) {
838 std::cout << " * FourMuonEvent::EventSelection * Add a new vertex to the list. Current size: " << vtxListX.size()
839 << " vtx.x= " << m_pxIDTrack[m_muonpos2]->vertex()->x()
840 << " vtx.y= " << m_pxIDTrack[m_muonpos2]->vertex()->y()
841 << " vtx.z= " << m_pxIDTrack[m_muonpos2]->vertex()->z()
842 << std::endl;
843 std::cout << " * FourMuonEvent::EventSelection * muonpos2 in vertex: " << m_muonpos2_vtx << std::endl;
844 }
845 }
846 }
847
848 if (vertexstatus) {
849 if(m_doDebug) std::cout << " * FourMuonEvent::EventSelection ** All muons come from some vertex. " << std::endl
850 << " N listed vertex: " << m_nVertex << std::endl
851 << " muon- 1: " << m_muonneg1_vtx << std::endl
852 << " muon- 2: " << m_muonneg2_vtx << std::endl
853 << " muon+ 1: " << m_muonpos1_vtx << std::endl
854 << " muon+ 2: " << m_muonpos2_vtx << std::endl
855 << " Cut passed :) " << std::endl;
856 }
857 else { // vertex cut failed
858 if (m_doDebug) std::cout <<" * FourMuonEvent::EventSelection ** Failing all muons coming from a primary vertex cut :(" << std::endl;
859 return false;
860 }
861 } // if (eType == ID) {
862 */
863
864
865 if(m_doDebug) {
866 std::cout << " * FourMuonEvent::EventSelection( type= " << eType << ")* Good 4-muon set: pt range from " << leadingMuonPt/1000
867 << " to " << secondMuonPt/1000
868 << " GeV 4-muon invariant mass = " << m_fInvariantMass[eType] << " GeV " << std::endl;
869 std::cout << " * FourMuonEvent::EventSelection( type= " << eType << ")* completed * " << std::endl;
870 }
871 return true;
872}
873
874//==================================================================================
876{
879 m_passedSelectionCuts = false;
883
884
885 m_FourMuonInvMass = -1.; // flag as no reconstructed inv mass yet
886 m_muon1 = MUON1; // point to the first two
887 m_muon2 = MUON2;
888 m_muonneg1 = -1;
889 m_muonneg2 = -1;
890 m_muonpos1 = -1;
891 m_muonpos2 = -1;
892
893
894 for ( unsigned int u = 0; u < NUM_MUONS; ++u ) {
895 m_pxRecMuon[u] = nullptr;
896 m_pxMSTrack[u] = nullptr;
897 m_pxMETrack[u] = nullptr;
898 m_pxIDTrack[u] = nullptr;
899 m_pxMUTrack[u] = nullptr;
900 m_pxELTrack[u] = nullptr;
901 }
902 for ( unsigned int v = 0; v < NUM_TYPES; ++v ) {
903 m_fZPt[v] = -999.9f;
904 m_fZEtaDir[v] = -999.9f;
905 m_fZPhiDir[v] = -999.9f;
906 m_fInvariantMass[v] = -999.9f;
907 m_fMuonDispersion[v] = -999.9f;
908 }
909
910 // tell us to which vertex the muons are associated
911 m_nVertex = 0; // reset vertex count
912 m_muonneg1_vtx = 0;
913 m_muonneg2_vtx = 0;
914 m_muonpos1_vtx = 0;
915 m_muonpos2_vtx = 0;
916
917 for (size_t i=0; i < NUM_MUONS; i++) m_muon_vtx[i] = 0; // reset the vertex ID to which the electrons are associated
918 for (size_t i=0; i < NUM_MUONS; i++) m_elec_vtx[i] = 0; // reset the vertex ID to which the electrons are associated
919 return;
920}
921
922//==================================================================================
924{
925 bool thisdebug = false;
926 // if(m_doDebug){ std::cout <<" * FourMuonEvent * RecordMuon * started "<< std::endl;}
927 // This shouldn't really ever happen but just in case.
928 if ( !pxMuon ) {
929 if(m_doDebug){ std::cout <<" * FourMuonEvent * RecordMuon * bad pxMuon --> EXIT "<< std::endl;}
930 return;
931 }
932
934 // The main Muon
936 if (thisdebug) {
937 std::cout <<" * FourMuonEvent * RecordMuon * m_pxRecMuon for this muon--> pt "<< m_pxRecMuon[m_numberOfFullPassMuons]->pt() << std::endl;
938 std::cout <<" d0 "<< m_pxRecMuon[m_numberOfFullPassMuons]->primaryTrackParticle()->d0() << std::endl;
939 std::cout <<" sigma_d0 "<< m_pxRecMuon[m_numberOfFullPassMuons]->primaryTrackParticle()->definingParametersCovMatrixVec()[0] << std::endl;
940 }
941
942 const xAOD::TrackParticle* pxMSTrack = pxMuon->trackParticle(xAOD::Muon::MuonSpectrometerTrackParticle);
943 if (!pxMSTrack) {
944 if (m_doDebug){ std::cout <<" * FourMuonEvent * RecordMuon * bad pxMSmuon --> EXIT "<< std::endl;}
945 return;
946 }
948 if (thisdebug) {
949 std::cout <<" * FourMuonEvent * RecordMuon * m_pxMSTrack for this muon--> pt "<< m_pxMSTrack[m_numberOfFullPassMuons]->pt() << std::endl;
950 std::cout <<" d0 "<< m_pxMSTrack[m_numberOfFullPassMuons]->d0() << std::endl;
951 std::cout <<" sigma_d0 "<< m_pxMSTrack[m_numberOfFullPassMuons]->definingParametersCovMatrixVec()[0] << std::endl;
952 }
953
954 // ID muon
955 const xAOD::TrackParticle* pxIDTrack = pxMuon->trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
956 if (!pxIDTrack) {
957 if (m_doDebug){ std::cout <<" * FourMuonEvent * RecordMuon * bad pxIDTrack for this muon--> EXIT "<< std::endl;}
958 return;
959 }
961 if (thisdebug) {
962 std::cout <<" * FourMuonEvent * RecordMuon * m_pxIDTrack for this muon--> pt "<< m_pxIDTrack[m_numberOfFullPassMuons]->pt() << std::endl;
963 std::cout <<" d0 "<< m_pxIDTrack[m_numberOfFullPassMuons]->d0() << std::endl;
964 std::cout <<" sigma_d0 "<< m_pxIDTrack[m_numberOfFullPassMuons]->definingParametersCovMatrixVec()[0] << std::endl;
965 }
966 //
969 }
970 // if(m_doDebug){ std::cout <<" * FourMuonEvent * RecordMuon * completed -- return with a total of " << m_numberOfFullPassMuons << std::endl;}
971 return;
972}
973
974
975//==================================================================================
977{
978 if(m_doDebug){ std::cout << " * FourMuonEvent * ReconstructKinematics * -- start -- " << std::endl; }
979 bool kinematicscomputed = false;
980
981 // Three ways. No checks here. Thus make sure the pointers are ok before this.
982 if ( m_numberOfFullPassMuons == 4 ) {
983 // crosscheck identifiers are good:
984 bool goodidentifiers = true;
985 if (m_muonneg1 < 0) goodidentifiers = false;
986 if (m_muonneg2 < 0) goodidentifiers = false;
987 if (m_muonpos1 < 0) goodidentifiers = false;
988 if (m_muonpos2 < 0) goodidentifiers = false;
989
990 if (goodidentifiers) {
991 // before computing the kinematic parameters check track particles are ok
992 bool goodtracks = true;
993 if (m_pxIDTrack[m_muonneg1] == nullptr) goodtracks = false;
994 if (m_pxIDTrack[m_muonneg2] == nullptr) goodtracks = false;
995 if (m_pxIDTrack[m_muonpos1] == nullptr) goodtracks = false;
996 if (m_pxIDTrack[m_muonpos2] == nullptr) goodtracks = false;
997
1002
1003 if (goodtracks) { // Everything is ready
1005 m_fMuonDispersion[ID] = EvaluateAngle( m_pxMUTrack[0], m_pxMUTrack[2]); // leading mu- and leading mu+
1006 m_fZPt[ID] = EvalPt( m_pxMUTrack[0], m_pxMUTrack[2]); // leading mu- and leading mu+
1007 m_fZEtaDir[ID] = EvalEta( m_pxMUTrack[0], m_pxMUTrack[2]); // leading mu- and leading mu+
1008 m_fZPhiDir[ID] = EvalPhi( m_pxMUTrack[0], m_pxMUTrack[2]); // leading mu- and leading mu+
1009
1010 kinematicscomputed = true;
1011
1012 if(m_doDebug){
1013 std::cout << " * FourMuonEvent * ReconstructKinematics4Elec * -- Muon ID Tracks -- new -- " << std::endl
1014 << " Pt(mu1-)= " << m_pxMUTrack[0]->pt() << std::endl
1015 << " Pt(mu2-)= " << m_pxMUTrack[1]->pt() << std::endl
1016 << " Pt(mu1+)= " << m_pxMUTrack[2]->pt() << std::endl
1017 << " Pt(mu2+)= " << m_pxMUTrack[3]->pt() << std::endl
1018 << " invariant mass (4mu) = " << m_fInvariantMass[ID] << std::endl
1019 << std::endl;
1020 }
1021
1022 } // good tracks
1023 } // goodidentifiers
1024 } // goodmuons == 4
1025
1026 if (!kinematicscomputed) {
1027 if(m_doDebug){ std::cout <<" * FourMuonEvent * ReconstructKinematics * -- FAILED -- " << std::endl; }
1028 }
1029
1030 if(m_doDebug){ std::cout <<" * FourMuonEvent * ReconstructKinematics * -- completed -- status: " << kinematicscomputed << std::endl; }
1031 return kinematicscomputed;
1032}
1033
1034//==================================================================================
1036{
1037 if(m_doDebug){ std::cout << " * FourMuonEvent * ReconstructKinematics4Elec * -- start -- " << std::endl; }
1038 bool kinematicscomputed = false;
1039
1040 // Three ways. No checks here. Thus make sure the pointers are ok before this.
1041 if ( m_numberOfFullPassElectrons == 4 ) {
1042 // before computing the kinematic parameters check track particles are ok
1043 bool goodtracks = true;
1044 m_pxELTrack[0] = m_xElecID.GetElecNegTrackParticle(0);
1045 m_pxELTrack[1] = m_xElecID.GetElecNegTrackParticle(1);
1046 m_pxELTrack[2] = m_xElecID.GetElecPosTrackParticle(0);
1047 m_pxELTrack[3] = m_xElecID.GetElecPosTrackParticle(1);
1048 if (m_pxELTrack[0] == nullptr) goodtracks = false;
1049 if (m_pxELTrack[1] == nullptr) goodtracks = false;
1050 if (m_pxELTrack[2] == nullptr) goodtracks = false;
1051 if (m_pxELTrack[3] == nullptr) goodtracks = false;
1052
1053 if (goodtracks) { // Everything is ready
1054 // For the time being analysis is performed only with ID tracks
1056 m_fMuonDispersion[ID] = EvaluateAngle( m_pxELTrack[0], m_pxELTrack[2]); // leading e- and leading e+
1057 m_fZPt[ID] = EvalPt( m_pxELTrack[0], m_pxELTrack[2]); // leading e- and leading e+
1058 m_fZEtaDir[ID] = EvalEta( m_pxELTrack[0], m_pxELTrack[2]); // leading e- and leading e+
1059 m_fZPhiDir[ID] = EvalPhi( m_pxELTrack[0], m_pxELTrack[2]); // leading e- and leading e+
1060 kinematicscomputed = true;
1061
1062 if(m_doDebug){
1063 std::cout << " * FourMuonEvent * ReconstructKinematics4Elec * -- Electron Tracks -- " << std::endl
1064 << " Pt(e1-)= " << m_pxELTrack[0]->pt() << std::endl
1065 << " Pt(e2-)= " << m_pxELTrack[1]->pt() << std::endl
1066 << " Pt(e1+)= " << m_pxELTrack[2]->pt() << std::endl
1067 << " Pt(e2+)= " << m_pxELTrack[3]->pt() << std::endl
1068 << " invariant mass (4e) = " << m_fInvariantMass[ID] << std::endl
1069 << std::endl;
1070 }
1071 } // good tracks
1072 } // goodidentifiers
1073
1074 if (!kinematicscomputed) {
1075 if(m_doDebug){ std::cout <<" * FourMuonEvent * ReconstructKinematics4Elec * -- FAILED -- " << std::endl; }
1076 }
1077
1078 if(m_doDebug){ std::cout <<" * FourMuonEvent * ReconstructKinematics4Elec * -- completed -- status: " << kinematicscomputed << std::endl; }
1079 return kinematicscomputed;
1080}
1081
1082//==================================================================================
1084{
1085 (*m_msgStream) << MSG::DEBUG << " * FourMuonEvent * ReconstructKinematicsNew * -- START -- " << endmsg;
1086
1087 bool kinematicscomputed = false;
1088
1089 // first step get the list of TrackParticles for muons and electrons
1090 // -- muons (a bit more complex than for electrons)
1095 // add an extra proteccion
1096 if (m_numberOfFullPassMuons < 2) {
1097 for (int i=0; i<4; i++) m_pxMUTrack[i] = nullptr;
1098 }
1099
1100 // -- electrons
1101 m_pxELTrack[0] = m_xElecID.GetElecNegTrackParticle(0);
1102 m_pxELTrack[1] = m_xElecID.GetElecNegTrackParticle(1);
1103 m_pxELTrack[2] = m_xElecID.GetElecPosTrackParticle(0);
1104 m_pxELTrack[3] = m_xElecID.GetElecPosTrackParticle(1);
1105 // add an extra proteccion
1107 for (int i=0; i<4; i++) m_pxELTrack[i] = nullptr;
1108 }
1109
1110 if ( m_numberOfFullPassMuons == 4 ) {
1111 bool goodtracks = true;
1112 if (m_pxMUTrack[0] == nullptr) goodtracks = false;
1113 if (m_pxMUTrack[1] == nullptr) goodtracks = false;
1114 if (m_pxMUTrack[2] == nullptr) goodtracks = false;
1115 if (m_pxMUTrack[3] == nullptr) goodtracks = false;
1116
1117 if (goodtracks) { // Everything is ready
1119 m_fMuonDispersion[ID] = EvaluateAngle ( m_pxMUTrack[0], m_pxMUTrack[2]); // leading mu- and leading mu+
1120 m_fZPt[ID] = EvalPt ( m_pxMUTrack[0], m_pxMUTrack[2]); // leading mu- and leading mu+
1121 m_fZEtaDir[ID] = EvalEta ( m_pxMUTrack[0], m_pxMUTrack[2]); // leading mu- and leading mu+
1122 m_fZPhiDir[ID] = EvalPhi ( m_pxMUTrack[0], m_pxMUTrack[2]); // leading mu- and leading mu+
1123 kinematicscomputed = true;
1124 }
1125 }
1126
1127 if(m_doDebug){
1128 std::cout << " * FourMuonEvent * ReconstructKinematicsNew * -- Muon ID Tracks -- new -- " << std::endl;
1129 if (m_pxMUTrack[0] != nullptr) std::cout << " Pt(mu1-)= " << m_pxMUTrack[0]->pt() << std::endl;
1130 if (m_pxMUTrack[1] != nullptr) std::cout << " Pt(mu2-)= " << m_pxMUTrack[1]->pt() << std::endl;
1131 if (m_pxMUTrack[2] != nullptr) std::cout << " Pt(mu1+)= " << m_pxMUTrack[2]->pt() << std::endl;
1132 if (m_pxMUTrack[3] != nullptr) std::cout << " Pt(mu2+)= " << m_pxMUTrack[3]->pt() << std::endl;
1133 if (kinematicscomputed) std::cout << " invariant mass (4mu) = " << m_fInvariantMass[ID] << std::endl;
1134 }
1135
1136 double invmass_test = -1.; // default value
1137 if ( m_numberOfFullPassElectrons == 4) {
1138 // before computing the kinematic parameters check track particles are ok
1139 bool goodtracks = true;
1140 if (m_pxELTrack[0] == nullptr) goodtracks = false;
1141 if (m_pxELTrack[1] == nullptr) goodtracks = false;
1142 if (m_pxELTrack[2] == nullptr) goodtracks = false;
1143 if (m_pxELTrack[3] == nullptr) goodtracks = false;
1144
1145 if (goodtracks && !kinematicscomputed) { // Everything is ready
1146 // For the time being analysis is performed only with ID tracks
1148 invmass_test = m_fInvariantMass[ID];
1149 m_fMuonDispersion[ID] = EvaluateAngle( m_pxELTrack[0], m_pxELTrack[2]); // leading e- and leading e+
1150 m_fZPt[ID] = EvalPt( m_pxELTrack[0], m_pxELTrack[2]); // leading e- and leading e+
1151 m_fZEtaDir[ID] = EvalEta( m_pxELTrack[0], m_pxELTrack[2]); // leading e- and leading e+
1152 m_fZPhiDir[ID] = EvalPhi( m_pxELTrack[0], m_pxELTrack[2]); // leading e- and leading e+
1153 kinematicscomputed = true;
1154 } // good tracks
1155 }
1156 if(m_doDebug){
1157 std::cout << " * FourMuonEvent * ReconstructKinematicsNew * -- Electron Tracks -- " << std::endl;
1158 if (m_pxELTrack[0] != nullptr) std::cout << " Pt(e1-)= " << m_pxELTrack[0]->pt() << std::endl;
1159 if (m_pxELTrack[1] != nullptr) std::cout << " Pt(e2-)= " << m_pxELTrack[1]->pt() << std::endl;
1160 if (m_pxELTrack[2] != nullptr) std::cout << " Pt(e1+)= " << m_pxELTrack[2]->pt() << std::endl;
1161 if (m_pxELTrack[3] != nullptr) std::cout << " Pt(e2+)= " << m_pxELTrack[3]->pt() << std::endl;
1162 std::cout << " invariant mass (4e) = " << invmass_test << std::endl;
1163 }
1164
1165 if ( m_numberOfFullPassMuons >= 2 && m_numberOfFullPassElectrons >= 2 && !kinematicscomputed) {
1166 // before computing the kinematic parameters check track particles are ok
1167 bool goodtracks = true;
1168 if (m_pxMUTrack[0] == nullptr) goodtracks = false; // leading mu-
1169 if (m_pxMUTrack[2] == nullptr) goodtracks = false; // leading mu+
1170 if (m_pxELTrack[0] == nullptr) goodtracks = false; // leading e-
1171 if (m_pxELTrack[2] == nullptr) goodtracks = false; // leading e+
1172
1173 if (goodtracks && !kinematicscomputed) { // Everything is ready
1174 // For the time being analysis is performed only with ID tracks
1176 invmass_test = m_fInvariantMass[ID];
1177 m_fMuonDispersion[ID] = EvaluateAngle ( m_pxMUTrack[0], m_pxELTrack[0]); // leading mu- and leading e-
1178 m_fZPt[ID] = EvalPt ( m_pxMUTrack[0], m_pxELTrack[0]); // leading mu- and leading e-
1179 m_fZEtaDir[ID] = EvalEta ( m_pxMUTrack[0], m_pxELTrack[0]); // leading mu- and leading e-
1180 m_fZPhiDir[ID] = EvalPhi ( m_pxMUTrack[0], m_pxELTrack[0]); // leading mu- and leading e-
1181 kinematicscomputed = true;
1182 } // good tracks
1183 }
1184 if(m_doDebug){
1185 std::cout << " * FourMuonEvent * ReconstructKinematicsNew * -- Muon and Electron Tracks -- " << std::endl;
1186 if (m_pxMUTrack[0] != nullptr) std::cout << " Pt(mu1-)= " << m_pxMUTrack[0]->pt() << std::endl;
1187 if (m_pxMUTrack[1] != nullptr) std::cout << " Pt(mu2-)= " << m_pxMUTrack[1]->pt() << std::endl;
1188 if (m_pxMUTrack[2] != nullptr) std::cout << " Pt(mu1+)= " << m_pxMUTrack[2]->pt() << std::endl;
1189 if (m_pxMUTrack[3] != nullptr) std::cout << " Pt(mu2+)= " << m_pxMUTrack[3]->pt() << std::endl;
1190 if (m_pxELTrack[0] != nullptr) std::cout << " Pt(e1-)= " << m_pxELTrack[0]->pt() << std::endl;
1191 if (m_pxELTrack[1] != nullptr) std::cout << " Pt(e2-)= " << m_pxELTrack[1]->pt() << std::endl;
1192 if (m_pxELTrack[2] != nullptr) std::cout << " Pt(e1+)= " << m_pxELTrack[2]->pt() << std::endl;
1193 if (m_pxELTrack[3] != nullptr) std::cout << " Pt(e2+)= " << m_pxELTrack[3]->pt() << std::endl;
1194 std::cout << " invariant mass used = " << m_fInvariantMass[ID] << std::endl;
1195 std::cout << " invariant mass test = " << invmass_test << std::endl;
1196 }
1197
1198 if (!kinematicscomputed) {
1199 if(m_doDebug){ std::cout <<" * FourMuonEvent * ReconstructKinematicsNew * -- FAILED -- " << std::endl; }
1200 }
1201
1202 (*m_msgStream) << MSG::DEBUG << " * FourMuonEvent * ReconstructKinematicsNew * -- COMPLETED -- status " << kinematicscomputed << endmsg;
1203 return kinematicscomputed;
1204}
1205
1206//==================================================================================
1208{
1209 // First determine what's positive
1210 if ( m_numberOfFullPassMuons == 2 )
1211 {
1212 switch ( eType )
1213 {
1214 case MS :
1215 {
1217 }
1218 case ME:
1219 {
1221 }
1222 case CB:
1223 {
1225 }
1226 case ID:
1227 {
1229 }
1230 default:
1231 return -999.0;
1232 }
1233 }
1234 else
1235 {
1236 return -999.0;
1237 }
1238}
1239
1240//==================================================================================
1242{
1243 switch ( eType )
1244 {
1245 case MS :
1246 {
1247 return ( static_cast<int>( EvalCharge( m_pxMSTrack[m_muon1], m_pxMSTrack[m_muon2] ) ) );
1248 }
1249 case ME:
1250 {
1251 return ( static_cast<int>( EvalCharge( m_pxMETrack[m_muon1], m_pxMETrack[m_muon2] ) ) );
1252 }
1253 case CB:
1254 {
1255 return ( static_cast<int>( EvalCharge( m_pxRecMuon[m_muon1], m_pxRecMuon[m_muon2] ) ) );
1256 }
1257 case ID:
1258 {
1259 return ( static_cast<int>( EvalCharge( m_pxIDTrack[m_muon1], m_pxIDTrack[m_muon2] ) ) );
1260 }
1261 default:
1262 return -999;
1263 }
1264}
1265
1266//==================================================================================
1267unsigned int FourMuonEvent::getPosMuon( int eType )
1268{
1269 //if ( getNumberOfTaggedMuons() != 2 ) return 999;
1270 //if ( getZCharge(eType) != 0 ) return 999;
1271
1272 unsigned int muid = m_muonpos1;
1273 if (eType==2) muid = m_muonpos2;
1274 return muid;
1275}
1276
1277//==================================================================================
1278unsigned int FourMuonEvent::getNegMuon( int eType )
1279{
1280 unsigned int muid = m_muonneg1;
1281 if (eType==2) muid = m_muonneg2;
1282 return muid;
1283}
1284
1285//==================================================================================
1286const xAOD::TrackParticle* FourMuonEvent::getLooseIDTk( unsigned int /*uPart*/ )
1287{
1288 const xAOD::TrackParticleContainer* pxTrackContainer =
1290
1291 if ( pxTrackContainer )
1292 {
1293 xAOD::TrackParticleContainer::const_iterator xTrkItr = pxTrackContainer->begin();
1294 xAOD::TrackParticleContainer::const_iterator xTrkItrE = pxTrackContainer->end();
1295 while ( xTrkItr != xTrkItrE )
1296 {
1297 const xAOD::TrackParticle* pxTrack = *xTrkItr;
1298 if ( !pxTrack ) continue;
1299 const Trk::Track* pxTrkTrack = pxTrack->track();
1300 if(!pxTrkTrack) continue;
1301 const Trk::Perigee* pxPerigee = pxTrkTrack->perigeeParameters() ;
1302 if ( !pxPerigee ) continue;
1303 const float fTrkPhi = pxPerigee->parameters()[Trk::phi];
1304 const float fTrkEta = pxPerigee->eta();
1305
1306 float fDPhi = fabs( fTrkPhi - m_pxMETrack[m_muon1]->phi() );
1307 float fDEta = fabs( fTrkEta - m_pxMETrack[m_muon2]->eta() );
1308 float fDR = sqrt( fDPhi*fDPhi + fDEta*fDEta );
1309
1310 if ( fDR < 0.3f )
1311 {
1312 return pxTrack;
1313 }
1314
1315 ++xTrkItr;
1316 }
1317 }
1318 // if ()
1319 return nullptr;
1320}
1321
1322//==================================================================================
1324{
1325 // first set the new pt cut value
1326 m_LeadingMuonPtCut = newvalue;
1327
1328 // the second muon pt cut can not be higher than the leading muon pt cut:
1330
1331 // this has to be translated to the MuonSelector
1332 // but there one has to use the minimum momentum --> second muon
1333 //this->SetMuonPtCut(m_SecondMuonPtCut);
1334 if(m_doDebug){
1335 std::cout <<" * FourMuonEvent * SetLeadingMuonPtCut * new Pt cuts: " << m_LeadingMuonPtCut << " & "
1337 << " MuonSelector: " << m_xMuonID.GetPtCut() << std::endl;
1338 }
1339 return;
1340}
1341
1342//==================================================================================
1344{
1345 m_SecondMuonPtCut = newvalue;
1346
1347 // use same for electrons
1348 m_xElecID.SetPtCut(m_SecondMuonPtCut);
1349
1350 // second muon pt shouldn't be higher than the leading muon pt
1352
1353 // this has to be translated to the MuonSelector
1355
1356 if(m_doDebug) {
1357 std::cout <<" * FourMuonEvent * SetSecondMuonPtCut * new Pt cuts: " << m_LeadingMuonPtCut
1358 << " & " << m_SecondMuonPtCut
1359 << " MuonSelector: " << m_xMuonID.GetPtCut() << std::endl;
1360 }
1361
1362 return;
1363}
1364
1365//==================================================================================
1367{
1368 // Salva: 20/January/2020 RecMuon -> IDTrack
1369 bool thisdebug = false;
1370
1371 if (m_doDebug || thisdebug) {std::cout << " * FourMuonEvent::OrderMuonList * -- start -- " << std::endl
1372 << " #muons: " << m_numberOfFullPassMuons<< std::endl;}
1373
1374 int muPlus1Id = -9;
1375 int muPlus2Id = -9;
1376 int muMinus1Id = -9;
1377 int muMinus2Id = -9;
1378 double muPlus1Pt = 0.;
1379 double muPlus2Pt = 0.;
1380 double muMinus1Pt = 0.;
1381 double muMinus2Pt = 0.;
1382
1383 int muposcount = 0;
1384 int munegcount = 0;
1385
1386 int nMuonsAtEntry = m_numberOfFullPassMuons;
1387 m_numberOfFullPassMuons = 0; // reset the number of full pass muons
1388
1389 if (nMuonsAtEntry >= 2) { // we need at least 2 muons
1390 for (int imuon=0; imuon < (int) nMuonsAtEntry; imuon++) {
1391 if(m_doDebug && false ){ std::cout << " * FourMuonEvent::OrderMuonList * testing imuon= " << imuon
1392 << " with charge= " << m_pxRecMuon[imuon]->charge()
1393 << " and pt= " << m_pxRecMuon[imuon]->pt()
1394 << std::endl;
1395 }
1396 if (m_pxIDTrack[imuon] != nullptr) {
1397
1398 if (m_pxIDTrack[imuon]->charge()==1) { // positive muon
1399 muposcount++;
1400 if (m_pxIDTrack[imuon]->pt()> muPlus1Pt) {
1401 // store 1st in 2nd
1402 muPlus2Pt = muPlus1Pt;
1403 muPlus2Id = muPlus1Id;
1404 // now store the new one in 1st place
1405 muPlus1Pt = m_pxIDTrack[imuon]->pt();
1406 muPlus1Id = imuon;
1407 }
1408 else if (m_pxIDTrack[imuon]->pt()> muPlus2Pt) {
1409 // store the new one in 2nd place
1410 muPlus2Pt = m_pxIDTrack[imuon]->pt();
1411 muPlus2Id = imuon;
1412 }
1413 }
1414 // Negative muons
1415 if (m_pxIDTrack[imuon]->charge()==-1) {
1416 munegcount++;
1417 if(m_pxIDTrack[imuon]->pt()> muMinus1Pt) {
1418 // store 1st in 2nd
1419 muMinus2Pt = muMinus1Pt;
1420 muMinus2Id = muMinus1Id;
1421 muMinus1Pt = m_pxIDTrack[imuon]->pt();
1422 muMinus1Id = imuon;
1423 }
1424 else if(m_pxRecMuon[imuon]->pt()> muMinus2Pt) {
1425 muMinus2Pt = m_pxIDTrack[imuon]->pt();
1426 muMinus2Id = imuon;
1427 }
1428 }
1429 } // muon exist
1430 } // for (int imuon)
1431 } // if (nMuonsAtEntry >= 2)
1432
1433 // require at least one opposite charge muon pair
1434 if (nMuonsAtEntry >= 2 && (muposcount == 0 || munegcount == 0)) {
1435 if (m_doDebug) std::cout << " -- FourMuonEvent::OrderMuonList -- No opposite charge muons in the " << nMuonsAtEntry << " input muons"
1436 << " #mu+ " << muposcount
1437 << " #mu- " << munegcount
1438 << " --> DISCARD ALL MUONS -- " << std::endl;
1439 muPlus1Id = -1;
1440 muPlus1Id = -9;
1441 muPlus2Id = -9;
1442 muMinus1Id = -9;
1443 muMinus2Id = -9;
1444 }
1445
1446
1447 if (muPlus1Id>=0) {m_muonpos1 = muPlus1Id; m_numberOfFullPassMuons++;}
1448 if (muPlus2Id>=0) {m_muonpos2 = muPlus2Id; m_numberOfFullPassMuons++;}
1449 if (muMinus1Id>=0) {m_muonneg1 = muMinus1Id; m_numberOfFullPassMuons++;}
1450 if (muMinus2Id>=0) {m_muonneg2 = muMinus2Id; m_numberOfFullPassMuons++;}
1451
1452 m_muon1 = m_muonpos1; // to be deleted when no more m_muon is left
1453 m_muon2 = m_muonneg1; // to be deleted when no more m_muon is left
1454
1455 if ((m_doDebug || thisdebug) && m_numberOfFullPassMuons >= 2){
1456 std::cout << " * FourMuonEvent::OrderMuonList * taking " << m_numberOfFullPassMuons << " muons from the input list of " << nMuonsAtEntry << " muons: " << std::endl;
1457 if (muMinus1Id >= 0) std::cout << " leading mu-: " << muMinus1Id << " Pt = " << muMinus1Pt << std::endl;
1458 if (muMinus2Id >= 0) std::cout << " second mu-: " << muMinus2Id << " Pt = " << muMinus2Pt << std::endl;
1459 if (muPlus1Id >= 0) std::cout << " leading mu+: " << muPlus1Id << " Pt = " << muPlus1Pt << std::endl;
1460 if (muPlus2Id >= 0) std::cout << " second mu+: " << muPlus2Id << " Pt = " << muPlus2Pt << std::endl;
1461 }
1462 else {
1463 if (m_doDebug) std::cout << " * FourMuonEvent::OrderMuonList * This event has less than 2 muons :(" << std::endl;
1464 }
1465
1466 if (m_doDebug || thisdebug) std::cout << " * FourMuonEvent::OrderMuonList * completed * m_numberOfFullPassMuons= " << m_numberOfFullPassMuons << std::endl;
1467 return;
1468}
1469
1472{
1473 (*m_msgStream) << MSG::DEBUG << " * FourMuonsEvents::CheckMuonVertices * -- START --" << endmsg;
1474
1475 bool goodvertices = false;
1476 goodvertices = true; // R22 set true by default. Needs to be revisited
1477 int nverticesfound = 0;
1478
1479 // loop on mu-, and for each mu-, loop on mu+ and check at least one mu+ and mu- come from the same vertex
1480 // mu- indices are 0 or 1
1481 for (unsigned int imuneg = 0; imuneg <= 1; imuneg++) {
1482 if (m_pxMUTrack[imuneg] != nullptr) {
1483 /* R21 SALVA --> vertex is not available in R22 --> A FIX IS NEEDED */
1484 /*
1485 if (m_pxMUTrack[imuneg]->vertex()) {
1486
1487 if (m_doDebug) std::cout << " mu-(" << imuneg <<")->vertex()->v= (" << m_pxMUTrack[imuneg]->vertex()->x()
1488 << ", " << m_pxMUTrack[imuneg]->vertex()->y()
1489 << ", " << m_pxMUTrack[imuneg]->vertex()->z()
1490 << ") " << std::endl;
1491
1492 for (unsigned int imupos = 2; imupos <= 3; imupos++) { // mu+ indices are 2 and 3
1493 if (m_pxMUTrack[imupos] != nullptr) {
1494 if (m_pxMUTrack[imupos]->vertex()) {
1495 if (m_doDebug) std::cout << " mu+(" << imupos <<")->vertex()->v= (" << m_pxMUTrack[imupos]->vertex()->x()
1496 << ", " << m_pxMUTrack[imupos]->vertex()->y()
1497 << ", " << m_pxMUTrack[imupos]->vertex()->z()
1498 << ") " << std::endl;
1499
1500 float delta_x = fabs( m_pxMUTrack[imuneg]->vertex()->x() - m_pxMUTrack[imupos]->vertex()->x());
1501 float delta_y = fabs( m_pxMUTrack[imuneg]->vertex()->y() - m_pxMUTrack[imupos]->vertex()->y());
1502 float delta_z = fabs( m_pxMUTrack[imuneg]->vertex()->z() - m_pxMUTrack[imupos]->vertex()->z());
1503
1504 if (delta_x < m_deltaXYcut && delta_y < m_deltaXYcut && delta_z < m_Z0GapCut) {
1505 nverticesfound++;
1506 if (m_doDebug) std::cout << " MUON-BINGO !!! mu+mu- pair in same vertex !!! mu-[" << imuneg
1507 << "] mu+[" << imupos<< "] count: " << nverticesfound << std::endl;
1508 } // vertex is the same
1509 } // mu+ has vertex
1510 } // mu+ exists
1511 } // loop on mu+
1512 } // mu- has vertex
1513 */
1514 } // mu- exists
1515 } // loop on mu-
1516
1517 if (nverticesfound >= 1) goodvertices = true;
1518
1519 if (nverticesfound == 0) if (m_doDebug) std::cout << " -- FourMuonEvent::CheckMuonVertices -- WARNING -- MUONS DO NOT COME FROM SAME VERTEX " << std::endl;
1520
1521 (*m_msgStream) << MSG::DEBUG << " * FourMuonsEvents::CheckMuonVertices * -- COMPLETED -- status: " << goodvertices << endmsg;
1522 return goodvertices;
1523}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define endmsg
double charge(const T &p)
Definition AtlasPID.h:997
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
static float EvaluateAngle(const T *pxP1, const T *pxP2)
static float EvalCharge(const T *pxP1, const T *pxP2)
static float EvalPhi(const T *pxP1, const T *pxP2)
static float EvalPtDiff(const T *pxP1, const T *pxP2)
virtual void Init()
static float EvalPt(const T *pxP1, const T *pxP2)
static float EvalFourMuInvMass(const T *pxP1, const T *pxP2, const T *pxP3, const T *pxP4)
static float EvalEta(const T *pxP1, const T *pxP2)
std::string m_xSampleName
const xAOD::TrackParticle * m_pxMETrack[NUM_MUONS]
void SetSecondMuonPtCut(double newvalue)
float m_fInvariantMass[NUM_TYPES]
double m_MassWindowLow
double m_FourMuonInvMass
bool m_passedFourLeptonSelection
void SetLeadingMuonPtCut(double newvalue)
int getZCharge(ZTYPE eType)
MuonSelector m_xMuonID
PerfMonServices::CONTAINERS m_container
virtual ~FourMuonEvent()
int m_muon_vtx[NUM_MUONS]
bool m_passedFourElectronSelection
bool ReconstructKinematics4Elec()
int m_elec_vtx[NUM_MUONS]
bool ReconstructKinematics()
float m_fMuonDispersion[NUM_TYPES]
bool m_workAsFourElectrons
double m_SecondMuonPtCut
double m_MassWindowHigh
MsgStream * m_msgStream
void SetMuonPtCut(double newvalue)
float m_fZPhiDir[NUM_TYPES]
float m_fZEtaDir[NUM_TYPES]
const xAOD::TrackParticle * m_pxIDTrack[NUM_MUONS]
bool EventSelection(ZTYPE eType)
const xAOD::TrackParticle * m_pxMUTrack[NUM_MUONS]
double m_LeadingMuonPtCut
ElectronSelector m_xElecID
unsigned int m_uMuonTags
bool m_passedFourMuonSelection
bool ReconstructKinematicsNew()
bool m_passedSelectionCuts
float m_fZPt[NUM_TYPES]
void RecordMuon(const xAOD::Muon *pxMuon)
const xAOD::TrackParticle * m_pxELTrack[NUM_MUONS]
float getPtImbalance(ZTYPE eType)
unsigned int getPosMuon(int eType)
unsigned int m_numberOfFullPassElectrons
const xAOD::Muon * m_pxRecMuon[NUM_MUONS]
unsigned int getNegMuon(int eType)
const xAOD::TrackParticle * m_pxMSTrack[NUM_MUONS]
const xAOD::TrackParticle * getLooseIDTk(unsigned int uPart)
bool EventSelectionNew(ZTYPE eType)
unsigned int m_numberOfFullPassMuons
static const T * getContainer(CONTAINERS eContainer)
static const std::string & getContainerName(CONTAINERS eContainer)
double eta() const
Access method for pseudorapidity - from momentum.
const Perigee * perigeeParameters() const
return Perigee.
const TrackParticle * trackParticle(TrackParticleType type) const
Returns a pointer (which can be NULL) to the TrackParticle used in identification of this muon.
Definition Muon_v1.cxx:482
const Trk::Track * track() const
Returns a pointer (which can be NULL) to the Trk::Track which was used to make this TrackParticle.
singleton-like access to IMessageSvc via open function and helper
IMessageSvc * getMessageSvc(bool quiet=false)
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ phi
Definition ParamDefs.h:75
ElectronContainer_v1 ElectronContainer
Definition of the current "electron container version".
TrackParticle_v1 TrackParticle
Reference the current persistent version:
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
Muon_v1 Muon
Reference the current persistent version:
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".