00001
00010 #include "HepMCtoG4.h"
00011 #include "G4DataHelpers/G4DhPrimaryVertexInformation.h"
00012 #include "G4DataHelpers/G4DhPrimaryParticleInformation.h"
00013
00014 #include "HepMC/GenParticle.h"
00015 #include "HepMC/GenEvent.h"
00016 #include "HepMC/GenVertex.h"
00017
00018 #include "GaudiAlg/GaudiCommon.h"
00019 #include "GaudiKernel/ParticleProperty.h"
00020
00021
00022 #include "G4PrimaryParticle.hh"
00023 #include "G4PrimaryVertex.hh"
00024 #include "G4OpticalPhoton.hh"
00025
00026 #include "CLHEP/Vector/LorentzVector.h"
00027 #include "CLHEP/Geometry/Normal3D.h"
00028
00029
00030
00031 HepMCtoG4::HepMCtoG4(const std::string& type,
00032 const std::string& name,
00033 const IInterface* parent)
00034 : GaudiTool(type,name,parent)
00035 , m_pps(0)
00036 {
00037 declareInterface<IHepMCtoG4>(this);
00038
00039 declareProperty("ZeroTime",m_zeroTime = true,
00040 "Set true and all times will be reset so the signal vertex is at t=0.");
00041 }
00042
00043 HepMCtoG4::~HepMCtoG4()
00044 {
00045 }
00046
00047
00048 StatusCode HepMCtoG4::initialize()
00049 {
00050 m_pps = svc<IParticlePropertySvc>( "ParticlePropertySvc", true ) ;
00051 return StatusCode::SUCCESS;
00052 }
00053
00054 StatusCode HepMCtoG4::finalize()
00055 {
00056 return StatusCode::SUCCESS;
00057 }
00058
00059
00060
00061
00062
00063
00064 G4PrimaryParticle*
00065 HepMCtoG4::makeG4particle(const HepMC::GenParticle& part, const HepMC::GenEvent* event, const HepMC::GenVertex* vertex)
00066 {
00067 HepMC::FourVector p = part.momentum();
00068
00069 G4PrimaryParticle* g4part = 0;
00070
00071 double m, cm ;
00072 if (part.pdg_id() == 20022 ) {
00073 g4part = new G4PrimaryParticle(G4OpticalPhoton::Definition(),
00074 p.px(),p.py(),p.pz());
00075 m = 0. ;
00076 }
00077 else {
00078 g4part = new G4PrimaryParticle(part.pdg_id(),p.px(),p.py(),p.pz());
00079 m = cm = sqrt(fabs( p.t()*p.t() - (p.x()*p.x() + p.y()*p.y() + p.z()*p.z()) ));
00080
00081 ParticleProperty* ppp = m_pps->findByStdHepID( part.pdg_id() );
00082 if ( ppp )
00083 {
00084 m = ppp->mass();
00085 double r = 0.;
00086 if ( m > 0 ) { r = std::abs(cm-m)/m; }
00087 if ( r > 0.001 || std::abs(cm-m) > 0.01*MeV )
00088 {
00089 warning() << "calculated mass = " << cm
00090 << " differs from IParticlePropertySvc mass " << m
00091 << " for pdg_id " << part.pdg_id()
00092 << ". Using IParticlePropertySvc mass. " << endreq;
00093 }
00094 }
00095 else
00096 {
00097 if ( p.t() < 0.01*MeV && std::abs(part.pdg_id()) > 1000000000 )
00098 {
00099 debug() << "As expected, there is no IParticlePropertySvc mass for pdg_id "
00100 << part.pdg_id() << " which is a zero-energy, recoil nucleus created by GenDecay. Use calculated mass " << m
00101 << " from particle energy " << p.t() << " momentum " << sqrt(p.x()*p.x() + p.y()*p.y() + p.z()*p.z())
00102 << endreq;
00103 }
00104 else
00105 {
00106 warning() << "cannot find IParticlePropertySvc mass for pdg_id "
00107 << part.pdg_id() << " and status " << part.status() << " . Using calculated mass " << m
00108 << " from particle energy " << p.t() << " momentum " << sqrt(p.x()*p.x() + p.y()*p.y() + p.z()*p.z())
00109 << endreq;
00110 }
00111 }
00112
00113 }
00114 g4part->SetMass(m);
00115 HepMC::ThreeVector pol = part.polarization().normal3d();
00116 g4part->SetPolarization(pol.x(),pol.y(),pol.z());
00117
00118 g4part->SetUserInformation(new G4DhPrimaryParticleInformation(event,vertex,&part));
00119 return g4part;
00120 }
00121
00122 StatusCode HepMCtoG4::convert(const HepMC::GenEvent& input,
00123 std::vector<G4PrimaryVertex*>& output)
00124 {
00125
00126
00127 bool hasEventWeight = false;
00128 double eventWeight = 1.0;
00129
00130
00131 if( input.weights().size() == 1 ){
00132 hasEventWeight = true;
00133 eventWeight *= input.weights().front();
00134 }
00135
00136
00137 HepMC::GenEvent::vertex_const_iterator
00138 iVtx = input.vertices_begin(),
00139 doneVtx = input.vertices_end();
00140 for (; doneVtx != iVtx; ++iVtx) {
00141
00142 G4PrimaryVertex* g4vtx = new G4PrimaryVertex;
00143 bool first_time = true;
00144
00145
00146 bool hasVertexWeight = false;
00147 double vertexWeight = 1.0;
00148
00149
00150
00151 if( (*iVtx)->weights().size() == 1 ){
00152 hasVertexWeight = true;
00153 vertexWeight *= (*iVtx)->weights().front();
00154 }
00155 if( hasEventWeight || hasVertexWeight ){
00156 g4vtx->SetWeight( eventWeight*vertexWeight );
00157 }
00158
00159
00160 HepMC::GenVertex::particles_out_const_iterator
00161 iPart = (*iVtx)->particles_out_const_begin(),
00162 donePart = (*iVtx)->particles_out_const_end();
00163 for (; donePart != iPart; ++iPart) {
00164
00165
00166 if ((*iPart)->status() != 1) continue;
00167
00168 if (first_time) {
00169 first_time = false;
00170 HepMC::FourVector v = (*iPart)->production_vertex()->position();
00171 g4vtx->SetPosition(v.x(),v.y(),v.z());
00172 if (m_zeroTime)
00173 g4vtx->SetT0(0.0);
00174 else
00175 g4vtx->SetT0(v.t());
00176 g4vtx->SetUserInformation(new G4DhPrimaryVertexInformation(&input,*iVtx));
00177 }
00178 g4vtx->SetPrimary(makeG4particle(*(*iPart),&input,*iVtx));
00179 }
00180
00181 if (!g4vtx->GetNumberOfParticle()) {
00182 delete g4vtx;
00183 continue;
00184 }
00185
00186 output.push_back(g4vtx);
00187 }
00188 return StatusCode::SUCCESS;
00189 }
00190