hepmc - Blame information for rev 31
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 | |||
| 58 | class Flow { | ||
| 59 | |||
| 60 | friend std::ostream& operator<<( std::ostream& ostr, const Flow& f ); | ||
| 61 | |||
| 62 | public: | ||
| 63 | Flow( GenParticle* particle_owner = 0 ); | ||
| 64 | Flow( const Flow& ); | ||
| 65 | virtual ~Flow(); | ||
| 66 | Flow& operator=( const Flow& ); | ||
| 67 | bool operator==( const Flow& a ) const; //compares only flow | ||
| 68 | bool operator!=( const Flow& a ) const; //patterns not owner | ||
| 69 | |||
| 70 | void print( std::ostream& ostr = std::cout ) const; | ||
| 71 | |||
| 72 | // returns all connected particles which have "code" in any of the | ||
| 73 | // num_indices beginning with index code_index. | ||
| 74 | std::set<GenParticle*> connected_partners( int code, int code_index =1, | ||
| 75 | int num_indices = 2 ) const; | ||
| 76 | // same as connected_partners, but returns only those particles which | ||
| 77 | // are connected to <=1 other particles (i.e. the flow line "dangles" | ||
| 78 | // at these particles) | ||
| 79 | std::set<GenParticle*> dangling_connected_partners( int code, | ||
| 80 | int code_index = 1, int num_indices = 2 ) const; | ||
| 81 | |||
| 82 | //////////////////// | ||
| 83 | // access methods // | ||
| 84 | //////////////////// | ||
| 85 | const GenParticle* particle_owner() const; | ||
| 86 | int icode( int code_index = 1 ) const; | ||
| 87 | Flow set_icode( int code_index, int code ); | ||
| 88 | Flow set_unique_icode( int code_index = 1 ); | ||
| 89 | |||
| 90 | ////////////////////// | ||
| 91 | // container access // | ||
| 92 | ////////////////////// | ||
| 93 | |||
| 94 | bool empty() const; | ||
| 95 | int size() const; | ||
| 96 | void clear(); | ||
| 97 | bool erase( int code_index ); | ||
| 98 | |||
| 99 | typedef std::map<int,int>::iterator iterator; | ||
| 100 | typedef std::map<int,int>::const_iterator const_iterator; | ||
| 101 | iterator begin(); | ||
| 102 | iterator end(); | ||
| 103 | const_iterator begin() const; | ||
| 104 | const_iterator end() const; | ||
| 105 | |||
| 106 | protected: // intended for internal use only | ||
| 107 | void connected_partners( std::set<GenParticle*>* output, | ||
| 108 | int code, | ||
| 109 | int code_index, | ||
| 110 | int num_indices ) const; | ||
| 111 | void dangling_connected_partners( std::set<GenParticle*>* | ||
| 112 | output, | ||
| 113 | std::set<GenParticle*>* | ||
| 114 | visited_particles, | ||
| 115 | int code, int code_index, | ||
| 116 | int num_indices ) const; | ||
| 117 | private: | ||
| 118 | GenParticle* m_particle_owner; | ||
| 119 | std::map<int,int> m_icode; // stores flow patterns as(code_index,icode) | ||
| 120 | }; | ||
| 121 | |||
| 122 | /////////////////////////// | ||
| 123 | // INLINE Access Methods // | ||
| 124 | /////////////////////////// | ||
| 125 | |||
| 126 | inline const GenParticle* Flow::particle_owner() const { | ||
| 127 | return m_particle_owner; | ||
| 128 | } | ||
| 129 | inline int Flow::icode( int code_index ) const { | ||
| 130 | std::map<int,int>::const_iterator a = m_icode.find(code_index); | ||
| 131 | return a==m_icode.end() ? 0 : (*a).second; | ||
| 132 | } | ||
| 133 | inline Flow Flow::set_icode( int code_index, int code ) { | ||
| 134 | m_icode[code_index] = code; | ||
| 135 | return *this; | ||
| 136 | } | ||
| 137 | inline Flow Flow::set_unique_icode( int flow_num ) { | ||
| 138 | // use this method if you want to assign a unique flow code, but | ||
| 139 | // do not want the burden of choosing it yourself | ||
| 31 | garren | 140 | m_icode[flow_num] = size_t(this); |
| 2 | garren | 141 | return *this; |
| 142 | } | ||
| 143 | inline bool Flow::empty() const { return (bool)m_icode.empty(); } | ||
| 144 | inline int Flow::size() const { return (int)m_icode.size(); } | ||
| 145 | inline void Flow::clear() { m_icode.clear(); } | ||
| 146 | inline bool Flow::erase( int code_index ) { | ||
| 147 | return (bool)m_icode.erase( code_index ); | ||
| 148 | } | ||
| 149 | inline Flow::iterator Flow::begin() { return m_icode.begin(); } | ||
| 150 | inline Flow::iterator Flow::end() { return m_icode.end(); } | ||
| 151 | inline Flow::const_iterator Flow::begin() const { return m_icode.begin(); } | ||
| 152 | inline Flow::const_iterator Flow::end() const { return m_icode.end(); } | ||
| 153 | |||
| 154 | /////////////////////////// | ||
| 155 | // INLINE Operators // | ||
| 156 | /////////////////////////// | ||
| 157 | |||
| 158 | inline bool Flow::operator==( const Flow& a ) const { | ||
| 159 | // equivalent flows have the same flow codes for all flow_numbers | ||
| 160 | // (i.e. their m_icode maps are identical), but they need not have the | ||
| 161 | // same m_particle owner | ||
| 162 | return (m_icode == a.m_icode); | ||
| 163 | } | ||
| 164 | inline bool Flow::operator!=( const Flow& a ) const { | ||
| 165 | return !( *this == a ); | ||
| 166 | } | ||
| 167 | inline Flow& Flow::operator=( const Flow& inflow ) { | ||
| 168 | // copies only the m_icode ... not the particle_owner | ||
| 169 | // this is intuitive behaviour so you can do | ||
| 170 | // oneparticle->flow() = otherparticle->flow() | ||
| 171 | // | ||
| 172 | m_icode = inflow.m_icode; | ||
| 173 | return *this; | ||
| 174 | } | ||
| 175 | |||
| 176 | } // HepMC | ||
| 177 | |||
| 178 | #endif // HEPMC_FLOW_H | ||
| 179 | //-------------------------------------------------------------------------- | ||
| 180 |
