Subversion Repositories hepmc

Rev

Rev 120 | Rev 168 | 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"
95 garren 8
#include "HepMC/GenParticleComparison.h"
2 garren 9
#include "HepMC/GenVertex.h"
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
 
95 garren 38
    std::set<GenParticle*,GenParticleComparison> 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
        //
95 garren 49
        std::set<GenParticle*,GenParticleComparison> output;
2 garren 50
        for ( int i = code_index; i!=code_index+num_indices; ++i ) {
51
            if ( icode(i)==code ) {
52
                output.insert(m_particle_owner);
53
                connected_partners( &output, code, code_index, num_indices );
54
                break;
55
            }
56
        }
57
        return output;
58
    }
59
 
95 garren 60
    void Flow::connected_partners( std::set<GenParticle*,GenParticleComparison>* 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 ){
77
                    if ( (*p)->flow(index)==code &&
78
                         output->insert(*p).second ) {
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 ){
97
                    if ( (*p)->flow(index)==code &&
98
                         output->insert(*p).second ) {
99
                        (*p)->flow().connected_partners( output, code,
100
                                                         code_index,
101
                                                         num_indices );
102
                    }
103
                }
104
            }
105
        }
106
    }
107
 
95 garren 108
    std::set<GenParticle*,GenParticleComparison> Flow::dangling_connected_partners( int code,
2 garren 109
                                     int code_index, int num_indices ) const {
95 garren 110
        std::set<GenParticle*,GenParticleComparison> output;
111
        std::set<GenParticle*,GenParticleComparison> visited_particles;
2 garren 112
        for ( int i = code_index; i!=code_index+num_indices; ++i ) {
113
            if ( icode(i)==code ) {
114
                visited_particles.insert(m_particle_owner);
115
                dangling_connected_partners( &output, &visited_particles, code,
116
                                             code_index, num_indices );
117
                break;
118
            }
119
        }
120
        return output;
121
    }
122
 
95 garren 123
    void Flow::dangling_connected_partners( std::set<GenParticle*,GenParticleComparison>* output,
124
                                            std::set<GenParticle*,GenParticleComparison>*
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;
146
                        if ( visited_particles->insert(*p).second ) {
147
                            (*p)->flow().dangling_connected_partners( output,
148
                                                     visited_particles, code,
149
                                                     code_index, num_indices );
150
 
151
                        }
152
                    }          
153
                }
154
            }
155
        }
156
        // same for production_vertex
157
        if ( m_particle_owner->production_vertex() ) {
158
            for ( GenVertex::particle_iterator p = m_particle_owner->
159
                                                production_vertex()->
160
                                                particles_begin( family );
161
                  p != m_particle_owner->production_vertex()->
162
                                                particles_end( family );
163
                  ++p ) {
164
                // if the particle has the correct flow code and is not yet in 
165
                // the set, then we recursively call connected_partners
166
                for ( int index = code_index; index!=code_index+num_indices;
167
                      ++index ){
168
                    if ( (*p)->flow(index)==code ) {
169
                        if ( *p!=m_particle_owner ) ++count_partners;
170
                        if ( visited_particles->insert(*p).second ) {
171
                            (*p)->flow().dangling_connected_partners( output,
172
                                                     visited_particles, code,
173
                                                     code_index, num_indices );
174
 
175
                        }
176
                    }
177
                }
178
            }
179
        }
180
        if ( count_partners <= 1 ) output->insert( m_particle_owner );
181
    }
182
 
183
    /////////////
184
    // Friends //
185
    /////////////
186
 
69 garren 187
        /// send Flow informatin to ostr for printing
2 garren 188
    std::ostream& operator<<( std::ostream& ostr, const Flow& f ) {
189
        ostr << f.m_icode.size();
190
        for ( std::map<int,int>::const_iterator i = f.m_icode.begin();
191
              i != f.m_icode.end(); ++i ) {
192
            ostr << " " << (*i).first << " " << (*i).second;
193
        }
194
        return ostr;
195
    }
196
 
197
} // HepMC
198
 
199
 
200
 
201
 
202
 
203
 
204
 
205
 
206
 
207
 
208
 
209
 
210
 
211
 
212
 
213
 
214
 
215