LCIO  02.17
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ProcessFlag.cc
Go to the documentation of this file.
1 
2 #include "UTIL/ProcessFlag.h"
3 
4 #include "EVENT/LCCollection.h"
5 #include "EVENT/MCParticle.h"
6 #include "UTIL/LCTOOLS.h"
7 #include "UTIL/Operators.h"
8 
9 
10 namespace UTIL{
11 
12  ProcessFlag decodeMCTruthProcess(const EVENT::LCCollection* col, int maxParticles){
13 
23 
24  ProcessFlag flag ;
25 
26 // LCTOOLS::printMCParticles( col ) ;
27 
28  std::map< int, int> pdgFSCount ;
29  EVENT::MCParticle* higgs = nullptr ;
30  int hDpdg0 =0 , hDpdg1 =0;
31  int icase = 0;
32  int n_parentless = 0;
33  EVENT::MCParticleVec hf_vec;
34 
35  int nP = maxParticles > col->getNumberOfElements() ? col->getNumberOfElements() : maxParticles ;
36 
37  for( int i=0 ; i<nP ; ++i){
38  auto* mcp = static_cast<EVENT::MCParticle*>( col->getElementAt(i) ) ;
39 
40  if( mcp->getGeneratorStatus() == 3 ){
41  icase = 1 ;
42  hf_vec = mcp->getDaughters();
43  break; // in this case we're done!
44  }
45 
46  if( mcp->getParents().empty() ){
47  n_parentless++ ;
48  }
49  }
50 
53  if (icase == 0) {
54 
55  if (n_parentless > 2) { // 2 ISRs and more parentless particles
56 
57  icase = 2;
58 
59  for( int i=0 ; i<n_parentless ; ++i){ // this assumes that all parentless particles are at the beginning of the list
60 
61  auto* mcp = static_cast<EVENT::MCParticle*>( col->getElementAt(i) ) ;
62 
63  hf_vec.push_back(mcp);
64  }
65  }
66  else if (n_parentless == 2) {
67 
68  auto* mcp = static_cast<EVENT::MCParticle*>( col->getElementAt(0) ) ;
69  auto& daughter_vec = mcp->getDaughters();
70 
71  for( unsigned i=0 ; i<daughter_vec.size() ; ++i){
72  auto* dmcp = daughter_vec[i] ;
73 
74  if (dmcp->getDaughters().size() > 1) { // found daughter with more than one daughter -> hard final state
75 
76  icase = 3; // set icase only here to keep icase == 0 in case there is no daughter with more than one daughter...
77  hf_vec = dmcp->getDaughters();
78  break;
79  }
80  }
81  }
82  else { // something is WRONG - cannot decode MC process
83 
84  icase = 0;
85  }
86  }
87 
88  if(icase == 0 || hf_vec.empty() ) {
89 
90  flag.add( PF::unknown ) ;
91  return flag ;
92  }
93 
94  // ------------------------------------------------------------------------------------------
95  // NOW we safely have the pointers to the MCParticles forming the hard final state in hf_vec !
96 
97  for(unsigned i=0 ; i<hf_vec.size() ; ++i){
98 
99  auto* mcp = hf_vec[i] ;
100 
101  int pdg = std::abs( mcp->getPDG() ) ;
102  pdgFSCount[ pdg ]++ ;
103 
105  if( pdg == 25 ){ // higgs
106 
107  while (mcp->getDaughters().size() == 1 && std::abs( mcp->getDaughters()[0]->getPDG() ) == 25) {
108 
109  // keep going while single daughter is still a (SM) Higgs
110  mcp = mcp->getDaughters()[0] ;
111  }
112 
113  hDpdg0 = mcp->getDaughters()[0]->getPDG() ;
114  if( mcp->getDaughters().size() > 1 )
115  hDpdg1 = mcp->getDaughters()[1]->getPDG() ;
116 
117  higgs = mcp ;
118  }
119  }
120  // for (icase == 2) we have falsly counted 2 ISR photons:
121  if( icase == 2 )
122  pdgFSCount[ 22 ] -= 2 ;
123 
124 
125  //---------------------------------------------------------------------------------------------------
126 
127  // fill final state particles into flag:
128  // set flag already for single occurrance of a given particle, so that eg muons and neutrinos from WW-> qqmunu will be visible
129 
130  for( auto m : pdgFSCount ){
131 
132  if( m.second > 0 )
133  flag.addFSParticles( m.first ) ;
134 
135  if( m.second > 1000000 )
136  flag.add( PF::exotic ) ;
137  }
138 
139  // fill Higgs decay
140 
141  if(higgs != nullptr){
142 
143  if( std::abs( hDpdg0 ) == std::abs( hDpdg1 ) ) // particle anti-particle pair
144  flag.addHiggsDecay( std::abs( hDpdg0 ) ) ;
145 
146  if( hDpdg0 == 22 && hDpdg1 == 23 )
147  flag.add( PF::higgsgaZ ) ;
148 
149  if( hDpdg0 == 23 && hDpdg1 == 22 )
150  flag.add( PF::higgsgaZ ) ;
151 
152  if( (std::abs( hDpdg0 ) > 1000000 ) || (std::abs( hDpdg1 ) > 1000000 ) )
153  flag.add( PF::exotic ) ;
154 
155  }
156 
157  return flag ;
158  }
159 
160 }
T empty(T...args)
void add(PF bit)
add an individual bit
Definition: ProcessFlag.h:80
bool addHiggsDecay(int pdg)
add the bit for the Higgs decaying to a particles with given PDG code - false if not known ...
Definition: ProcessFlag.h:94
STL class.
virtual LCObject * getElementAt(int index) const =0
Returns pointer to element at index - no range check, use getNumberOfEntries().
T push_back(T...args)
ProcessFlag decodeMCTruthProcess(const EVENT::LCCollection *mcps, int maxParticle=10)
Helper function that decodes the MC truth process from an LCCollection with MCParticles.
Definition: ProcessFlag.cc:12
exotic process (SUSY etc)
Higss to gamma Z decay.
The LCIO Monte Carlo particle.
Definition: MCParticle.h:27
bool addFSParticles(int pdg)
add the bit for the final state particles with given PDG code - false if not known ...
Definition: ProcessFlag.h:85
virtual int getNumberOfElements() const =0
Returns the number of elements in the collection.
T size(T...args)
The generic collection used in LCIO.
Definition: LCCollection.h:29
Helper class for defining the generated Monte Carlo physics process.
Definition: ProcessFlag.h:58
virtual const MCParticleVec & getDaughters() const =0
Returns the daughters of this particle.