hepmc - Rev 448

Subversion Repositories:
Rev:
  1. //////////////////////////////////////////////////////////////////////////
  2. // Matt.Dobbs@Cern.CH, September 1999
  3. // Updated: 07.02.2000 no longer does particle point to ParticleData,
  4. //                     but rather it uses an int id which can be looked up
  5. // particle within an event coming in/out of a vertex
  6. //////////////////////////////////////////////////////////////////////////
  7. #include "HepMC/GenEvent.h"
  8. #include "HepMC/GenVertex.h"
  9. #include "HepMC/GenParticle.h"
  10. #include <iomanip>       // needed for formatted output
  11.  
  12. namespace HepMC {
  13.  
  14.     GenParticle::GenParticle( void ) :
  15.         m_momentum(0), m_pdg_id(0), m_status(0), m_flow(this),
  16.         m_polarization(0), m_production_vertex(0), m_end_vertex(0),
  17.         m_barcode(0), m_generated_mass(0.)
  18.     {}
  19.     //{
  20.         //s_counter++;
  21.     //}
  22.  
  23.     GenParticle::GenParticle( const FourVector& momentum,
  24.                         int pdg_id, int status,
  25.                         const Flow& itsflow,
  26.                         const Polarization& polar ) :
  27.         m_momentum(momentum), m_pdg_id(pdg_id), m_status(status), m_flow(this),
  28.         m_polarization(polar), m_production_vertex(0), m_end_vertex(0),
  29.         m_barcode(0), m_generated_mass(momentum.m())
  30.     {
  31.         // Establishing *this as the owner of m_flow is done above,
  32.         // then we set it equal to the other flow pattern (subtle)
  33.         set_flow(itsflow);
  34.         //s_counter++;
  35.     }
  36.  
  37.     GenParticle::GenParticle( const GenParticle& inparticle ) :
  38.         m_momentum( inparticle.momentum() ),
  39.         m_pdg_id( inparticle.pdg_id() ),
  40.         m_status( inparticle.status() ),
  41.         m_flow(inparticle.flow()),
  42.         m_polarization( inparticle.polarization() ),
  43.         m_production_vertex(0),
  44.         m_end_vertex(0),
  45.         m_barcode(0),
  46.         m_generated_mass( inparticle.generated_mass() )
  47.     {
  48.         /// Shallow copy: does not copy the vertex pointers
  49.         /// (note - impossible to copy vertex pointers which having the vertex
  50.         ///         and particles in/out point-back to one another -- unless you
  51.         ///         copy the entire tree -- which we don't want to do)
  52.         set_production_vertex_( 0 );
  53.         set_end_vertex_( 0 );
  54.         suggest_barcode( inparticle.barcode() );
  55.         //s_counter++;
  56.     }
  57.  
  58.     GenParticle::~GenParticle() {    
  59.         if ( parent_event() ) parent_event()->remove_barcode(this);
  60.         //s_counter--;
  61.     }
  62.  
  63.     void GenParticle::swap( GenParticle & other)
  64.     {
  65.         // if a container has a swap method, use that for improved performance
  66.         m_momentum.swap( other.m_momentum );
  67.         std::swap( m_pdg_id, other.m_pdg_id );
  68.         std::swap( m_status, other.m_status );
  69.         m_flow.swap( other.m_flow );
  70.         m_polarization.swap( other.m_polarization );
  71.         std::swap( m_production_vertex, other.m_production_vertex );
  72.         std::swap( m_end_vertex, other.m_end_vertex );
  73.         std::swap( m_barcode, other.m_barcode );
  74.         std::swap( m_generated_mass, other.m_generated_mass );
  75.     }
  76.  
  77.     GenParticle& GenParticle::operator=( const GenParticle& inparticle ) {
  78.         /// Shallow: does not copy the vertex pointers
  79.         /// (note - impossible to copy vertex pointers which having the vertex
  80.         ///         and particles in/out point-back to one another -- unless you
  81.         ///         copy the entire tree -- which we don't want to do)
  82.  
  83.         // best practices implementation
  84.         GenParticle tmp( inparticle );
  85.         swap( tmp );
  86.         return *this;
  87.     }
  88.  
  89.     bool GenParticle::operator==( const GenParticle& a ) const {
  90.         /// consistent with the definition of the copy constructor as a shallow
  91.         ///  constructor,.. this operator does not test the vertex pointers.
  92.         ///  Does not compare barcodes.
  93.         if ( a.momentum() != this->momentum() ) return false;
  94.         if ( a.generated_mass() != this->generated_mass() ) return false;
  95.         if ( a.pdg_id() != this->pdg_id() ) return false;
  96.         if ( a.status() != this->status() ) return false;
  97.         if ( a.m_flow != this->m_flow ) return false;
  98.         if ( a.polarization() != this->polarization() ) return false;
  99.         return true;
  100.     }
  101.  
  102.     bool GenParticle::operator!=( const GenParticle& a ) const {
  103.         return !( a == *this );
  104.     }
  105.  
  106.     void GenParticle::print( std::ostream& ostr ) const {
  107.         /// Dump this particle's full info to ostr, where by default
  108.         ///  particle.print(); will dump to cout.
  109.         ostr << "GenParticle: "
  110.              << barcode() << " ID:" << pdg_id()
  111.              << " (P,E)=" << momentum().px() << "," << momentum().py()
  112.              << "," << momentum().pz() << "," << momentum().e()
  113.              << " Stat:" << status();
  114.         if ( production_vertex() && production_vertex()->barcode()!=0 ) {
  115.             ostr << " PV:" << production_vertex()->barcode();
  116.         } else ostr << " PV:" << production_vertex();
  117.         if ( end_vertex() && end_vertex()->barcode()!=0 ) {
  118.             ostr << " EV:" << end_vertex()->barcode();
  119.         } else ostr << " EV:" << end_vertex();
  120.         ostr << " Pol:" << polarization() << " F:" << m_flow << std::endl;
  121.     }
  122.  
  123.     GenEvent* GenParticle::parent_event() const {
  124.         if ( production_vertex() ) return production_vertex()->parent_event();
  125.         if ( end_vertex() ) return end_vertex()->parent_event();
  126.         return 0;
  127.     }
  128.  
  129.     void GenParticle::set_production_vertex_( GenVertex* prodvertex )
  130.     {
  131.         GenEvent* its_orig_event = parent_event();
  132.         m_production_vertex = prodvertex;
  133.         GenEvent* its_new_event = parent_event();
  134.         // Next bit of logic ensures the barcode maps are kept up to date
  135.         //  in the GenEvent containers.
  136.         if ( its_orig_event != its_new_event ) {
  137.             if ( its_new_event ) its_new_event->set_barcode( this, barcode() );
  138.             if ( its_orig_event ) its_orig_event->remove_barcode( this );
  139.         }
  140.     }
  141.  
  142.     void GenParticle::set_end_vertex_( GenVertex* decayvertex )
  143.     {
  144.         GenEvent* its_orig_event = parent_event();
  145.         m_end_vertex = decayvertex;
  146.         GenEvent* its_new_event = parent_event();
  147.         if ( its_orig_event != its_new_event ) {
  148.             if ( its_new_event ) its_new_event->set_barcode( this, barcode() );
  149.             if ( its_orig_event ) its_orig_event->remove_barcode( this );
  150.         }
  151.     }  
  152.  
  153.     bool GenParticle::suggest_barcode( int the_bar_code )
  154.     {
  155.         /// allows a barcode to be suggested for this particle.
  156.         /// In general it is better to let the event pick the barcode for
  157.         /// you, which is automatic.
  158.         /// Returns TRUE if the suggested barcode has been accepted (i.e. the
  159.         ///  suggested barcode has not already been used in the event,
  160.         ///  and so it was used).
  161.         /// Returns FALSE if the suggested barcode was rejected, or if the
  162.         ///  particle is not yet part of an event, such that it is not yet
  163.         ///  possible to know if the suggested barcode will be accepted).
  164.         if ( the_bar_code <0 ) {
  165.             std::cerr << "GenParticle::suggest_barcode WARNING, particle bar "
  166.                       << "\n codes MUST be positive integers. Negative  "
  167.                       << "\n integers are reserved for vertices only. Your "
  168.                       << "\n suggestion has been rejected." << std::endl;
  169.             return false;
  170.         }
  171.         bool success = false;
  172.         if ( parent_event() ) {
  173.             success = parent_event()->set_barcode( this, the_bar_code );
  174.         } else { set_barcode_( the_bar_code ); }
  175.         return success;
  176.     }
  177.  
  178.     /////////////
  179.     // Static  //
  180.     /////////////
  181.     //unsigned int GenParticle::counter() { return s_counter; }
  182.     //unsigned int GenParticle::s_counter = 0U;
  183.  
  184.     /////////////
  185.     // Friends //
  186.     /////////////
  187.  
  188.     /// Dump this particle's full info to ostr
  189.     std::ostream& operator<<( std::ostream& ostr, const GenParticle& part ) {
  190.         // find the current stream state
  191.         std::ios_base::fmtflags orig = ostr.flags();
  192.         std::streamsize prec = ostr.precision();
  193.         ostr << " ";
  194.         ostr.width(9);
  195.         ostr << part.barcode();
  196.         ostr.width(9);
  197.         ostr << part.pdg_id() << " ";
  198.         ostr.width(9);
  199.         ostr.precision(2);
  200.         ostr.setf(std::ios::scientific, std::ios::floatfield);
  201.         ostr.setf(std::ios_base::showpos);
  202.         ostr << part.momentum().px() << ",";
  203.         ostr.width(9);
  204.         ostr << part.momentum().py() << ",";
  205.         ostr.width(9);
  206.         ostr << part.momentum().pz() << ",";
  207.         ostr.width(9);
  208.         ostr << part.momentum().e() << " ";
  209.         ostr.setf(std::ios::fmtflags(0), std::ios::floatfield);
  210.         ostr.unsetf(std::ios_base::showpos);
  211.         if ( part.end_vertex() && part.end_vertex()->barcode()!=0 ) {
  212.             ostr.width(3);
  213.             ostr << part.status() << " ";
  214.             ostr.width(9);
  215.             ostr << part.end_vertex()->barcode();
  216.         } else if ( !part.end_vertex() ) {
  217.             // There is no valid end_vertex
  218.             // For consistency across different compilers, do not print anything
  219.             ostr.width(3);
  220.             ostr << part.status();
  221.         } else {
  222.             // In this case the end_vertex does not have a unique
  223.             //   barcode assigned, so we choose instead to print its address
  224.             ostr.width(3);
  225.             ostr << part.status() << " ";
  226.             ostr.width(9);
  227.             ostr << (void*)part.end_vertex();
  228.         }
  229.         // restore the stream state
  230.         ostr.flags(orig);
  231.         ostr.precision(prec);
  232.         return ostr;
  233.     }
  234.  
  235.  
  236.     double  GenParticle::generated_mass() const {
  237.         return m_generated_mass;
  238.     }
  239.  
  240.     void   GenParticle::set_generated_mass( const double & m ) {
  241.         m_generated_mass = m;
  242.     }
  243.  
  244.     /// scale the momentum vector and generated mass
  245.     /// this method is only for use by GenEvent
  246.     void GenParticle::convert_momentum( const double & f ) {
  247.        m_momentum = FourVector( f*m_momentum.px(),
  248.                                 f*m_momentum.py(),
  249.                                 f*m_momentum.pz(),
  250.                                 f*m_momentum.e() );
  251.        if( m_generated_mass > 0. ) m_generated_mass = f*m_generated_mass;
  252.     }
  253.  
  254. } // HepMC
  255.  
  256.