Line data Source code
1 : //////////////////////////////////////////////////////////////////////////
2 : // Matt.Dobbs@Cern.CH, January 2000
3 : // particle's flow object
4 : //////////////////////////////////////////////////////////////////////////
5 :
6 : #include "HepMC/Flow.h"
7 : #include "HepMC/GenParticle.h"
8 : #include "HepMC/GenVertex.h"
9 : #include "HepMC/SearchVector.h"
10 :
11 : namespace HepMC {
12 :
13 0 : Flow::Flow( GenParticle* particle_owner )
14 0 : : m_particle_owner(particle_owner)
15 0 : {}
16 :
17 : Flow::Flow( const Flow& inflow ) :
18 0 : m_particle_owner(inflow.m_particle_owner),
19 0 : m_icode(inflow.m_icode)
20 0 : {
21 : /// copies both the m_icode AND the m_particle_owner
22 0 : }
23 :
24 0 : Flow::~Flow() {
25 0 : m_icode.clear();
26 0 : }
27 :
28 : void Flow::swap( Flow & other)
29 : {
30 0 : std::swap( m_particle_owner, other.m_particle_owner );
31 0 : m_icode.swap( other.m_icode );
32 0 : }
33 :
34 : void Flow::print( std::ostream& ostr ) const {
35 0 : ostr << "Flow(" << m_particle_owner << "): " << *this << std::endl;
36 0 : }
37 :
38 : std::vector<GenParticle*> Flow::connected_partners( int code, int code_index,
39 : int num_indices ) const {
40 : /// Returns all flow partners which have "code" in any of the
41 : /// num_indices beginning with index code_index.
42 : /// m_particle_owner is included in the result.
43 : /// Return is by value since the set should never be very big.
44 : /// EXAMPLE: if you want to find all flow partners that have the same
45 : /// code in indices 2,3,4 as particle p has in index 2, you would use:
46 : /// set<GenParticle*> result =
47 : /// p->flow().connected_partners(p->flow().icode(2),2,3);
48 : //
49 0 : std::vector<GenParticle*> output;
50 0 : for ( int i = code_index; i!=code_index+num_indices; ++i ) {
51 0 : if ( icode(i)==code ) {
52 0 : output.push_back(m_particle_owner);
53 0 : connected_partners( &output, code, code_index, num_indices );
54 0 : break;
55 : }
56 : }
57 : return output;
58 0 : }
59 :
60 : void Flow::connected_partners( std::vector<HepMC::GenParticle*>* output, int code,
61 : int code_index, int num_indices ) const
62 : {
63 : /// protected: for recursive use by Flow::connected_partners()
64 : //
65 0 : if ( !m_particle_owner ) return; // nothing to do
66 : // look for connected partners joined to this m_particle_owner
67 : // through its end_vertex
68 0 : if ( m_particle_owner->end_vertex() ) {
69 0 : for ( GenVertex::particle_iterator p
70 0 : = m_particle_owner->end_vertex()->particles_begin(family);
71 0 : p != m_particle_owner->end_vertex()->particles_end(family);
72 0 : ++p ) {
73 : // if the particle has the correct flow code and is not yet in
74 : // the set, then we recursively call connected_partners
75 0 : for ( int index = code_index; index!=code_index+num_indices;
76 0 : ++index ){
77 0 : if ( (*p)->flow(index)==code && not_in_vector(output,(*p)) ) {
78 0 : output->push_back(*p);
79 0 : (*p)->flow().connected_partners( output, code,
80 : code_index,
81 : num_indices );
82 : }
83 : }
84 : }
85 0 : }
86 : // same for production_vertex
87 0 : if ( m_particle_owner->production_vertex() ) {
88 0 : for ( GenVertex::particle_iterator p
89 0 : = m_particle_owner->production_vertex()->
90 : particles_begin( family );
91 0 : p != m_particle_owner->production_vertex()->
92 0 : particles_end( family ); ++p ) {
93 : // if the particle has the correct flow code and is not yet in
94 : // the set, then we recursively call connected_partners
95 0 : for ( int index = code_index; index!=code_index+num_indices;
96 0 : ++index ){
97 0 : if ( (*p)->flow(index)==code && not_in_vector(output,(*p)) ) {
98 0 : output->push_back(*p);
99 0 : (*p)->flow().connected_partners( output, code,
100 : code_index,
101 : num_indices );
102 : }
103 : }
104 : }
105 0 : }
106 0 : }
107 :
108 : std::vector<GenParticle*> Flow::dangling_connected_partners( int code,
109 : int code_index, int num_indices ) const {
110 0 : std::vector<GenParticle*> output;
111 0 : std::vector<GenParticle*> visited_particles;
112 0 : for ( int i = code_index; i!=code_index+num_indices; ++i ) {
113 0 : if ( icode(i)==code ) {
114 0 : visited_particles.push_back(m_particle_owner);
115 0 : dangling_connected_partners( &output, &visited_particles, code,
116 : code_index, num_indices );
117 0 : break;
118 : }
119 : }
120 : return output;
121 0 : }
122 :
123 : void Flow::dangling_connected_partners( std::vector<HepMC::GenParticle*>* output,
124 : std::vector<HepMC::GenParticle*>*
125 : visited_particles,
126 : int code, int code_index,
127 : int num_indices ) const
128 : {
129 : /// protected: for recursive use by Flow::dangling_connected_partners
130 : //
131 0 : if ( !m_particle_owner ) return; // nothing to do
132 : int count_partners = 0;
133 : // look for connected partners joined to this m_particle_owner
134 : // through its end_vertex
135 0 : if ( m_particle_owner->end_vertex() ) {
136 0 : for ( GenVertex::particle_iterator p
137 0 : = m_particle_owner->end_vertex()->particles_begin(family);
138 0 : p != m_particle_owner->end_vertex()->particles_end(family);
139 0 : ++p ) {
140 : // if the particle has the correct flow code and is not yet in
141 : // the set, then we recursively call connected_partners
142 0 : for ( int index = code_index; index!=code_index+num_indices;
143 0 : ++index ){
144 0 : if ( (*p)->flow(index)==code ) {
145 0 : if ( *p!=m_particle_owner ) ++count_partners;
146 0 : if ( not_in_vector(visited_particles,(*p)) ) {
147 0 : visited_particles->push_back(*p);
148 0 : (*p)->flow().dangling_connected_partners( output,
149 : visited_particles, code,
150 : code_index, num_indices );
151 :
152 : }
153 : }
154 : }
155 : }
156 0 : }
157 : // same for production_vertex
158 0 : if ( m_particle_owner->production_vertex() ) {
159 0 : for ( GenVertex::particle_iterator p = m_particle_owner->
160 : production_vertex()->
161 : particles_begin( family );
162 0 : p != m_particle_owner->production_vertex()->
163 : particles_end( family );
164 0 : ++p ) {
165 : // if the particle has the correct flow code and is not yet in
166 : // the set, then we recursively call connected_partners
167 0 : for ( int index = code_index; index!=code_index+num_indices;
168 0 : ++index ){
169 0 : if ( (*p)->flow(index)==code ) {
170 0 : if ( *p!=m_particle_owner ) ++count_partners;
171 0 : if ( not_in_vector(visited_particles,(*p)) ) {
172 0 : visited_particles->push_back(*p);
173 0 : (*p)->flow().dangling_connected_partners( output,
174 : visited_particles, code,
175 : code_index, num_indices );
176 :
177 : }
178 : }
179 : }
180 : }
181 0 : }
182 0 : if ( count_partners <= 1 ) output->push_back( m_particle_owner );
183 0 : }
184 :
185 : /////////////
186 : // Friends //
187 : /////////////
188 :
189 : /// send Flow informatin to ostr for printing
190 : std::ostream& operator<<( std::ostream& ostr, const Flow& f ) {
191 0 : ostr << f.m_icode.size();
192 0 : for ( std::map<int,int>::const_iterator i = f.m_icode.begin();
193 0 : i != f.m_icode.end(); ++i ) {
194 0 : ostr << " " << (*i).first << " " << (*i).second;
195 : }
196 0 : return ostr;
197 : }
198 :
199 : } // HepMC
200 :
201 :
202 :
203 :
204 :
205 :
206 :
207 :
208 :
209 :
210 :
211 :
212 :
213 :
214 :
215 :
216 :
217 :
|