00001 #include "GtBeamerTool.h"
00002
00003 #include "DetDesc/IDetectorElement.h"
00004 #include "DetDesc/IGeometryInfo.h"
00005
00006 #include "GaudiKernel/IRndmGenSvc.h"
00007 #include "GaudiKernel/IParticlePropertySvc.h"
00008 #include "GaudiKernel/ParticleProperty.h"
00009 #include "GaudiKernel/Vector3DTypes.h"
00010
00011 #include "HepMC/GenEvent.h"
00012 #include "HepMC/GenParticle.h"
00013 #include "HepMC/GenVertex.h"
00014
00015
00016 #include "CLHEP/Units/SystemOfUnits.h"
00017
00018 using namespace CLHEP;
00019
00020 GtBeamerTool::GtBeamerTool(const std::string& type,
00021 const std::string& name,
00022 const IInterface* parent)
00023 : GaudiTool(type,name,parent)
00024 , m_radius(0)
00025 , m_particlesPerEvent(1)
00026 , m_particleName("opticalphoton")
00027 , m_targetOffset(3,0)
00028 , m_sourceDirection(3,0)
00029 , m_distance(CLHEP::meter)
00030 , m_position(3,0)
00031 , m_direction(3,0)
00032 , m_pid(0)
00033 {
00034 declareInterface<IHepMCEventMutator>(this);
00035
00036 declareProperty("Radius",m_radius=CLHEP::meter,
00037 "Radius of source disk.");
00038
00039 declareProperty("ParticlesPerEvent",m_particlesPerEvent=1,
00040 "Number of particles per event");
00041
00042 declareProperty("ParticleName",m_particleName="opticalphoton",
00043 "Name of particle.");
00044
00045 declareProperty("Momentum",m_momentum=2.5*CLHEP::eV,
00046 "Momentum of particles in beam.");
00047
00048 declareProperty("TargetElement",m_targetElement="",
00049 "DetecorElement to aim at.");
00050
00051 declareProperty("TargetOffset",m_targetOffset,
00052 "Offset from target origin to aim for.");
00053
00054 declareProperty("SourceDirection",m_sourceDirection,
00055 "Direction from target to source.");
00056
00057 declareProperty("SourceDistance",m_distance,
00058 "Distance from target to source.");
00059
00060 }
00061
00062 GtBeamerTool::~GtBeamerTool()
00063 {
00064 }
00065
00066 StatusCode GtBeamerTool::initialize()
00067 {
00068
00069 IRndmGenSvc *rgs = 0;
00070 if (service("RndmGenSvc",rgs,true).isFailure()) {
00071 fatal() << "Failed to get random service" << endreq;
00072 return StatusCode::FAILURE;
00073 }
00074
00075 StatusCode sc = m_uni.initialize(rgs, Rndm::Flat(0,1));
00076 if (sc.isFailure()) {
00077 fatal() << "Failed to initialize uniform random numbers" << endreq;
00078 return StatusCode::FAILURE;
00079 }
00080
00081
00082 IParticlePropertySvc * ppSvc =
00083 svc<IParticlePropertySvc>("ParticlePropertySvc",true);
00084 ParticleProperty* particle = 0;
00085
00086
00087 double mass = 0;
00088 if (m_pid) {
00089 particle = ppSvc->findByStdHepID(m_pid);
00090 if (particle) {
00091 mass = particle->mass();
00092 m_particleName = particle->particle();
00093 }
00094 }
00095
00096 if (!particle) {
00097 particle = ppSvc->find(m_particleName);
00098 if (particle) {
00099 mass = particle->mass();
00100 m_pid = particle->pdgID();
00101 }
00102 }
00103
00104 if (!particle) {
00105 fatal() << "Failed to find particle named \""
00106 << m_particleName << "\" and with ID "
00107 << m_pid << endreq;
00108 return StatusCode::FAILURE;
00109 }
00110
00111
00112 if ("" == m_targetElement) {
00113 error() << "TargetElement not given" << endreq;
00114 return StatusCode::FAILURE;
00115 }
00116 IDetectorElement* targetDE =
00117 getDet<IDetectorElement>(m_targetElement);
00118
00119
00120
00121 Gaudi::XYZVector local_direction(m_sourceDirection[0],
00122 m_sourceDirection[1],
00123 m_sourceDirection[2]);
00124 Gaudi::XYZVector global_direction =
00125 targetDE->geometry()->toGlobal(local_direction);
00126 m_direction.setX(global_direction.x());
00127 m_direction.setY(global_direction.y());
00128 m_direction.setZ(global_direction.z());
00129 m_direction = m_direction.unit();
00130
00131
00132
00133 Gaudi::XYZPoint local_target(m_targetOffset[0],
00134 m_targetOffset[1],
00135 m_targetOffset[2]);
00136 Gaudi::XYZPoint global_target =
00137 targetDE->geometry()->toGlobal(local_target);
00138
00139 m_position.setX(global_target.x() - m_distance*global_direction.x());
00140 m_position.setY(global_target.y() - m_distance*global_direction.y());
00141 m_position.setZ(global_target.z() - m_distance*global_direction.z());
00142
00143
00144 m_fourmom = HepLorentzVector(m_momentum*m_direction,
00145 sqrt(m_momentum*m_momentum + mass*mass));
00146
00147
00148 return StatusCode::SUCCESS;
00149 }
00150
00151 StatusCode GtBeamerTool::finalize()
00152 {
00153 return StatusCode::SUCCESS;
00154 }
00155
00156 StatusCode GtBeamerTool::mutate(HepMC::GenEvent& event)
00157 {
00158 for (int ind=0; ind<m_particlesPerEvent; ++ind) {
00159
00160 Hep3Vector ortho = m_direction.orthogonal();
00161
00162 double angle = m_uni()*360*CLHEP::degree;
00163 ortho = ortho.rotate(angle,m_direction).unit();
00164
00165 double ran_radius = sqrt(m_uni()*m_radius*m_radius);
00166 ortho = ran_radius*ortho + m_position;
00167
00168 HepLorentzVector position(ortho,0);
00169 HepMC::GenVertex* vertex = new HepMC::GenVertex(position);
00170
00171 HepMC::GenParticle* part =
00172 new HepMC::GenParticle(m_fourmom,m_pid,1);
00173 double phi = m_uni()*360*CLHEP::degree;
00174 part->set_polarization(HepMC::Polarization(0.5*HepMC::HepMC_pi,phi));
00175 vertex->add_particle_out(part);
00176
00177 if (!event.vertices_size())
00178 event.set_signal_process_vertex(vertex);
00179 event.add_vertex(vertex);
00180 }
00181
00182 return StatusCode::SUCCESS;
00183 }