ATLAS Offline Software
BSignalFilter.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // -----------------------------------------------------------------------------------------------
6 //
7 // BSignalFilter.cxx
8 //
9 // Description: finds all B-chains, applies cuts specified in jobOptionsFile
10 //
11 // Author: Malte Muller <maltemlr@yahoo.co.uk>
12 // August 2002 Malte Muller
13 // Sept. 2002 M.Smizanska: minor updates in fill Ntuple
14 // Dec. 2003 M.Smizanska: filtering out events with B-hadrons
15 // left undecayed either in Pythia or in EvtGen.
16 // This is used as a method of selecting only wanted
17 // exclusive channels into persistent output. See PythiaB manual.
18 // Feb. 2004 J. Catmore LVL1/LVL2 cut facility added.
19 //
20 // Sept. 2013 C. Alpigiani - Removed the code that writes the ntuples
21 // - Wrote the code that implements the particle selection (pT, eta
22 // and invariant mass)
23 // -----------------------------------------------------------------------------------------------
24 
27 #include "CLHEP/Vector/LorentzVector.h"
29 
30 #include <sstream>
31 
32 
33 BSignalFilter::BSignalFilter(const std::string& name, ISvcLocator* pSvcLocator) :
34  GenFilter(name, pSvcLocator)
35 {
36  // ** Declare the algorithm's properties **
37  declareProperty("LVL1MuonCutOn" , m_localLVL1MuonCutOn = false );
38  declareProperty("LVL2MuonCutOn" , m_localLVL2MuonCutOn = false );
39  declareProperty("LVL2ElectronCutOn" , m_localLVL2ElectronCutOn = false);
40  declareProperty("LVL1MuonCutPT" , m_localLVL1MuonCutPT = 0.0 );
41  declareProperty("LVL1MuonCutEta" , m_localLVL1MuonCutEta = 102.5 );
42  declareProperty("LVL2MuonCutPT" , m_localLVL2MuonCutPT = 0.0 );
43  declareProperty("LVL2MuonCutEta" , m_localLVL2MuonCutEta = 102.5 );
44  declareProperty("LVL2ElectronCutPT" , m_localLVL2ElectronCutPT = 0.0 );
45  declareProperty("LVL2ElectronCutEta" , m_localLVL2ElectronCutEta = 102.5);
46  declareProperty("Cuts_Final_e_switch" , m_cuts_f_e_on = false );
47  declareProperty("Cuts_Final_e_pT" , m_cuts_f_e_pT = 0. );
48  declareProperty("Cuts_Final_e_eta" , m_cuts_f_e_eta = 2.5 );
49  declareProperty("Cuts_Final_mu_switch" , m_cuts_f_mu_on = false );
50  declareProperty("Cuts_Final_mu_pT" , m_cuts_f_mu_pT = 0. );
51  declareProperty("Cuts_Final_mu_eta" , m_cuts_f_mu_eta = 102.5 );
52  declareProperty("Cuts_Final_hadrons_switch", m_cuts_f_had_on = false );
53  declareProperty("Cuts_Final_hadrons_pT" , m_cuts_f_had_pT = 0. );
54  declareProperty("Cuts_Final_hadrons_eta" , m_cuts_f_had_eta = 102.5 );
55  declareProperty("Cuts_Final_gamma_switch" , m_cuts_f_gam_on = false );
56  declareProperty("Cuts_Final_gamma_pT" , m_cuts_f_gam_pT = 0. );
57  declareProperty("Cuts_Final_gamma_eta" , m_cuts_f_gam_eta = 102.5 );
58  declareProperty("Cuts_Final_K0_switch" , m_cuts_f_K0_on = false );
59  declareProperty("Cuts_Final_K0_pT" , m_cuts_f_K0_pT = 0. );
60  declareProperty("Cuts_Final_K0_eta" , m_cuts_f_K0_eta = 102.5 );
61  //
62  // ** Declare the signal B-meson/hadron PDGid
63  declareProperty("B_PDGCode" ,m_B_pdgid = 0);
64  //
65  // ** Declare properties for mass filter **
66  declareProperty("InvMass_switch" , m_InvMass_switch = false );
67  declareProperty("InvMass_PartId1" , m_InvMass_PartId1 = 13 );
68  declareProperty("InvMass_PartId2" , m_InvMass_PartId2 = -m_InvMass_PartId1 );
69  declareProperty("InvMass_PartFakeMass1", m_InvMass_PartFakeMass1 = -1. );
70  declareProperty("InvMass_PartFakeMass2", m_InvMass_PartFakeMass2 = -1. );
71  declareProperty("InvMassMin" , m_InvMassMin = 0.0 );
72  declareProperty("InvMassMax" , m_InvMassMax = 14000000.0 );
73  declareProperty("TotalInvMass_switch" , m_TotalInvMass_switch = false );
74  declareProperty("TotalInvMassMin" , m_TotalInvMassMin = 0.0 );
75  declareProperty("TotalInvMassMax" , m_TotalInvMassMax = 14000000.0 );
76 
77  // ** Initialise event counter **
78  m_EventCnt = 0;
79  m_LVL1Counter = 0;
80  m_LVL2Counter = 0;
82  m_rejectedAll = 0;
83 
84 }
85 
86 
88 {
89  ATH_MSG_INFO("");
90  ATH_MSG_INFO(" ---------------------------------- ");
91  ATH_MSG_INFO(" >>> BSignalFilter::FilterEvent <<< ");
92  ATH_MSG_INFO(" ---------------------------------- ");
93  ATH_MSG_INFO("");
94 
95  // ** Return ERROR and exit if the user has not selected the PDGid of the B-meson/hadron signal **
97  if (m_B_pdgid==0)
98  {
99  ATH_MSG_ERROR("");
100  ATH_MSG_ERROR(" ==>> 'B_PDGCode = 0'! Please define the PDGid of the B-meson/hadron signal!");
101  ATH_MSG_ERROR("");
102  return StatusCode::FAILURE;
103  }
104 
105  // ** Begin iterating over McEventCollection **
107  for( itr = events()->begin(); itr != events()->end(); ++itr )
108  {
109  m_EventCnt++;
110  bool acceptEvent = true;
111  const HepMC::GenEvent* genEvt = (*itr);
112 
113  // ** Check HepMC for particles activating LVL1 trigger, if that is what user wishes **
114  //
115  bool LVL1Passed = false;
116  HepMC::ConstGenParticlePtr LVL1Muon = nullptr;
117  //
118  if ( m_localLVL1MuonCutOn ) {
119  for(const auto& part: *genEvt){
120  bool LVL1Result = LVL1_Mu_Trigger( part );
121  if ( LVL1Result )
122  {
123  LVL1Passed = true;
124  LVL1Muon = part; // Remember the muon for LVL2 testing
125  break;
126  }
127  }
128  }
129 
130  // ** Check HepMC for particles activating LVL2 trigger, if that is what user wishes **
131  //
132  bool LVL2Passed = false;
133  //
134  if ( LVL1Passed && (m_localLVL2MuonCutOn || m_localLVL2ElectronCutOn) )
135  {
136  for(const auto& part: *genEvt)
137  {
138  bool LVL2Result = LVL2_eMu_Trigger( part );
139  if ( LVL2Result )
140  {
141  if ( part != LVL1Muon ) // Check the particle triggering LVL2 isn't
142  LVL2Passed = true; // the muon that triggered LVL1 --> Artificial,
143  // since, effectively, LVL2 trigger is not applied.
144  // This is needed to "trigger" the 2nd muon!
145  }
146  }
147  }
148 
149  // ** Flag event as passing LVL1 if it has passed **
150  //cy of both versions of the filter and go
151  if ( m_localLVL1MuonCutOn && LVL1Passed )
152  {
153  ATH_MSG_DEBUG(" LVL1 Trigger activated for event " << m_EventCnt);
154  m_LVL1Counter++;
155  }
156  // ** Flag event as passing LVL2 if it has passed **
157  //
158  if ( (m_localLVL2MuonCutOn || m_localLVL2ElectronCutOn) && LVL2Passed )
159  {
160  ATH_MSG_DEBUG(" LVL2 Trigger activated for event " << m_EventCnt);
161  m_LVL2Counter++;
162  }
163 
164  // ** If user hasn't requested triggers then set everything to true so nothing is thrown away **
165  //
166  if ( !m_localLVL1MuonCutOn )
167  {
168  LVL1Passed = true;
169  LVL2Passed = true;
170  }
171  if ( !m_localLVL2MuonCutOn && !m_localLVL2ElectronCutOn ) LVL2Passed = true;
172 
173  // ** Reject event if an undecayed quark is found **
174  //
175  for(const auto& part: *genEvt)
176  {
177  if ( std::abs(part->pdg_id()) <= 6 && MC::isStable(part) )
178  {
179  acceptEvent = false;
180  ATH_MSG_WARNING(" Undecayed quark "<< part);
181  }
182  }
183 
184  // ** Look for signal events **
185  //
186  bool SignalPassedCuts=false;
187  if ( LVL1Passed && LVL2Passed )
188  {
189  // ** Loop on all particles **
190  for(const auto& part: *genEvt)
191  {
192  const int particleID = part->pdg_id();
193  //
194  bool motherIsB = false;
195  bool newBChain = false;
196 
197  if( ( MC::isBottomMeson(particleID) || MC::isBottomBaryon(particleID) ) && MC::isPhysical(part) ){
198  // ** Reject whole event if any of B-hadrons in the event is not decayed **
199  if( MC::isStable(part) || part->status() == HepMC::EVTGENUNDECAYEDSTATUS ) { acceptEvent = false; }
200 
201 #ifdef HEPMC3
202  auto firstParent = part->production_vertex()->particles_in().begin();
203  auto lastParent = part->production_vertex()->particles_in().end();
204 #else
205  auto firstParent = part->production_vertex()->particles_begin(HepMC::parents);
206  auto lastParent = part->production_vertex()->particles_end(HepMC::parents);
207 #endif
208  for (auto thisParent = firstParent; thisParent != lastParent; ++thisParent ) {
209  if (MC::isBottomMeson(*thisParent) || MC::isBottomBaryon(*thisParent) ) motherIsB = true;
210  }
211  if( motherIsB ){
212  newBChain = false; // Since the chain is not new
213  }else{
214  newBChain = true;
215  }
216  }
217  else{ newBChain = false; } // Since particle is not b
218 
219  // ** New B-signal found, output message and find whole decay tree **
220  if( newBChain )
221  {
222  const HepPDT::ParticleData* HadronData = particleData(particleID);
223  std::string HadronName = "unknown particle";
224  if (HadronData){
225  HadronName = HadronData->name();
226  if (particleID < 0) HadronName = "anti - " + HadronName;
227  }
228  ATH_MSG_DEBUG("");
229  ATH_MSG_DEBUG(" ------------------------------------------ ");
230  ATH_MSG_DEBUG(" *** BSignalFilter.cxx: B-signal found *** ");
231  ATH_MSG_DEBUG(" ------------------------------------------ ");
232  ATH_MSG_DEBUG("");
233  // cppcheck-suppress shiftNegative; false positive
234  ATH_MSG_DEBUG(" Event " << m_EventCnt << " --> B-hadron/B-meson (" << HadronName << ") " << part);
235  ATH_MSG_DEBUG("");
236 
237  // ** Looping on all children checking if they have passed the selection cuts defined by the user **
240  {
241  ATH_MSG_DEBUG(" *** KINEMATIC CUTS ON PARTICLES ACTIVATED *** ");
242  ATH_MSG_DEBUG("");
243  ATH_MSG_DEBUG(" --------------------------------- ");
244  ATH_MSG_DEBUG(" Started looping on all children ");
245  ATH_MSG_DEBUG(" --------------------------------- ");
246  ATH_MSG_DEBUG("");
247  //
248  bool isSignal=false;
249  bool havePassedCuts=true;
250  TLorentzVector CandPart1, CandPart2, total_4mom;
251  //
252  FindAllChildren(part,"",false,isSignal,havePassedCuts,CandPart1,CandPart2,false,total_4mom);
253  //
254  ATH_MSG_DEBUG("");
255  ATH_MSG_DEBUG(" ------------------------------- ");
256  ATH_MSG_DEBUG(" Ended looping on all children ");
257  ATH_MSG_DEBUG(" ------------------------------- ");
258  ATH_MSG_DEBUG("");
259 
260  SignalPassedCuts = ( isSignal && havePassedCuts );
261 
262  // ** If signal event is found and InvMass_switch = true, check if the selected
263  // couple of particles has an invariant mass within the range set by the user **
264  if ( m_InvMass_switch )
265  {
266  if ( SignalPassedCuts )
267  {
268  bool accept_mass = false;
269  bool accept_total_mass = false;
270  ATH_MSG_DEBUG("");
271  ATH_MSG_DEBUG(" *** INVARIANT MASS CUTS ON PARTICLES ACTIVATED! *** ");
272  ATH_MSG_DEBUG("");
273  if (m_InvMass_switch ) ATH_MSG_DEBUG(" -- Mass cuts -->> " << m_InvMassMin << " < mass < " << m_InvMassMax << " MeV");
274  //
275  double invMass = ( CandPart1 + CandPart2 ).M();
276  double invMass_total = total_4mom.M();
277  //
278 
279  if ( m_InvMass_switch )
280  {
281  ATH_MSG_DEBUG(" -- Invariant mass of the couple of particles = " << invMass << " MeV");
283  {
284  ATH_MSG_DEBUG(" ==>> Event has passed the mass filter!");
285  ATH_MSG_DEBUG("");
286  accept_mass = true;
287  }else
288  {
289  ATH_MSG_DEBUG(" ==>> Event has NOT passed the mass filter!");
290  ATH_MSG_DEBUG("");
291  }
292  SignalPassedCuts = SignalPassedCuts && accept_mass;
293  }
294  if ( m_TotalInvMass_switch )
295  {
296  ATH_MSG_DEBUG(" -- Total invariant mass of the final-state particles = " << invMass_total << " MeV");
297  if ( m_TotalInvMassMin < invMass_total && invMass_total < m_TotalInvMassMax )
298  {
299  ATH_MSG_DEBUG(" ==>> Event has passed the total mass filter!");
300  ATH_MSG_DEBUG("");
301  accept_total_mass = true;
302  } else {
303  ATH_MSG_DEBUG(" ==>> Event has NOT passed the total mass filter!");
304  ATH_MSG_DEBUG("");
305  }
306  SignalPassedCuts = SignalPassedCuts && accept_total_mass;
307  }
308  }else{
309  ATH_MSG_DEBUG("");
310  ATH_MSG_DEBUG(" *** INVARIANT MASS CUTS ON PARTICLES NOT APPLIED (since the event is not a signal that passed cuts)! *** ");
311  ATH_MSG_DEBUG("");
312  }
313  }else{
314  ATH_MSG_DEBUG(" *** INVARIANT MASS CUTS ON PARTICLES NOT ACTIVATED *** ");
315  ATH_MSG_DEBUG("");
316  }
317  }else{
318  SignalPassedCuts = true;
319  //
320  ATH_MSG_DEBUG(" *** KINEMATIC CUTS ON PARTICLES NOT ACTIVATED ==>> ACCEPT ALL EVENTS! *** ");
321  ATH_MSG_DEBUG("");
322  }
323  } // End newBChain
324  if ( SignalPassedCuts ) break; // We have found the signal, we do not need to look for other particles
325  } // End particle iteration
326 
327  if ( SignalPassedCuts )
328  {
329  ATH_MSG_DEBUG(" -->> All signal children have passed cuts on particles!");
330  }else{
331  ATH_MSG_DEBUG(" -->> Signal children have NOT passed cuts on particles!");
332  }
333  } // end of LVL1/LVL2 selection
334  else{
335  ATH_MSG_DEBUG("");
336  ATH_MSG_DEBUG(" -->> Event has NOT passed the trigger!");
337  }
338  // ** Reject event if it has not passed triggers **
339  // --> If not requested by user these flags will be set
340  // to true so there will be no erroneous rejection
341  if ( (!LVL1Passed) || (!LVL2Passed) ){
343  acceptEvent = false;
344  }
345 
346  // ** Check if all conditions are true **
347  // --> Accept the event if acceptEvent is true and the event is a signal event
348  acceptEvent = acceptEvent && SignalPassedCuts;
349 
350  // ** Print whether the event has passed or not **
351  //
352  ATH_MSG_DEBUG("");
353  if( !acceptEvent )
354  {
355  setFilterPassed(false);
356  m_rejectedAll++;
357  ATH_MSG_DEBUG(" ==========================");
358  ATH_MSG_DEBUG(" Event REJECTED by Filter ");
359  ATH_MSG_DEBUG(" ==========================");
360  }else
361  {
362  setFilterPassed(true);
363  ATH_MSG_DEBUG(" ==========================");
364  ATH_MSG_DEBUG(" Event ACCEPTED by Filter ");
365  ATH_MSG_DEBUG(" ==========================");
366  }
367  ATH_MSG_DEBUG("");
368 
369  } // End event iteration
370  // End of execution for each event
371  return StatusCode::SUCCESS;
372 }
373 
374 
375 bool BSignalFilter::test_cuts(const double myPT, const double testPT, const double myEta, const double testEta) const
376 {
377  return ( (myPT >= testPT) && (std::abs(myEta) <= testEta) );
378 }
379 
380 
382 {
383  bool accept = false;
384  int pID = child->pdg_id();
385  double myPT = child->momentum().perp();
386  double myEta = child->momentum().pseudoRapidity();
387 
388  if ( (std::abs(pID) == 13) && m_localLVL1MuonCutOn )
390 
391  return accept;
392 
393 }
394 
395 
397 {
398  bool accept = false;
399  int pID = child->pdg_id();
400  double myPT = child->momentum().perp();
401  double myEta = child->momentum().pseudoRapidity();
402 
403  if ( (std::abs(pID) == 11) && m_localLVL2ElectronCutOn )
405  if ( (std::abs(pID) == 13) && m_localLVL2MuonCutOn )
407 
408  return accept;
409 }
410 
411 
412 void BSignalFilter::FindAllChildren(const HepMC::ConstGenParticlePtr& mother,std::string treeIDStr,
413  bool fromFinalB, bool &foundSignal, bool &passedAllCuts,
414  TLorentzVector &p1, TLorentzVector &p2, bool fromSelectedB, TLorentzVector &total_4mom) const
415 {
416  int pID = mother->pdg_id();
417  //
418  if ( !(mother->end_vertex()) && MC::isStable(mother) ) // i.e. this is a final state
419  {
420  bool hasChildGoodParent = fromFinalB && (fromSelectedB || m_B_pdgid==0);
421  //
422  if( fromFinalB && hasChildGoodParent )
423  {
424  foundSignal=true;
425  bool passedCut = FinalStatePassedCuts(mother); // X = X && ... in case of multiple particles (e.g. KK)
426  if ( m_cuts_f_e_on && std::abs(pID)==11 ) passedAllCuts = passedAllCuts && passedCut;
427  if ( m_cuts_f_mu_on && std::abs(pID)==13 ) passedAllCuts = passedAllCuts && passedCut;
428  if ( m_cuts_f_had_on && MC::isHadron(pID) && MC::isCharged(pID) ) passedAllCuts = passedAllCuts && passedCut;
429  if ( m_cuts_f_gam_on && std::abs(pID)==22 ) passedAllCuts = passedAllCuts && passedCut;
430  if ( m_cuts_f_K0_on && std::abs(pID)==311 ) passedAllCuts = passedAllCuts && passedCut;
431  //
433  {
434  if (m_InvMass_PartFakeMass1 < 0.) p1.SetPxPyPzE(mother->momentum().x(),mother->momentum().y(),mother->momentum().z(),mother->momentum().e() );
435  else p1.SetXYZM(mother->momentum().x(),mother->momentum().y(),mother->momentum().z(),m_InvMass_PartFakeMass1);
436  total_4mom = total_4mom + p1;
437  } else if ( (m_InvMass_switch || m_TotalInvMass_switch) && m_InvMass_PartId2==pID ) {
438  if (m_InvMass_PartFakeMass2 < 0.) p2.SetPxPyPzE(mother->momentum().x(),mother->momentum().y(),mother->momentum().z(),mother->momentum().e() );
439  else p2.SetXYZM(mother->momentum().x(),mother->momentum().y(),mother->momentum().z(),m_InvMass_PartFakeMass2);
440  total_4mom = total_4mom + p2;
441  } else if (m_TotalInvMass_switch) {
442  TLorentzVector current_4p;
443  current_4p.SetPxPyPzE(mother->momentum().x(),mother->momentum().y(),mother->momentum().z(),mother->momentum().e());
444  total_4mom = total_4mom + current_4p;
445  }
446  }
447  return;
448  }
449  else{
450  if ( !(mother->end_vertex()) ) // i.e. something is wrong in HepMC
451  {
452  if (MC::isDecayed(mother))
453  ATH_MSG_DEBUG(" Inconsistent entry in HepMC (status 2 particle not decayed), chain rejected!");
454  return;
455  }
456  }
457 #ifdef HEPMC3
458  auto firstChild = mother->end_vertex()->particles_out().begin();
459  auto lastChild = mother->end_vertex()->particles_out().end();
460 #else
461  auto firstChild = mother->end_vertex()->particles_begin(HepMC::children);
462  auto lastChild = mother->end_vertex()->particles_end(HepMC::children);
463 #endif
464 
465  int childCnt = 0;
466  std::string childIDStr;
467  if( !( treeIDStr=="" ) ) treeIDStr = treeIDStr + ".";
468 
469  // ** Find out whether particle is child of final (non-excited) B, used for cuts **
470  if( (!fromFinalB) && (MC::isBottomMeson(pID) || MC::isBottomBaryon(pID)) )
471  {
472  fromFinalB = true;
473  int pID{};
474  for (auto thisChild = firstChild; thisChild != lastChild; ++thisChild)
475  {
476  pID = (*thisChild)->pdg_id();
477  if( MC::isBottomMeson(pID) || MC::isBottomBaryon(pID) ) fromFinalB = false;
478  }
479  }
480 
481  // ** Main loop: iterate over all children, call method recursively.
482  //Note: Iterators changed between HEPMC2 and HEPMC3; the previous version
483  //was a custom iterator which could be incremented indefinitely, always returning
484  //'end' when necessary. In HEPMC3, these are standard library iterators
485  for (auto thisChild = firstChild; thisChild != lastChild; ++thisChild)
486  {
487  childCnt++;
488  std::stringstream childCntSS; childCntSS << childCnt;
489  childIDStr = treeIDStr + childCntSS.str();
490  PrintChild( (*thisChild), childIDStr, fromFinalB );
491  FindAllChildren( (*thisChild),childIDStr,fromFinalB,foundSignal,passedAllCuts,p1,p2,(pID==m_B_pdgid) || fromSelectedB,total_4mom);
492  }
493 
494  return;
495 
496 }
497 
498 
500 {
501  bool accept = true;
502 
503  // ** Look if children has passed the cuts **
504  //
505  int pID = child->pdg_id();
506  double myPT = child->momentum().perp();
507  double myEta = child->momentum().pseudoRapidity();
508 
509  ATH_MSG_DEBUG("");
510  ATH_MSG_DEBUG(" ** Found a child with: ");
511  ATH_MSG_DEBUG(" - id = " << pID );
512  ATH_MSG_DEBUG(" - pT = " << myPT << " MeV");
513  ATH_MSG_DEBUG(" - eta = " << myEta );
514  ATH_MSG_DEBUG("");
515 
516  if ( m_cuts_f_e_on )
517  {
518  if ( std::abs(pID) == 11 )
519  {
520  ATH_MSG_DEBUG(" ** ( pT , eta ) cuts applied on the electron --> ( " << m_cuts_f_e_pT
521  << " , " << m_cuts_f_e_eta << " )");
522  if ( test_cuts( myPT, m_cuts_f_e_pT, myEta, m_cuts_f_e_eta) )
523  {
524  ATH_MSG_DEBUG(" ==>> Found an electron which passed the pT and eta cuts!");
525  ATH_MSG_DEBUG(" - Electron: pT = " << myPT << " MeV");
526  ATH_MSG_DEBUG(" - Electron: eta = " << myEta);
527  ATH_MSG_DEBUG("");
528  ATH_MSG_DEBUG(" ==>> Accepted the electron!");
529  ATH_MSG_DEBUG("");
530  }else
531  {
532  accept = false;
533  ATH_MSG_DEBUG(" ==>> The electron has NOT passed the pT and eta cuts!");
534  ATH_MSG_DEBUG("");
535  }
536  }
537  }
538  if ( m_cuts_f_mu_on )
539  {
540  if ( std::abs(pID) == 13 )
541  {
542  ATH_MSG_DEBUG(" ** ( pT , eta ) cuts applied on the muon --> ( " << m_cuts_f_mu_pT
543  << " , " << m_cuts_f_mu_eta << " )");
544  if ( test_cuts( myPT, m_cuts_f_mu_pT, myEta, m_cuts_f_mu_eta) )
545  {
546  ATH_MSG_DEBUG(" ==>> Found a muon which passed the pT and eta cuts!");
547  ATH_MSG_DEBUG(" - Muon: pT = " << myPT << " MeV");
548  ATH_MSG_DEBUG(" - Muon: eta = " << myEta);
549  ATH_MSG_DEBUG("");
550  ATH_MSG_DEBUG(" ==>> Accepted the muon!");
551  ATH_MSG_DEBUG("");
552  }else
553  {
554  accept = false;
555  ATH_MSG_DEBUG(" ==>> The muon has NOT passed the pT and eta cuts!");
556  ATH_MSG_DEBUG("");
557  }
558  }
559  }
560  if ( m_cuts_f_had_on )
561  {
562  if ( MC::isHadron(pID) && MC::isCharged(pID))
563  {
564  ATH_MSG_DEBUG(" ** ( pT , eta ) cuts applied on the charged hadron --> ( " << m_cuts_f_had_pT
565  << " , " << m_cuts_f_had_eta << " )");
566  if ( test_cuts( myPT, m_cuts_f_had_pT, myEta, m_cuts_f_had_eta) )
567  {
568  ATH_MSG_DEBUG(" ==>> Found a charged hadron which passed the pT and eta cuts!");
569  ATH_MSG_DEBUG(" - Charged hadron: pT = " << myPT << " MeV");
570  ATH_MSG_DEBUG(" - Charged hadron: eta = " << myEta);
571  ATH_MSG_DEBUG("");
572  ATH_MSG_DEBUG(" ==>> Accepted the charged hadron!");
573  ATH_MSG_DEBUG("");
574  }else
575  {
576  accept = false;
577  ATH_MSG_DEBUG(" ==>> The charged hadron has NOT passed the pT and eta cuts!");
578  ATH_MSG_DEBUG("");
579  }
580  }
581  }
582  if ( m_cuts_f_gam_on )
583  {
584  if ( std::abs(pID) == 22 )
585  {
586  ATH_MSG_DEBUG(" ** ( pT , eta ) cuts applied on the gamma --> ( " << m_cuts_f_gam_pT
587  << " , " << m_cuts_f_gam_eta << " )");
588  if ( test_cuts( myPT, m_cuts_f_gam_pT, myEta, m_cuts_f_gam_eta) )
589  {
590  ATH_MSG_DEBUG(" ==>> Found a gamma which passed the pT and eta cuts!");
591  ATH_MSG_DEBUG(" - Gamma: pT = " << myPT << " MeV");
592  ATH_MSG_DEBUG(" - Gamma: eta = " << myEta);
593  ATH_MSG_DEBUG("");
594  ATH_MSG_DEBUG(" ==>> Accepted the gamma!");
595  ATH_MSG_DEBUG("");
596  }else
597  {
598  accept = false;
599  ATH_MSG_DEBUG(" ==>> The gamma has NOT passed the pT and eta cuts!");
600  ATH_MSG_DEBUG("");
601  }
602  }
603  }
604  if ( m_cuts_f_K0_on )
605  {
606  if ( std::abs(pID) == 311 )
607  {
608  ATH_MSG_DEBUG(" ** ( pT , eta ) cuts applied on the K0 --> ( " << m_cuts_f_K0_pT
609  << " , " << m_cuts_f_K0_eta << " )");
610  if ( test_cuts( myPT, m_cuts_f_K0_pT, myEta, m_cuts_f_K0_eta) )
611  {
612  ATH_MSG_DEBUG(" ==>> Found a K0 which passed the pT and eta cuts!");
613  ATH_MSG_DEBUG(" - K0: pT = " << myPT << " MeV");
614  ATH_MSG_DEBUG(" - K0: eta = " << myEta);
615  ATH_MSG_DEBUG("");
616  ATH_MSG_DEBUG(" ==>> Accepted the K0!");
617  ATH_MSG_DEBUG("");
618  }else
619  {
620  accept = false;
621  ATH_MSG_DEBUG(" ==>> The K0 has NOT passed the pT and eta cuts!");
622  ATH_MSG_DEBUG("");
623  }
624  }
625  }
626 
627  return accept;
628 
629 }
630 
631 
633  const std::string& treeIDStr, const bool fromFinalB) const
634 {
635  int pID = child->pdg_id();
636  // ** Find name **
637  const HepPDT::ParticleData* pData = particleData(std::abs(pID));
638  std::string pName = "unknown particle";
639  if (pData){
640  pName = pData->name();
641  if (pID < 0) pName = "anti - " + pName;
642  }
643  ATH_MSG_DEBUG(" " << treeIDStr << " " << "Child (" << pName
644  << ") " << child<<" , from final B = " << fromFinalB);
645 
646  return;
647 }
648 
649 
651 {
652  double total = m_EventCnt;
653  ATH_MSG_ALWAYS(" I===============================================================================================");
654  ATH_MSG_ALWAYS(" I BSignalFilter Summary Report ");
655  ATH_MSG_ALWAYS(" I===============================================================================================");
657  {
658  ATH_MSG_ALWAYS(" I LVL1 muon trigger report:");
659  ATH_MSG_ALWAYS(" I Muon pT cut " << '\t' << '\t' << '\t' << '\t' << '\t' << '\t' << '\t' << '\t' << "I" << '\t'
660  << m_localLVL1MuonCutPT << " MeV ");
661  ATH_MSG_ALWAYS(" I Muon pseudo-rapidity cut" << '\t' << '\t' << '\t' << '\t' << '\t' << '\t' << '\t' << "I" << '\t'
663  ATH_MSG_ALWAYS(" I No of events containing at least " << '\t' << '\t' << '\t' << '\t' << '\t' << "I");
664  ATH_MSG_ALWAYS(" I one particle satisfying these cuts " << '\t' << '\t' << '\t' << '\t' << '\t' << "I" << '\t'
665  << m_LVL1Counter);
667  {
668  ATH_MSG_ALWAYS(" I LVL2 muon trigger report:");
669  ATH_MSG_ALWAYS(" I Muon pT cut " << '\t' << '\t' << '\t' << '\t' << '\t' << '\t' << '\t' << '\t' << "I" << '\t'
670  << m_localLVL2MuonCutPT << " MeV ");
671  ATH_MSG_ALWAYS(" I Muon pseudo-rapidity cut " << '\t' << '\t' << '\t' << '\t' << '\t' << '\t' << "I" << '\t'
673  }
675  {
676  ATH_MSG_ALWAYS(" I LVL2 electron trigger report:");
677  ATH_MSG_ALWAYS(" I Electron pT cut " << '\t' << '\t' << '\t' << '\t' << '\t' << '\t' << '\t' <<
678  " I" << '\t' << m_localLVL2ElectronCutPT << " MeV ");
679  ATH_MSG_ALWAYS(" I Electron pseudo-rapidity cut " << '\t' << '\t' << '\t' << '\t' << '\t' << "I"
680  << '\t' << m_localLVL2ElectronCutEta);
681  }
683  {
684  ATH_MSG_ALWAYS(" I No of events containing at least one muon satisfying LVL1 cut" << '\t' << "I");
685  ATH_MSG_ALWAYS(" I and at least one separate particle passing these LVL2 cuts " << '\t' << '\t' << "I" << '\t'
686  << m_LVL2Counter);
687  }
688  }
689  ATH_MSG_ALWAYS(" I Total no of input events " << '\t'<< '\t'<< '\t'<< '\t'<< '\t'<< '\t'<< '\t' << "I" << '\t'
690  << total);
691  ATH_MSG_ALWAYS(" I No of events rejected by trigger " << '\t' << '\t'<< '\t'<< '\t'<< '\t'<< '\t'<< '\t' << "I" << '\t'
692  << m_rejectedTrigger);
693  ATH_MSG_ALWAYS(" I No of events rejected in total " << '\t' << '\t'<< '\t'<< '\t'<< '\t'<< '\t'<< '\t' << "I" << '\t'
694  << m_rejectedAll);
696  ATH_MSG_ALWAYS(" I To obtain correct cross section, multiply BX in PythiaB report by " << '\t' << '\t' << "I" << '\t'
697  << m_LVL1Counter / total);
699  ATH_MSG_ALWAYS(" I To obtain correct cross section, multiply BX in PythiaB report by " << '\t' << '\t' << "I" << '\t'
700  << m_LVL2Counter / total);
702  ATH_MSG_ALWAYS(" I No trigger requests made");
703  //
704  ATH_MSG_ALWAYS(" I=========================================== End of report =====================================");
705 
706  return StatusCode::SUCCESS;
707 }
708 
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
BSignalFilter::m_cuts_f_mu_pT
double m_cuts_f_mu_pT
Definition: BSignalFilter.h:48
isBottomMeson
bool isBottomMeson(const T &p)
Definition: AtlasPID.h:473
BSignalFilter::m_TotalInvMassMax
double m_TotalInvMassMax
Definition: BSignalFilter.h:63
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
P4Helpers::invMass
double invMass(const I4Momentum &pA, const I4Momentum &pB)
invariant mass from two I4momentum references
Definition: P4Helpers.h:239
isBottomBaryon
bool isBottomBaryon(const T &p)
Definition: AtlasPID.h:489
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
BSignalFilter::filterFinalize
virtual StatusCode filterFinalize()
Definition: BSignalFilter.cxx:650
BSignalFilter::m_InvMass_switch
bool m_InvMass_switch
Definition: BSignalFilter.h:47
BSignalFilter::PrintChild
void PrintChild(const HepMC::ConstGenParticlePtr &child, const std::string &treeIDStr, const bool fromFinalB) const
Definition: BSignalFilter.cxx:632
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
python.DecayParser.parents
parents
print ("==> buf:",buf)
Definition: DecayParser.py:31
BSignalFilter::m_InvMass_PartFakeMass2
double m_InvMass_PartFakeMass2
Definition: BSignalFilter.h:61
BSignalFilter::m_TotalInvMassMin
double m_TotalInvMassMin
Definition: BSignalFilter.h:63
CutsMETMaker::accept
StatusCode accept(const xAOD::Muon *mu)
Definition: CutsMETMaker.cxx:18
BSignalFilter::m_cuts_f_had_pT
double m_cuts_f_had_pT
Definition: BSignalFilter.h:48
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
BSignalFilter::m_localLVL2ElectronCutOn
bool m_localLVL2ElectronCutOn
Definition: BSignalFilter.h:46
BSignalFilter::m_localLVL1MuonCutOn
bool m_localLVL1MuonCutOn
Definition: BSignalFilter.h:45
BSignalFilter::m_localLVL2MuonCutPT
double m_localLVL2MuonCutPT
Definition: BSignalFilter.h:52
BSignalFilter::FinalStatePassedCuts
bool FinalStatePassedCuts(const HepMC::ConstGenParticlePtr &child) const
Definition: BSignalFilter.cxx:499
BSignalFilter::m_localLVL2MuonCutOn
bool m_localLVL2MuonCutOn
Definition: BSignalFilter.h:45
BSignalFilter::m_TotalInvMass_switch
bool m_TotalInvMass_switch
Definition: BSignalFilter.h:47
BSignalFilter::m_InvMass_PartFakeMass1
double m_InvMass_PartFakeMass1
Definition: BSignalFilter.h:61
python.DataFormatRates.events
events
Definition: DataFormatRates.py:105
BSignalFilter::test_cuts
bool test_cuts(const double myPT, const double testPT, const double myEta, const double testEta) const
Definition: BSignalFilter.cxx:375
BSignalFilter::m_cuts_f_had_on
bool m_cuts_f_had_on
Definition: BSignalFilter.h:43
BSignalFilter::m_EventCnt
int m_EventCnt
Definition: BSignalFilter.h:65
BSignalFilter::LVL2_eMu_Trigger
bool LVL2_eMu_Trigger(const HepMC::ConstGenParticlePtr &child) const
Definition: BSignalFilter.cxx:396
MC::isPhysical
bool isPhysical(const T &p)
Definition: HepMCHelpers.h:32
BSignalFilter::m_rejectedTrigger
double m_rejectedTrigger
Definition: BSignalFilter.h:57
GenFilter
Base class for event generator filtering modules.
Definition: GenFilter.h:30
BSignalFilter::m_localLVL2MuonCutEta
double m_localLVL2MuonCutEta
Definition: BSignalFilter.h:53
HepMC::EVTGENUNDECAYEDSTATUS
constexpr int EVTGENUNDECAYEDSTATUS
Definition: MagicNumbers.h:42
BSignalFilter::m_cuts_f_e_pT
double m_cuts_f_e_pT
Definition: BSignalFilter.h:48
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
BSignalFilter.h
BSignalFilter::m_localLVL2ElectronCutEta
double m_localLVL2ElectronCutEta
Definition: BSignalFilter.h:54
BSignalFilter::m_localLVL1MuonCutEta
double m_localLVL1MuonCutEta
Definition: BSignalFilter.h:52
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
ATH_MSG_ALWAYS
#define ATH_MSG_ALWAYS(x)
Definition: AthMsgStreamMacros.h:35
BSignalFilter::m_cuts_f_e_eta
double m_cuts_f_e_eta
Definition: BSignalFilter.h:50
BSignalFilter::BSignalFilter
BSignalFilter(const std::string &name, ISvcLocator *pSvcLocator)
Definition: BSignalFilter.cxx:33
BSignalFilter::m_InvMass_PartId2
int m_InvMass_PartId2
Definition: BSignalFilter.h:60
BSignalFilter::m_cuts_f_had_eta
double m_cuts_f_had_eta
Definition: BSignalFilter.h:50
BSignalFilter::m_cuts_f_e_on
bool m_cuts_f_e_on
Definition: BSignalFilter.h:43
BSignalFilter::m_cuts_f_gam_eta
double m_cuts_f_gam_eta
Definition: BSignalFilter.h:51
HepMC::ConstGenParticlePtr
const GenParticle * ConstGenParticlePtr
Definition: GenParticle.h:38
BSignalFilter::m_rejectedAll
double m_rejectedAll
Definition: BSignalFilter.h:58
BSignalFilter::m_localLVL1MuonCutPT
double m_localLVL1MuonCutPT
Definition: BSignalFilter.h:52
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
MagicNumbers.h
BSignalFilter::filterEvent
virtual StatusCode filterEvent()
Definition: BSignalFilter.cxx:87
BSignalFilter::m_cuts_f_K0_pT
double m_cuts_f_K0_pT
Definition: BSignalFilter.h:49
BSignalFilter::m_LVL2Counter
double m_LVL2Counter
Definition: BSignalFilter.h:56
isHadron
bool isHadron(const T &p)
Definition: AtlasPID.h:207
BSignalFilter::m_cuts_f_gam_pT
double m_cuts_f_gam_pT
Definition: BSignalFilter.h:49
BSignalFilter::m_cuts_f_K0_eta
double m_cuts_f_K0_eta
Definition: BSignalFilter.h:51
BSignalFilter::m_cuts_f_gam_on
bool m_cuts_f_gam_on
Definition: BSignalFilter.h:44
MC::isStable
bool isStable(const T &p)
Definition: HepMCHelpers.h:30
BSignalFilter::m_cuts_f_K0_on
bool m_cuts_f_K0_on
Definition: BSignalFilter.h:44
isCharged
bool isCharged(const T &p)
Definition: AtlasPID.h:496
BSignalFilter::m_B_pdgid
int m_B_pdgid
Definition: BSignalFilter.h:59
BSignalFilter::FindAllChildren
void FindAllChildren(const HepMC::ConstGenParticlePtr &mother, std::string treeIDStr, bool fromFinalB, bool &foundSignal, bool &passedAllCuts, TLorentzVector &p1, TLorentzVector &p2, bool fromSelectedB, TLorentzVector &total_4mom) const
Definition: BSignalFilter.cxx:412
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
BSignalFilter::m_localLVL2ElectronCutPT
double m_localLVL2ElectronCutPT
Definition: BSignalFilter.h:53
MC::isDecayed
bool isDecayed(const T &p)
Definition: HepMCHelpers.h:29
BSignalFilter::m_InvMassMin
double m_InvMassMin
Definition: BSignalFilter.h:62
python.DecayParser.children
children
Definition: DecayParser.py:32
BSignalFilter::m_cuts_f_mu_on
bool m_cuts_f_mu_on
Definition: BSignalFilter.h:43
BSignalFilter::m_cuts_f_mu_eta
double m_cuts_f_mu_eta
Definition: BSignalFilter.h:50
GenBase::particleData
const HepPDT::ParticleData * particleData(int pid) const
Access an element in the particle data table.
Definition: GenBase.h:126
BSignalFilter::m_LVL1Counter
double m_LVL1Counter
Definition: BSignalFilter.h:55
BSignalFilter::m_InvMass_PartId1
int m_InvMass_PartId1
Definition: BSignalFilter.h:60
HepMCHelpers.h
BSignalFilter::m_InvMassMax
double m_InvMassMax
Definition: BSignalFilter.h:62
BSignalFilter::LVL1_Mu_Trigger
bool LVL1_Mu_Trigger(const HepMC::ConstGenParticlePtr &child) const
Definition: BSignalFilter.cxx:381