![]() |
HepMC Reference DocumentationHepMC |
00001 00002 // Matt.Dobbs@Cern.CH, September 1999 00003 // Updated: 07.02.2000 no longer does particle point to ParticleData, 00004 // but rather it uses an int id which can be looked up 00005 // particle within an event coming in/out of a vertex 00007 #include "HepMC/GenEvent.h" 00008 #include "HepMC/GenVertex.h" 00009 #include "HepMC/GenParticle.h" 00010 #include <iomanip> // needed for formatted output 00011 00012 namespace HepMC { 00013 00014 GenParticle::GenParticle( void ) : 00015 m_momentum(0), m_pdg_id(0), m_status(0), m_flow(this), 00016 m_polarization(0), m_production_vertex(0), m_end_vertex(0), 00017 m_barcode(0), m_generated_mass(0.) 00018 {} 00019 //{ 00020 //s_counter++; 00021 //} 00022 00023 GenParticle::GenParticle( const FourVector& momentum, 00024 int pdg_id, int status, 00025 const Flow& itsflow, 00026 const Polarization& polar ) : 00027 m_momentum(momentum), m_pdg_id(pdg_id), m_status(status), m_flow(this), 00028 m_polarization(polar), m_production_vertex(0), m_end_vertex(0), 00029 m_barcode(0), m_generated_mass(momentum.m()) 00030 { 00031 // Establishing *this as the owner of m_flow is done above, 00032 // then we set it equal to the other flow pattern (subtle) 00033 set_flow(itsflow); 00034 //s_counter++; 00035 } 00036 00037 GenParticle::GenParticle( const GenParticle& inparticle ) : 00038 m_momentum( inparticle.momentum() ), 00039 m_pdg_id( inparticle.pdg_id() ), 00040 m_status( inparticle.status() ), 00041 m_flow(this), 00042 m_polarization( inparticle.polarization() ), 00043 m_production_vertex(0), 00044 m_end_vertex(0), 00045 m_barcode(0), 00046 m_generated_mass( inparticle.generated_mass() ) 00047 { 00052 set_production_vertex_( 0 ); 00053 set_end_vertex_( 0 ); 00054 suggest_barcode( inparticle.barcode() ); 00055 //s_counter++; 00056 } 00057 00058 GenParticle::~GenParticle() { 00059 if ( parent_event() ) parent_event()->remove_barcode(this); 00060 //s_counter--; 00061 } 00062 00063 void GenParticle::swap( GenParticle & other) 00064 { 00065 // if a container has a swap method, use that for improved performance 00066 m_momentum.swap( other.m_momentum ); 00067 std::swap( m_pdg_id, other.m_pdg_id ); 00068 std::swap( m_status, other.m_status ); 00069 m_flow.swap( other.m_flow ); 00070 m_polarization.swap( other.m_polarization ); 00071 std::swap( m_production_vertex, other.m_production_vertex ); 00072 std::swap( m_end_vertex, other.m_end_vertex ); 00073 std::swap( m_barcode, other.m_barcode ); 00074 std::swap( m_generated_mass, other.m_generated_mass ); 00075 } 00076 00077 GenParticle& GenParticle::operator=( const GenParticle& inparticle ) { 00082 00083 // best practices implementation 00084 GenParticle tmp( inparticle ); 00085 swap( tmp ); 00086 return *this; 00087 } 00088 00089 bool GenParticle::operator==( const GenParticle& a ) const { 00093 if ( a.momentum() != this->momentum() ) return false; 00094 if ( a.generated_mass() != this->generated_mass() ) return false; 00095 if ( a.pdg_id() != this->pdg_id() ) return false; 00096 if ( a.status() != this->status() ) return false; 00097 if ( a.m_flow != this->m_flow ) return false; 00098 if ( a.polarization() != this->polarization() ) return false; 00099 return true; 00100 } 00101 00102 bool GenParticle::operator!=( const GenParticle& a ) const { 00103 return !( a == *this ); 00104 } 00105 00106 void GenParticle::print( std::ostream& ostr ) const { 00109 ostr << "GenParticle: " 00110 << barcode() << " ID:" << pdg_id() 00111 << " (P,E)=" << momentum().px() << "," << momentum().py() 00112 << "," << momentum().pz() << "," << momentum().e() 00113 << " Stat:" << status(); 00114 if ( production_vertex() && production_vertex()->barcode()!=0 ) { 00115 ostr << " PV:" << production_vertex()->barcode(); 00116 } else ostr << " PV:" << production_vertex(); 00117 if ( end_vertex() && end_vertex()->barcode()!=0 ) { 00118 ostr << " EV:" << end_vertex()->barcode(); 00119 } else ostr << " EV:" << end_vertex(); 00120 ostr << " Pol:" << polarization() << " F:" << m_flow << std::endl; 00121 } 00122 00123 GenEvent* GenParticle::parent_event() const { 00124 if ( production_vertex() ) return production_vertex()->parent_event(); 00125 if ( end_vertex() ) return end_vertex()->parent_event(); 00126 return 0; 00127 } 00128 00129 void GenParticle::set_production_vertex_( GenVertex* prodvertex ) 00130 { 00131 GenEvent* its_orig_event = parent_event(); 00132 m_production_vertex = prodvertex; 00133 GenEvent* its_new_event = parent_event(); 00134 // Next bit of logic ensures the barcode maps are kept up to date 00135 // in the GenEvent containers. 00136 if ( its_orig_event != its_new_event ) { 00137 if ( its_new_event ) its_new_event->set_barcode( this, barcode() ); 00138 if ( its_orig_event ) its_orig_event->remove_barcode( this ); 00139 } 00140 } 00141 00142 void GenParticle::set_end_vertex_( GenVertex* decayvertex ) 00143 { 00144 GenEvent* its_orig_event = parent_event(); 00145 m_end_vertex = decayvertex; 00146 GenEvent* its_new_event = parent_event(); 00147 if ( its_orig_event != its_new_event ) { 00148 if ( its_new_event ) its_new_event->set_barcode( this, barcode() ); 00149 if ( its_orig_event ) its_orig_event->remove_barcode( this ); 00150 } 00151 } 00152 00153 bool GenParticle::suggest_barcode( int the_bar_code ) 00154 { 00164 if ( the_bar_code <0 ) { 00165 std::cerr << "GenParticle::suggest_barcode WARNING, particle bar " 00166 << "\n codes MUST be positive integers. Negative " 00167 << "\n integers are reserved for vertices only. Your " 00168 << "\n suggestion has been rejected." << std::endl; 00169 return false; 00170 } 00171 bool success = false; 00172 if ( parent_event() ) { 00173 success = parent_event()->set_barcode( this, the_bar_code ); 00174 } else { set_barcode_( the_bar_code ); } 00175 return success; 00176 } 00177 00179 // Static // 00181 //unsigned int GenParticle::counter() { return s_counter; } 00182 //unsigned int GenParticle::s_counter = 0U; 00183 00185 // Friends // 00187 00189 std::ostream& operator<<( std::ostream& ostr, const GenParticle& part ) { 00190 // find the current stream state 00191 std::ios_base::fmtflags orig = ostr.flags(); 00192 std::streamsize prec = ostr.precision(); 00193 ostr << " "; 00194 ostr.width(9); 00195 ostr << part.barcode(); 00196 ostr.width(9); 00197 ostr << part.pdg_id() << " "; 00198 ostr.width(9); 00199 ostr.precision(2); 00200 ostr.setf(std::ios::scientific, std::ios::floatfield); 00201 ostr.setf(std::ios_base::showpos); 00202 ostr << part.momentum().px() << ","; 00203 ostr.width(9); 00204 ostr << part.momentum().py() << ","; 00205 ostr.width(9); 00206 ostr << part.momentum().pz() << ","; 00207 ostr.width(9); 00208 ostr << part.momentum().e() << " "; 00209 ostr.setf(std::ios::fmtflags(0), std::ios::floatfield); 00210 ostr.unsetf(std::ios_base::showpos); 00211 if ( part.end_vertex() && part.end_vertex()->barcode()!=0 ) { 00212 ostr.width(3); 00213 ostr << part.status() << " "; 00214 ostr.width(9); 00215 ostr << part.end_vertex()->barcode(); 00216 } else if ( !part.end_vertex() ) { 00217 // There is no valid end_vertex 00218 // For consistency across different compilers, do not print anything 00219 ostr.width(3); 00220 ostr << part.status(); 00221 } else { 00222 // In this case the end_vertex does not have a unique 00223 // barcode assigned, so we choose instead to print its address 00224 ostr.width(3); 00225 ostr << part.status() << " "; 00226 ostr.width(9); 00227 ostr << (void*)part.end_vertex(); 00228 } 00229 // restore the stream state 00230 ostr.flags(orig); 00231 ostr.precision(prec); 00232 return ostr; 00233 } 00234 00235 00236 double GenParticle::generated_mass() const { 00237 return m_generated_mass; 00238 } 00239 00240 void GenParticle::set_generated_mass( const double & m ) { 00241 m_generated_mass = m; 00242 } 00243 00246 void GenParticle::convert_momentum( const double & f ) { 00247 m_momentum = FourVector( f*m_momentum.px(), 00248 f*m_momentum.py(), 00249 f*m_momentum.pz(), 00250 f*m_momentum.e() ); 00251 if( m_generated_mass > 0. ) m_generated_mass = f*m_generated_mass; 00252 } 00253 00254 } // HepMC 00255