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