Subversion Repositories hepmc

Rev

Rev 140 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 garren 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"
168 garren 9
#include "HepMC/SearchVector.h"
2 garren 10
 
11
namespace HepMC {
12
 
13
    Flow::Flow( GenParticle* particle_owner )
14
        : m_particle_owner(particle_owner)
15
    {}
16
 
17
    Flow::Flow( const Flow& inflow ) :
140 garren 18
        m_particle_owner(inflow.m_particle_owner),
19
        m_icode(inflow.m_icode)
2 garren 20
    {
65 garren 21
        /// copies both the m_icode AND the m_particle_owner
2 garren 22
    }
23
 
24
    Flow::~Flow() {
25
        m_icode.clear();
26
    }
27
 
140 garren 28
    void Flow::swap( Flow & other)
29
    {
30
        std::swap( m_particle_owner, other.m_particle_owner );
31
        m_icode.swap( other.m_icode );
32
    }
33
 
2 garren 34
    void Flow::print( std::ostream& ostr ) const {
35
        ostr << "Flow(" << m_particle_owner << "): " << *this << std::endl;
36
    }
37
 
168 garren 38
    std::vector<GenParticle*> Flow::connected_partners( int code, int code_index,
2 garren 39
                                                  int num_indices ) const {
65 garren 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);
2 garren 48
        //
168 garren 49
        std::vector<GenParticle*> output;
2 garren 50
        for ( int i = code_index; i!=code_index+num_indices; ++i ) {
51
            if ( icode(i)==code ) {
168 garren 52
                output.push_back(m_particle_owner);
2 garren 53
                connected_partners( &output, code, code_index, num_indices );
54
                break;
55
            }
56
        }
57
        return output;
58
    }
59
 
168 garren 60
    void Flow::connected_partners( std::vector<GenParticle*>* output, int code,
2 garren 61
                                   int code_index, int num_indices ) const
62
    {
65 garren 63
        /// protected: for recursive use by Flow::connected_partners()
2 garren 64
        //
65
        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
        if ( m_particle_owner->end_vertex() ) {
69
            for ( GenVertex::particle_iterator p
70
                     = m_particle_owner->end_vertex()->particles_begin(family);
71
                  p != m_particle_owner->end_vertex()->particles_end(family);
72
                  ++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
                for ( int index = code_index; index!=code_index+num_indices;
76
                      ++index ){
168 garren 77
                    if ( (*p)->flow(index)==code && not_in_vector(output,(*p)) ) {
78
                        output->push_back(*p);
2 garren 79
                        (*p)->flow().connected_partners( output, code,
80
                                                         code_index,
81
                                                         num_indices );
82
                    }
83
                }
84
            }
85
        }
86
        // same for production_vertex
87
        if ( m_particle_owner->production_vertex() ) {
88
            for ( GenVertex::particle_iterator p
89
                      = m_particle_owner->production_vertex()->
90
                      particles_begin( family );
91
                  p != m_particle_owner->production_vertex()->
92
                      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
                for ( int index = code_index; index!=code_index+num_indices;
96
                      ++index ){
168 garren 97
                    if ( (*p)->flow(index)==code && not_in_vector(output,(*p)) ) {
98
                        output->push_back(*p);
2 garren 99
                        (*p)->flow().connected_partners( output, code,
100
                                                         code_index,
101
                                                         num_indices );
102
                    }
103
                }
104
            }
105
        }
106
    }
107
 
168 garren 108
    std::vector<GenParticle*> Flow::dangling_connected_partners( int code,
2 garren 109
                                     int code_index, int num_indices ) const {
168 garren 110
        std::vector<GenParticle*> output;
111
        std::vector<GenParticle*> visited_particles;
2 garren 112
        for ( int i = code_index; i!=code_index+num_indices; ++i ) {
113
            if ( icode(i)==code ) {
168 garren 114
                visited_particles.push_back(m_particle_owner);
2 garren 115
                dangling_connected_partners( &output, &visited_particles, code,
116
                                             code_index, num_indices );
117
                break;
118
            }
119
        }
120
        return output;
121
    }
122
 
168 garren 123
    void Flow::dangling_connected_partners( std::vector<GenParticle*>* output,
124
                                            std::vector<GenParticle*>*
2 garren 125
                                            visited_particles,
126
                                            int code, int code_index,
127
                                            int num_indices ) const
128
    {
65 garren 129
        /// protected: for recursive use by Flow::dangling_connected_partners
2 garren 130
        //
131
        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
        if ( m_particle_owner->end_vertex() ) {
136
            for ( GenVertex::particle_iterator p
137
                     = m_particle_owner->end_vertex()->particles_begin(family);
138
                  p != m_particle_owner->end_vertex()->particles_end(family);
139
                  ++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
                for ( int index = code_index; index!=code_index+num_indices;
143
                      ++index ){
144
                    if ( (*p)->flow(index)==code ) {
145
                        if ( *p!=m_particle_owner ) ++count_partners;
168 garren 146
                        if ( not_in_vector(visited_particles,(*p)) ) {
147
                            visited_particles->push_back(*p);
2 garren 148
                            (*p)->flow().dangling_connected_partners( output,
149
                                                     visited_particles, code,
150
                                                     code_index, num_indices );
151
 
152
                        }
153
                    }          
154
                }
155
            }
156
        }
157
        // same for production_vertex
158
        if ( m_particle_owner->production_vertex() ) {
159
            for ( GenVertex::particle_iterator p = m_particle_owner->
160
                                                production_vertex()->
161
                                                particles_begin( family );
162
                  p != m_particle_owner->production_vertex()->
163
                                                particles_end( family );
164
                  ++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
                for ( int index = code_index; index!=code_index+num_indices;
168
                      ++index ){
169
                    if ( (*p)->flow(index)==code ) {
170
                        if ( *p!=m_particle_owner ) ++count_partners;
168 garren 171
                        if ( not_in_vector(visited_particles,(*p)) ) {
172
                            visited_particles->push_back(*p);
2 garren 173
                            (*p)->flow().dangling_connected_partners( output,
174
                                                     visited_particles, code,
175
                                                     code_index, num_indices );
176
 
177
                        }
178
                    }
179
                }
180
            }
181
        }
168 garren 182
        if ( count_partners <= 1 ) output->push_back( m_particle_owner );
2 garren 183
    }
184
 
185
    /////////////
186
    // Friends //
187
    /////////////
188
 
69 garren 189
        /// send Flow informatin to ostr for printing
2 garren 190
    std::ostream& operator<<( std::ostream& ostr, const Flow& f ) {
191
        ostr << f.m_icode.size();
192
        for ( std::map<int,int>::const_iterator i = f.m_icode.begin();
193
              i != f.m_icode.end(); ++i ) {
194
            ostr << " " << (*i).first << " " << (*i).second;
195
        }
196
        return ostr;
197
    }
198
 
199
} // HepMC
200
 
201
 
202
 
203
 
204
 
205
 
206
 
207
 
208
 
209
 
210
 
211
 
212
 
213
 
214
 
215
 
216
 
217