Line data Source code
1 : //--------------------------------------------------------------------------
2 : #ifndef HEPMC_FLOW_H
3 : #define HEPMC_FLOW_H
4 :
5 : //////////////////////////////////////////////////////////////////////////
6 : // Matt.Dobbs@Cern.CH, January 2000, refer to:
7 : // M. Dobbs and J.B. Hansen, "The HepMC C++ Monte Carlo Event Record for
8 : // High Energy Physics", Computer Physics Communications (to be published).
9 : //
10 : // particle's flow object
11 : // keeps track of an arbitrary number of flow patterns within a graph
12 : // (i.e. color flow, charge flow, lepton number flow, ...)
13 : // Flow patterns are coded with an integer, in the same manner as in Herwig.
14 : // Note: 0 is NOT allowed as code index nor as flow code since it
15 : // is used to indicate null.
16 : //////////////////////////////////////////////////////////////////////////
17 :
18 : // This class can be used to keep track of flow patterns within
19 : // a graph. An example is color flow. If we have two quarks going through
20 : // an s-channel gluon to form two more quarks:
21 : //
22 : // \q1 /q3 then we can keep track of the color flow with the
23 : // \_______/ HepMC::Flow class as follows:
24 : // / g \.
25 : // /q2 \q4
26 : //
27 : // lets say the color flows from q2-->g-->q3 and q1-->g-->q4
28 : // the individual colors are unimportant, but the flow pattern is.
29 : // We can capture this flow by assigning the first pattern (q2-->g-->q3)
30 : // a unique (arbitrary) flow code 678 and the second pattern (q1-->g-->q4)
31 : // flow code 269 ( you can ask HepMC::Flow to choose
32 : // a unique code for you using Flow::set_unique_icode() ).
33 : // The first two code indices are reserved for color codes, so we store
34 : // these codes with the particles as follows:
35 : // q2->flow().set_icode(1,678);
36 : // g->flow().set_icode(1,678);
37 : // q3->flow().set_icode(1,678);
38 : // q1->flow().set_icode(1,269);
39 : // g->flow().set_icode(2,269);
40 : // q4->flow().set_icode(1,269);
41 : // later on if we wish to know the color partner of q1 we can ask for a list
42 : // of all particles connected via this code to q1 which do have less than
43 : // 2 color partners using:
44 : // vector<GenParticle*> result=q1->dangling_connected_partners(q1->icode(1),1,2);
45 : // this will return a list containing q1 and q4.
46 : // vector<GenParticle*> result=q1->connected_partners(q1->icode(1),1,2);
47 : // would return a list containing q1, g, and q4.
48 : //
49 :
50 : #include <iostream>
51 : #include <map>
52 : #include <vector>
53 :
54 : namespace HepMC {
55 :
56 : class GenParticle;
57 :
58 : //! The flow object
59 :
60 : ///
61 : /// \class Flow
62 : /// The particle's flow object
63 : /// keeps track of an arbitrary number of flow patterns within a graph
64 : /// (i.e. color flow, charge flow, lepton number flow, ...)
65 : /// Flow patterns are coded with an integer, in the same manner as in Herwig.
66 : class Flow {
67 :
68 : /// for printing
69 : friend std::ostream& operator<<( std::ostream& ostr, const Flow& f );
70 :
71 : public:
72 : /// default constructor
73 : Flow( GenParticle* particle_owner = 0 );
74 : /// copy
75 : Flow( const Flow& );
76 : virtual ~Flow();
77 : /// swap
78 : void swap( Flow & other);
79 : /// make a copy
80 : Flow& operator=( const Flow& );
81 : /// equality
82 : bool operator==( const Flow& a ) const; //compares only flow
83 : /// inequality
84 : bool operator!=( const Flow& a ) const; //patterns not owner
85 :
86 : /// print Flow information to ostr
87 : void print( std::ostream& ostr = std::cout ) const;
88 :
89 : /// returns all connected particles which have "code" in any of the
90 : /// num_indices beginning with index code_index.
91 : std::vector<HepMC::GenParticle*> connected_partners( int code, int code_index =1,
92 : int num_indices = 2 ) const;
93 : /// same as connected_partners, but returns only those particles which
94 : /// are connected to <=1 other particles (i.e. the flow line "dangles"
95 : /// at these particles)
96 : std::vector<HepMC::GenParticle*> dangling_connected_partners( int code,
97 : int code_index = 1, int num_indices = 2 ) const;
98 :
99 : ////////////////////
100 : // access methods //
101 : ////////////////////
102 :
103 : /// find particle owning this Flow
104 : const GenParticle* particle_owner() const;
105 : /// flow code
106 : int icode( int code_index = 1 ) const;
107 : /// set flow code
108 : Flow set_icode( int code_index, int code );
109 : /// set unique flow code
110 : Flow set_unique_icode( int code_index = 1 );
111 :
112 : //////////////////////
113 : // container access //
114 : //////////////////////
115 :
116 : /// return true if there is no flow container
117 : bool empty() const;
118 : /// size of flow pattern container
119 : int size() const;
120 : /// clear flow patterns
121 : void clear();
122 : /// empty flow pattern container
123 : bool erase( int code_index );
124 :
125 : /// iterator for flow pattern container
126 : typedef std::map<int,int>::iterator iterator;
127 : /// const iterator for flow pattern container
128 : typedef std::map<int,int>::const_iterator const_iterator;
129 : /// beginning of flow pattern container
130 : iterator begin();
131 : /// end of flow pattern container
132 : iterator end();
133 : /// beginning of flow pattern container
134 : const_iterator begin() const;
135 : /// end of flow pattern container
136 : const_iterator end() const;
137 :
138 : protected: // intended for internal use only
139 : /// for internal use only
140 : void connected_partners( std::vector<HepMC::GenParticle*>* output,
141 : int code,
142 : int code_index,
143 : int num_indices ) const;
144 : /// for internal use only
145 : void dangling_connected_partners( std::vector<HepMC::GenParticle*>*
146 : output,
147 : std::vector<HepMC::GenParticle*>*
148 : visited_particles,
149 : int code, int code_index,
150 : int num_indices ) const;
151 : private:
152 : GenParticle* m_particle_owner;
153 : std::map<int,int> m_icode; // stores flow patterns as(code_index,icode)
154 : };
155 :
156 : ///////////////////////////
157 : // INLINE Access Methods //
158 : ///////////////////////////
159 :
160 : inline const GenParticle* Flow::particle_owner() const {
161 : return m_particle_owner;
162 : }
163 : inline int Flow::icode( int code_index ) const {
164 0 : std::map<int,int>::const_iterator a = m_icode.find(code_index);
165 0 : return a==m_icode.end() ? 0 : (*a).second;
166 0 : }
167 : inline Flow Flow::set_icode( int code_index, int code ) {
168 0 : m_icode[code_index] = code;
169 0 : return *this;
170 : }
171 : inline Flow Flow::set_unique_icode( int flow_num ) {
172 : /// use this method if you want to assign a unique flow code, but
173 : /// do not want the burden of choosing it yourself
174 : m_icode[flow_num] = size_t(this);
175 : return *this;
176 : }
177 : inline bool Flow::empty() const { return (bool)m_icode.empty(); }
178 : inline int Flow::size() const { return (int)m_icode.size(); }
179 : inline void Flow::clear() { m_icode.clear(); }
180 : inline bool Flow::erase( int code_index ) {
181 : // this will return true if the number of elements removed is nonzero
182 : return m_icode.erase( code_index )==0 ? false : true ;
183 : }
184 : inline Flow::iterator Flow::begin() { return m_icode.begin(); }
185 : inline Flow::iterator Flow::end() { return m_icode.end(); }
186 : inline Flow::const_iterator Flow::begin() const { return m_icode.begin(); }
187 : inline Flow::const_iterator Flow::end() const { return m_icode.end(); }
188 :
189 : ///////////////////////////
190 : // INLINE Operators //
191 : ///////////////////////////
192 :
193 : inline bool Flow::operator==( const Flow& a ) const {
194 : /// equivalent flows have the same flow codes for all flow_numbers
195 : /// (i.e. their m_icode maps are identical), but they need not have the
196 : /// same m_particle owner
197 0 : return (m_icode == a.m_icode);
198 : }
199 : inline bool Flow::operator!=( const Flow& a ) const {
200 0 : return !( *this == a );
201 : }
202 : inline Flow& Flow::operator=( const Flow& inflow ) {
203 : /// copies only the m_icode ... not the particle_owner
204 : /// this is intuitive behaviour so you can do
205 : /// oneparticle->flow() = otherparticle->flow()
206 : //
207 0 : m_icode = inflow.m_icode;
208 0 : return *this;
209 : }
210 :
211 : } // HepMC
212 :
213 : #endif // HEPMC_FLOW_H
214 : //--------------------------------------------------------------------------
215 :
|