hepmc - Blame information for rev 69
Subversion Repositories:
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 2 | garren | 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 | // set<GenParticle*> result=q1->dangling_connected_partners(q1->icode(1),1,2); | ||
| 45 | // this will return a list containing q1 and q4. | ||
| 46 | // set<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 <set> | ||
| 53 | |||
| 54 | namespace HepMC { | ||
| 55 | |||
| 56 | class GenParticle; | ||
| 57 | |||
| 65 | garren | 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. | ||
| 2 | garren | 66 | class Flow { |
| 67 | |||
| 65 | garren | 68 | /// for printing |
| 2 | garren | 69 | friend std::ostream& operator<<( std::ostream& ostr, const Flow& f ); |
| 70 | |||
| 71 | public: | ||
| 65 | garren | 72 | /// default constructor |
| 2 | garren | 73 | Flow( GenParticle* particle_owner = 0 ); |
| 65 | garren | 74 | /// copy |
| 2 | garren | 75 | Flow( const Flow& ); |
| 76 | virtual ~Flow(); | ||
| 65 | garren | 77 | /// make a copy |
| 2 | garren | 78 | Flow& operator=( const Flow& ); |
| 65 | garren | 79 | /// equality |
| 2 | garren | 80 | bool operator==( const Flow& a ) const; //compares only flow |
| 65 | garren | 81 | /// inequality |
| 2 | garren | 82 | bool operator!=( const Flow& a ) const; //patterns not owner |
| 83 | |||
| 65 | garren | 84 | /// print Flow information to ostr |
| 2 | garren | 85 | void print( std::ostream& ostr = std::cout ) const; |
| 86 | |||
| 65 | garren | 87 | /// returns all connected particles which have "code" in any of the |
| 88 | /// num_indices beginning with index code_index. | ||
| 2 | garren | 89 | std::set<GenParticle*> connected_partners( int code, int code_index =1, |
| 90 | int num_indices = 2 ) const; | ||
| 65 | garren | 91 | /// same as connected_partners, but returns only those particles which |
| 92 | /// are connected to <=1 other particles (i.e. the flow line "dangles" | ||
| 93 | /// at these particles) | ||
| 2 | garren | 94 | std::set<GenParticle*> dangling_connected_partners( int code, |
| 95 | int code_index = 1, int num_indices = 2 ) const; | ||
| 96 | |||
| 97 | //////////////////// | ||
| 98 | // access methods // | ||
| 99 | //////////////////// | ||
| 65 | garren | 100 | |
| 101 | /// find particle owning this Flow | ||
| 2 | garren | 102 | const GenParticle* particle_owner() const; |
| 65 | garren | 103 | /// flow code |
| 2 | garren | 104 | int icode( int code_index = 1 ) const; |
| 65 | garren | 105 | /// set flow code |
| 2 | garren | 106 | Flow set_icode( int code_index, int code ); |
| 65 | garren | 107 | /// set unique flow code |
| 2 | garren | 108 | Flow set_unique_icode( int code_index = 1 ); |
| 109 | |||
| 110 | ////////////////////// | ||
| 111 | // container access // | ||
| 112 | ////////////////////// | ||
| 113 | |||
| 65 | garren | 114 | /// return true if there is no flow container |
| 2 | garren | 115 | bool empty() const; |
| 65 | garren | 116 | /// size of flow pattern container |
| 2 | garren | 117 | int size() const; |
| 65 | garren | 118 | /// clear flow patterns |
| 2 | garren | 119 | void clear(); |
| 65 | garren | 120 | /// empty flow pattern container |
| 2 | garren | 121 | bool erase( int code_index ); |
| 122 | |||
| 65 | garren | 123 | /// iterator for flow pattern container |
| 2 | garren | 124 | typedef std::map<int,int>::iterator iterator; |
| 65 | garren | 125 | /// const iterator for flow pattern container |
| 2 | garren | 126 | typedef std::map<int,int>::const_iterator const_iterator; |
| 65 | garren | 127 | /// beginning of flow pattern container |
| 2 | garren | 128 | iterator begin(); |
| 65 | garren | 129 | /// end of flow pattern container |
| 2 | garren | 130 | iterator end(); |
| 65 | garren | 131 | /// beginning of flow pattern container |
| 2 | garren | 132 | const_iterator begin() const; |
| 65 | garren | 133 | /// end of flow pattern container |
| 2 | garren | 134 | const_iterator end() const; |
| 135 | |||
| 136 | protected: // intended for internal use only | ||
| 69 | garren | 137 | /// for internal use only |
| 2 | garren | 138 | void connected_partners( std::set<GenParticle*>* output, |
| 139 | int code, | ||
| 140 | int code_index, | ||
| 141 | int num_indices ) const; | ||
| 69 | garren | 142 | /// for internal use only |
| 2 | garren | 143 | void dangling_connected_partners( std::set<GenParticle*>* |
| 144 | output, | ||
| 145 | std::set<GenParticle*>* | ||
| 146 | visited_particles, | ||
| 147 | int code, int code_index, | ||
| 148 | int num_indices ) const; | ||
| 149 | private: | ||
| 150 | GenParticle* m_particle_owner; | ||
| 151 | std::map<int,int> m_icode; // stores flow patterns as(code_index,icode) | ||
| 152 | }; | ||
| 153 | |||
| 154 | /////////////////////////// | ||
| 155 | // INLINE Access Methods // | ||
| 156 | /////////////////////////// | ||
| 157 | |||
| 158 | inline const GenParticle* Flow::particle_owner() const { | ||
| 159 | return m_particle_owner; | ||
| 160 | } | ||
| 161 | inline int Flow::icode( int code_index ) const { | ||
| 162 | std::map<int,int>::const_iterator a = m_icode.find(code_index); | ||
| 163 | return a==m_icode.end() ? 0 : (*a).second; | ||
| 164 | } | ||
| 165 | inline Flow Flow::set_icode( int code_index, int code ) { | ||
| 166 | m_icode[code_index] = code; | ||
| 167 | return *this; | ||
| 168 | } | ||
| 169 | inline Flow Flow::set_unique_icode( int flow_num ) { | ||
| 65 | garren | 170 | /// use this method if you want to assign a unique flow code, but |
| 171 | /// do not want the burden of choosing it yourself | ||
| 31 | garren | 172 | m_icode[flow_num] = size_t(this); |
| 2 | garren | 173 | return *this; |
| 174 | } | ||
| 175 | inline bool Flow::empty() const { return (bool)m_icode.empty(); } | ||
| 176 | inline int Flow::size() const { return (int)m_icode.size(); } | ||
| 177 | inline void Flow::clear() { m_icode.clear(); } | ||
| 178 | inline bool Flow::erase( int code_index ) { | ||
| 179 | return (bool)m_icode.erase( code_index ); | ||
| 180 | } | ||
| 181 | inline Flow::iterator Flow::begin() { return m_icode.begin(); } | ||
| 182 | inline Flow::iterator Flow::end() { return m_icode.end(); } | ||
| 183 | inline Flow::const_iterator Flow::begin() const { return m_icode.begin(); } | ||
| 184 | inline Flow::const_iterator Flow::end() const { return m_icode.end(); } | ||
| 185 | |||
| 186 | /////////////////////////// | ||
| 187 | // INLINE Operators // | ||
| 188 | /////////////////////////// | ||
| 189 | |||
| 190 | inline bool Flow::operator==( const Flow& a ) const { | ||
| 191 | // equivalent flows have the same flow codes for all flow_numbers | ||
| 192 | // (i.e. their m_icode maps are identical), but they need not have the | ||
| 193 | // same m_particle owner | ||
| 194 | return (m_icode == a.m_icode); | ||
| 195 | } | ||
| 196 | inline bool Flow::operator!=( const Flow& a ) const { | ||
| 197 | return !( *this == a ); | ||
| 198 | } | ||
| 199 | inline Flow& Flow::operator=( const Flow& inflow ) { | ||
| 200 | // copies only the m_icode ... not the particle_owner | ||
| 201 | // this is intuitive behaviour so you can do | ||
| 202 | // oneparticle->flow() = otherparticle->flow() | ||
| 203 | // | ||
| 204 | m_icode = inflow.m_icode; | ||
| 205 | return *this; | ||
| 206 | } | ||
| 207 | |||
| 208 | } // HepMC | ||
| 209 | |||
| 210 | #endif // HEPMC_FLOW_H | ||
| 211 | //-------------------------------------------------------------------------- | ||
| 212 |
