hepmc - Blame information for rev 128
Subversion Repositories:
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 2 | garren | 1 | ////////////////////////////////////////////////////////////////////////// |
| 2 | // Matt.Dobbs@Cern.CH, September 1999 | ||
| 3 | // Updated: 07.02.2000 no longer does particle point to ParticleData, | ||
| 4 | // but rather it uses an int id which can be looked up | ||
| 5 | // particle within an event coming in/out of a vertex | ||
| 6 | ////////////////////////////////////////////////////////////////////////// | ||
| 7 | #include "HepMC/GenEvent.h" | ||
| 8 | #include "HepMC/GenVertex.h" | ||
| 9 | #include "HepMC/GenParticle.h" | ||
| 25 | garren | 10 | #include <iomanip> // needed for formatted output |
| 2 | garren | 11 | |
| 12 | namespace HepMC { | ||
| 13 | |||
| 14 | GenParticle::GenParticle( void ) : | ||
| 15 | m_momentum(0), m_pdg_id(0), m_status(0), m_flow(this), | ||
| 16 | m_polarization(0), m_production_vertex(0), m_end_vertex(0), | ||
| 95 | garren | 17 | m_barcode(0), m_generated_mass(0.), |
| 18 | m_serialnumber(++s_serialize) | ||
| 2 | garren | 19 | { |
| 20 | s_counter++; | ||
| 21 | } | ||
| 22 | |||
| 43 | garren | 23 | GenParticle::GenParticle( const FourVector& momentum, |
| 2 | garren | 24 | int pdg_id, int status, |
| 25 | const Flow& itsflow, | ||
| 26 | const Polarization& polar ) : | ||
| 27 | m_momentum(momentum), m_pdg_id(pdg_id), m_status(status), m_flow(this), | ||
| 28 | m_polarization(polar), m_production_vertex(0), m_end_vertex(0), | ||
| 95 | garren | 29 | m_barcode(0), m_generated_mass(momentum.m()), |
| 30 | m_serialnumber(++s_serialize) | ||
| 2 | garren | 31 | { |
| 32 | // Establishing *this as the owner of m_flow is done above, | ||
| 33 | // then we set it equal to the other flow pattern (subtle) | ||
| 34 | set_flow(itsflow); | ||
| 35 | s_counter++; | ||
| 36 | } | ||
| 37 | |||
| 38 | GenParticle::GenParticle( const GenParticle& inparticle ) : | ||
| 39 | m_pdg_id(0), m_status(0), m_flow(this), | ||
| 43 | garren | 40 | m_production_vertex(0), m_end_vertex(0), m_barcode(0), |
| 41 | m_generated_mass(0.) | ||
| 2 | garren | 42 | { |
| 65 | garren | 43 | /// Shallow copy: does not copy the vertex pointers |
| 44 | /// (note - impossible to copy vertex pointers which having the vertex | ||
| 45 | /// and particles in/out point-back to one another -- unless you | ||
| 46 | /// copy the entire tree -- which we don't want to do) | ||
| 2 | garren | 47 | *this = inparticle; |
| 48 | s_counter++; | ||
| 49 | } | ||
| 50 | |||
| 51 | GenParticle::~GenParticle() { | ||
| 52 | if ( parent_event() ) parent_event()->remove_barcode(this); | ||
| 53 | s_counter--; | ||
| 54 | } | ||
| 55 | |||
| 56 | GenParticle& GenParticle::operator=( const GenParticle& inparticle ) { | ||
| 65 | garren | 57 | /// Shallow: does not copy the vertex pointers |
| 58 | /// (note - impossible to copy vertex pointers which having the vertex | ||
| 59 | /// and particles in/out point-back to one another -- unless you | ||
| 60 | /// copy the entire tree -- which we don't want to do) | ||
| 128 | garren | 61 | // Protect against self assignment |
| 62 | // This works, but is not best practices | ||
| 63 | // Best practices involves a rewrite to use the copy constructor and swap | ||
| 64 | if( this != &inparticle ) { | ||
| 65 | set_momentum( inparticle.momentum() ); | ||
| 66 | set_pdg_id( inparticle.pdg_id() ); | ||
| 67 | set_status( inparticle.status() ); | ||
| 68 | set_production_vertex_( 0 ); | ||
| 69 | set_end_vertex_( 0 ); | ||
| 70 | set_flow(inparticle.m_flow); | ||
| 71 | set_polarization( inparticle.polarization() ); | ||
| 72 | suggest_barcode( inparticle.barcode() ); | ||
| 73 | set_generated_mass( inparticle.generated_mass() ); | ||
| 74 | } | ||
| 2 | garren | 75 | return *this; |
| 76 | } | ||
| 77 | |||
| 78 | bool GenParticle::operator==( const GenParticle& a ) const { | ||
| 65 | garren | 79 | /// consistent with the definition of the copy constructor as a shallow |
| 80 | /// constructor,.. this operator does not test the vertex pointers. | ||
| 81 | /// Does not compare barcodes. | ||
| 2 | garren | 82 | if ( a.momentum() != this->momentum() ) return 0; |
| 43 | garren | 83 | if ( a.generated_mass() != this->generated_mass() ) return 0; |
| 2 | garren | 84 | if ( a.pdg_id() != this->pdg_id() ) return 0; |
| 85 | if ( a.status() != this->status() ) return 0; | ||
| 86 | if ( a.m_flow != this->m_flow ) return 0; | ||
| 87 | if ( a.polarization() != this->polarization() ) return 0; | ||
| 88 | return 1; | ||
| 89 | } | ||
| 90 | |||
| 91 | bool GenParticle::operator!=( const GenParticle& a ) const { | ||
| 92 | return !( a == *this ); | ||
| 93 | } | ||
| 94 | |||
| 95 | void GenParticle::print( std::ostream& ostr ) const { | ||
| 65 | garren | 96 | /// Dump this particle's full info to ostr, where by default |
| 97 | /// particle.print(); will dump to cout. | ||
| 2 | garren | 98 | ostr << "GenParticle: " |
| 99 | << barcode() << " ID:" << pdg_id() | ||
| 100 | << " (P,E)=" << momentum().px() << "," << momentum().py() | ||
| 101 | << "," << momentum().pz() << "," << momentum().e() | ||
| 102 | << " Stat:" << status(); | ||
| 103 | if ( production_vertex() && production_vertex()->barcode()!=0 ) { | ||
| 104 | ostr << " PV:" << production_vertex()->barcode(); | ||
| 105 | } else ostr << " PV:" << production_vertex(); | ||
| 106 | if ( end_vertex() && end_vertex()->barcode()!=0 ) { | ||
| 107 | ostr << " EV:" << end_vertex()->barcode(); | ||
| 108 | } else ostr << " EV:" << end_vertex(); | ||
| 109 | ostr << " Pol:" << polarization() << " F:" << m_flow << std::endl; | ||
| 110 | } | ||
| 111 | |||
| 112 | GenEvent* GenParticle::parent_event() const { | ||
| 113 | if ( production_vertex() ) return production_vertex()->parent_event(); | ||
| 114 | if ( end_vertex() ) return end_vertex()->parent_event(); | ||
| 115 | return 0; | ||
| 116 | } | ||
| 117 | |||
| 118 | void GenParticle::set_production_vertex_( GenVertex* prodvertex ) | ||
| 119 | { | ||
| 120 | GenEvent* its_orig_event = parent_event(); | ||
| 121 | m_production_vertex = prodvertex; | ||
| 122 | GenEvent* its_new_event = parent_event(); | ||
| 123 | // Next bit of logic ensures the barcode maps are kept up to date | ||
| 124 | // in the GenEvent containers. | ||
| 125 | if ( its_orig_event != its_new_event ) { | ||
| 126 | if ( its_new_event ) its_new_event->set_barcode( this, barcode() ); | ||
| 127 | if ( its_orig_event ) its_orig_event->remove_barcode( this ); | ||
| 128 | } | ||
| 129 | } | ||
| 130 | |||
| 131 | void GenParticle::set_end_vertex_( GenVertex* decayvertex ) | ||
| 132 | { | ||
| 133 | GenEvent* its_orig_event = parent_event(); | ||
| 134 | m_end_vertex = decayvertex; | ||
| 135 | GenEvent* its_new_event = parent_event(); | ||
| 136 | if ( its_orig_event != its_new_event ) { | ||
| 137 | if ( its_new_event ) its_new_event->set_barcode( this, barcode() ); | ||
| 138 | if ( its_orig_event ) its_orig_event->remove_barcode( this ); | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | bool GenParticle::suggest_barcode( int the_bar_code ) | ||
| 143 | { | ||
| 65 | garren | 144 | /// allows a barcode to be suggested for this particle. |
| 145 | /// In general it is better to let the event pick the barcode for | ||
| 146 | /// you, which is automatic. | ||
| 147 | /// Returns TRUE if the suggested barcode has been accepted (i.e. the | ||
| 148 | /// suggested barcode has not already been used in the event, | ||
| 149 | /// and so it was used). | ||
| 150 | /// Returns FALSE if the suggested barcode was rejected, or if the | ||
| 151 | /// particle is not yet part of an event, such that it is not yet | ||
| 152 | /// possible to know if the suggested barcode will be accepted). | ||
| 2 | garren | 153 | if ( the_bar_code <0 ) { |
| 154 | std::cerr << "GenParticle::suggest_barcode WARNING, particle bar " | ||
| 155 | << "\n codes MUST be positive integers. Negative " | ||
| 156 | << "\n integers are reserved for vertices only. Your " | ||
| 157 | << "\n suggestion has been rejected." << std::endl; | ||
| 158 | return false; | ||
| 159 | } | ||
| 160 | bool success = false; | ||
| 161 | if ( parent_event() ) { | ||
| 162 | success = parent_event()->set_barcode( this, the_bar_code ); | ||
| 163 | } else { set_barcode_( the_bar_code ); } | ||
| 164 | return success; | ||
| 165 | } | ||
| 166 | |||
| 167 | ///////////// | ||
| 168 | // Static // | ||
| 169 | ///////////// | ||
| 170 | unsigned int GenParticle::counter() { return s_counter; } | ||
| 101 | garren | 171 | unsigned int GenParticle::s_counter = 0U; |
| 2 | garren | 172 | |
| 111 | garren | 173 | hepmc_uint64_t GenParticle::serialnumber() const { return m_serialnumber; } |
| 174 | hepmc_uint64_t GenParticle::s_serialize = 0U; | ||
| 95 | garren | 175 | |
| 2 | garren | 176 | ///////////// |
| 177 | // Friends // | ||
| 178 | ///////////// | ||
| 69 | garren | 179 | |
| 180 | /// Dump this particle's full info to ostr | ||
| 2 | garren | 181 | std::ostream& operator<<( std::ostream& ostr, const GenParticle& part ) { |
| 25 | garren | 182 | ostr << " "; |
| 183 | ostr.width(9); | ||
| 184 | ostr << part.barcode(); | ||
| 185 | ostr.width(9); | ||
| 186 | ostr << part.pdg_id() << " "; | ||
| 187 | ostr.width(9); | ||
| 188 | ostr.precision(2); | ||
| 189 | ostr.setf(std::ios::scientific, std::ios::floatfield); | ||
| 190 | ostr.setf(std::ios_base::showpos); | ||
| 191 | ostr << part.momentum().px() << ","; | ||
| 192 | ostr.width(9); | ||
| 193 | ostr.precision(2); | ||
| 194 | ostr << part.momentum().py() << ","; | ||
| 195 | ostr.width(9); | ||
| 196 | ostr.precision(2); | ||
| 197 | ostr << part.momentum().pz() << ","; | ||
| 198 | ostr.width(9); | ||
| 199 | ostr.precision(2); | ||
| 200 | ostr << part.momentum().e() << " "; | ||
| 201 | ostr.setf(std::ios::fmtflags(0), std::ios::floatfield); | ||
| 202 | ostr.unsetf(std::ios_base::showpos); | ||
| 2 | garren | 203 | if ( part.end_vertex() && part.end_vertex()->barcode()!=0 ) { |
| 25 | garren | 204 | ostr.width(3); |
| 205 | ostr << part.status() << " "; | ||
| 206 | ostr.width(9); | ||
| 207 | ostr << part.end_vertex()->barcode(); | ||
| 208 | } else if ( !part.end_vertex() ) { | ||
| 209 | // There is no valid end_vertex | ||
| 210 | // For consistency across different compilers, do not print anything | ||
| 211 | ostr.width(3); | ||
| 212 | ostr << part.status(); | ||
| 2 | garren | 213 | } else { |
| 214 | // In this case the end_vertex does not have a unique | ||
| 215 | // barcode assigned, so we choose instead to print its address | ||
| 25 | garren | 216 | ostr.width(3); |
| 217 | ostr << part.status() << " "; | ||
| 218 | ostr.width(9); | ||
| 219 | ostr << (void*)part.end_vertex(); | ||
| 2 | garren | 220 | } |
| 25 | garren | 221 | return ostr; |
| 2 | garren | 222 | } |
| 223 | |||
| 43 | garren | 224 | |
| 225 | double GenParticle::generated_mass() const { | ||
| 226 | return m_generated_mass; | ||
| 227 | } | ||
| 228 | |||
| 229 | void GenParticle::set_generated_mass( const double & m ) { | ||
| 230 | m_generated_mass = m; | ||
| 231 | } | ||
| 232 | |||
| 2 | garren | 233 | } // HepMC |
| 234 |
