Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:01:09

0001 //--------------------------------------------------------------------------
0002 #ifndef HEPMC_FLOW_H
0003 #define HEPMC_FLOW_H
0004 
0005 //////////////////////////////////////////////////////////////////////////
0006 // Matt.Dobbs@Cern.CH, January 2000, refer to:
0007 // M. Dobbs and J.B. Hansen, "The HepMC C++ Monte Carlo Event Record for
0008 // High Energy Physics", Computer Physics Communications (to be published).
0009 //
0010 // particle's flow object
0011 // keeps track of an arbitrary number of flow patterns within a graph 
0012 // (i.e. color flow, charge flow, lepton number flow, ...) 
0013 // Flow patterns are coded with an integer, in the same manner as in Herwig.
0014 // Note: 0 is NOT allowed as code index nor as flow code since it
0015 //       is used to indicate null.
0016 //////////////////////////////////////////////////////////////////////////
0017 
0018 // This class can be used to keep track of flow patterns within 
0019 //  a graph. An example is color flow. If we have two quarks going through
0020 //  an s-channel gluon to form two more quarks:
0021 //
0022 //  \q1       /q3   then we can keep track of the color flow with the
0023 //   \_______/      HepMC::Flow class as follows: 
0024 //   /   g   \. 
0025 //  /q2       \q4
0026 //
0027 //  lets say the color flows from q2-->g-->q3  and q1-->g-->q4
0028 //  the individual colors are unimportant, but the flow pattern is.
0029 //  We can capture this flow by assigning the first pattern (q2-->g-->q3)
0030 //  a unique (arbitrary) flow code 678 and the second pattern (q1-->g-->q4)
0031 //  flow code 269  ( you can ask HepMC::Flow to choose
0032 //  a unique code for you using Flow::set_unique_icode() ).
0033 //  The first two code indices are reserved for color codes, so we store 
0034 //  these codes with the particles as follows:
0035 //    q2->flow().set_icode(1,678);
0036 //    g->flow().set_icode(1,678);
0037 //    q3->flow().set_icode(1,678);
0038 //    q1->flow().set_icode(1,269);
0039 //    g->flow().set_icode(2,269);
0040 //    q4->flow().set_icode(1,269);
0041 //  later on if we wish to know the color partner of q1 we can ask for a list
0042 //  of all particles connected via this code to q1 which do have less than 
0043 //  2 color partners using:
0044 //    vector<GenParticle*> result=q1->dangling_connected_partners(q1->icode(1),1,2);
0045 //  this will return a list containing q1 and q4.
0046 //    vector<GenParticle*> result=q1->connected_partners(q1->icode(1),1,2);
0047 //  would return a list containing q1, g, and q4.
0048 //
0049 
0050 #include <iostream>
0051 #include <map>
0052 #include <vector>
0053 
0054 namespace HepMC {
0055 
0056     class GenParticle;
0057 
0058     //! The flow object
0059 
0060     ///
0061     /// \class  Flow
0062     /// The particle's flow object
0063     /// keeps track of an arbitrary number of flow patterns within a graph 
0064     /// (i.e. color flow, charge flow, lepton number flow, ...) 
0065     /// Flow patterns are coded with an integer, in the same manner as in Herwig.
0066     class Flow {
0067 
0068         /// for printing
0069     friend std::ostream& operator<<( std::ostream& ostr, const Flow& f );
0070     
0071     public:
0072         /// default constructor
0073     Flow( GenParticle* particle_owner = 0 );
0074     /// copy
0075     Flow( const Flow& );
0076     virtual         ~Flow();
0077         /// swap
0078         void swap( Flow & other);
0079     /// make a copy
0080     Flow&           operator=( const Flow& );
0081     /// equality
0082     bool            operator==( const Flow& a ) const; //compares only flow
0083     /// inequality
0084     bool            operator!=( const Flow& a ) const; //patterns not owner
0085 
0086         /// print Flow information to ostr
0087     void            print( std::ostream& ostr = std::cout ) const;
0088 
0089     /// returns all connected particles which have "code" in any  of the 
0090     ///  num_indices beginning with index code_index.
0091     std::vector<HepMC::GenParticle*> connected_partners( int code, int code_index =1,
0092                            int num_indices = 2 ) const;
0093     /// same as connected_partners, but returns only those particles which
0094     ///  are connected to <=1 other particles (i.e. the flow line "dangles"
0095     ///  at these particles)
0096     std::vector<HepMC::GenParticle*> dangling_connected_partners( int code, 
0097                    int code_index = 1, int num_indices = 2 ) const;
0098 
0099     ////////////////////
0100     // access methods //
0101     ////////////////////
0102 
0103     /// find particle owning this Flow
0104     const GenParticle* particle_owner() const;
0105     /// flow code
0106     int             icode( int code_index = 1 ) const;
0107     /// set flow code
0108     Flow            set_icode( int code_index, int code );
0109     /// set unique flow code
0110     Flow            set_unique_icode( int code_index = 1 );
0111 
0112     //////////////////////
0113     // container access //
0114     //////////////////////
0115 
0116         /// return true if there is no flow container
0117     bool            empty() const;
0118     /// size of flow pattern container
0119     int             size() const;
0120     /// clear flow patterns
0121         void            clear();
0122     /// empty flow pattern container
0123     bool            erase( int code_index );
0124 
0125         /// iterator for flow pattern container
0126         typedef std::map<int,int>::iterator       iterator;
0127         /// const iterator for flow pattern container
0128         typedef std::map<int,int>::const_iterator const_iterator;
0129     /// beginning of flow pattern container
0130         iterator            begin();
0131     /// end of flow pattern container
0132         iterator            end();
0133     /// beginning of flow pattern container
0134         const_iterator      begin() const;
0135     /// end of flow pattern container
0136         const_iterator      end() const;
0137 
0138     protected: // intended for internal use only
0139         /// for internal use only
0140     void            connected_partners( std::vector<HepMC::GenParticle*>* output, 
0141                         int code,
0142                         int code_index,
0143                         int num_indices ) const;
0144         /// for internal use only
0145     void            dangling_connected_partners( std::vector<HepMC::GenParticle*>* 
0146                              output, 
0147                              std::vector<HepMC::GenParticle*>*
0148                              visited_particles, 
0149                              int code, int code_index, 
0150                              int num_indices ) const; 
0151     private:
0152     GenParticle*         m_particle_owner;
0153     std::map<int,int> m_icode; // stores flow patterns as(code_index,icode)
0154     };  
0155 
0156     ///////////////////////////
0157     // INLINE Access Methods //
0158     ///////////////////////////
0159 
0160     inline const GenParticle* Flow::particle_owner() const {
0161     return m_particle_owner;
0162     }
0163     inline int Flow::icode( int code_index ) const {
0164     std::map<int,int>::const_iterator a = m_icode.find(code_index);
0165     return a==m_icode.end() ? 0 : (*a).second;
0166     }
0167     inline Flow Flow::set_icode( int code_index, int code ) {
0168     m_icode[code_index] = code;
0169     return *this;
0170     }
0171     inline Flow Flow::set_unique_icode( int flow_num ) {
0172     /// use this method if you want to assign a unique flow code, but
0173     /// do not want the burden of choosing it yourself
0174     m_icode[flow_num] = size_t(this);
0175     return *this;
0176     }
0177     inline bool Flow::empty() const { return (bool)m_icode.empty(); }
0178     inline int Flow::size() const { return (int)m_icode.size(); }
0179     inline void Flow::clear() { m_icode.clear(); }
0180     inline bool Flow::erase( int code_index ) {
0181     // this will return true if the number of elements removed is nonzero
0182     return m_icode.erase( code_index )==0 ? false : true ;
0183     }
0184     inline Flow::iterator Flow::begin() { return m_icode.begin(); }
0185     inline Flow::iterator Flow::end() { return m_icode.end(); }
0186     inline Flow::const_iterator Flow::begin() const { return m_icode.begin(); }
0187     inline Flow::const_iterator Flow::end() const { return m_icode.end(); }
0188 
0189     ///////////////////////////
0190     // INLINE Operators      //
0191     ///////////////////////////
0192 
0193     inline bool Flow::operator==( const Flow& a ) const {
0194     /// equivalent flows have the same flow codes for all flow_numbers 
0195     /// (i.e. their m_icode maps are identical), but they need not have the
0196     /// same m_particle owner
0197     return (m_icode == a.m_icode);
0198     }
0199     inline bool Flow::operator!=( const Flow& a ) const {
0200     return !( *this == a );
0201     }
0202     inline Flow& Flow::operator=( const Flow& inflow ) {
0203     /// copies only the m_icode ... not the particle_owner
0204     /// this is intuitive behaviour so you can do
0205     /// oneparticle->flow() = otherparticle->flow()
0206     //
0207     m_icode = inflow.m_icode;
0208     return *this;
0209     }
0210 
0211 } // HepMC
0212 
0213 #endif  // HEPMC_FLOW_H
0214 //--------------------------------------------------------------------------
0215