BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
SingleParticleGun.cxx
Go to the documentation of this file.
1// ------------------------------------------
2// File: SingleParticleGun/SingleParticleGun.cpp
3// Description:
4// Allows the user to "shoot" Monte Carlo particles and store the result
5// in the Transient Store.
6// -------------------------------------------------------------
7
8#include "SingleParticleGun.h"
9#include "GeneratorModule/GeneratorName.h"
10
11// Framework Related Headers:-
12#include "GaudiKernel/MsgStream.h"
13
14// Other classes used by this class:-
15#include "CLHEP/Units/PhysicalConstants.h"
16#include <math.h>
17
18#include "BesRndmGenSvc/IBesRndmGenSvc.h"
19#include "CLHEP/Random/RandFlat.h"
20#include "CLHEP/Random/RandGauss.h"
21
22#include "HepPDT/ParticleData.hh"
23#include "HepPDT/ParticleDataTable.hh"
24#ifndef ENABLE_BACKWARDS_COMPATIBILITY
25typedef double HepDouble;
26#endif
27using HepMC::GenParticle;
28using HepMC::GenVertex;
29
31// File scope declarations:-
32
33//--------------------------------------------------------------------------
34SingleParticleGun::SingleParticleGun( const std::string& name, ISvcLocator* pSvcLocator )
35 : GenModule( name, pSvcLocator ) {
36 //--------------------------------------------------------------------------
37 declareProperty( "Mode", m_Emode = SingleEnergyMode::PtMode );
38 // in PtMode user specifies Pt theta and phi
39 // in EMode user specifies E, theta and phi
40 // defaults are set so that something is always generated
41
42 declareProperty( "Pt", m_requestedPt = 5.0 );
43 declareProperty( "E", m_requestedE = 5.0 );
44 declareProperty( "Phi", m_requestedPhi = 0.0 );
45 declareProperty( "Theta", m_requestedTheta = 3.14 / 4.0 );
46
47 declareProperty( "VertexX", m_requestedX = 0.0 );
48 declareProperty( "VertexY", m_requestedY = 0.0 );
49 declareProperty( "VertexZ", m_requestedZ = 0.0 );
50 declareProperty( "Time", m_requestedT = 0.0 );
51
52 declareProperty( "MinPt", m_minPt = 1. );
53 declareProperty( "MinE", m_minE = 1. );
54 declareProperty( "MinTheta", m_minTheta = 0. );
55 declareProperty( "MinPhi", m_minPhi = 0. );
56
57 declareProperty( "MaxPt", m_maxPt = 100. );
58 declareProperty( "MaxE", m_maxE = 100. );
59 declareProperty( "MaxTheta", m_maxTheta = CLHEP::pi );
60 declareProperty( "MaxPhi", m_maxPhi = CLHEP::twopi );
61
62 declareProperty( "SigmaPt", m_sigmaPt = 0.1 );
63 declareProperty( "SigmaE", m_sigmaE = 0.1 );
64
65 declareProperty( "SigmaTheta", m_sigmaTheta = 0.1 );
66 declareProperty( "SigmaPhi", m_sigmaPhi = 0.1 );
67
68 declareProperty( "ModePt", m_PtGenMode = SingleParticleGunGenMode::FixedMode );
69 declareProperty( "ModeE", m_EGenMode = SingleParticleGunGenMode::FixedMode );
70 declareProperty( "ModeTheta", m_ThetaGenMode = SingleParticleGunGenMode::FixedMode );
71
72 declareProperty( "ModePhi", m_PhiGenMode = SingleParticleGunGenMode::FixedMode );
73 // specifies type of distribution
74
75 declareProperty( "PdgCode", m_pdgCode = 211 );
76}
77
78//--------------------------------------------------------------------------
80 //--------------------------------------------------------------------------
81 // if(m_pFlatGenerator) delete m_pFlatGenerator;
82 // if(m_pGaussGenerator) delete m_pGaussGenerator;
83}
84
85//---------------------------------------------------------------------------
87 //---------------------------------------------------------------------------
88
89 // Create the flat and gaussian generators
90 //
91
92 MsgStream log( msgSvc(), name() );
93
94 static const bool CREATEIFNOTTHERE( true );
95 StatusCode RndmStatus = service( "BesRndmGenSvc", p_BesRndmGenSvc, CREATEIFNOTTHERE );
96 if ( !RndmStatus.isSuccess() || 0 == p_BesRndmGenSvc )
97 {
98 log << MSG::ERROR << " Could not initialize Random Number Service" << endmsg;
99 return RndmStatus;
100 }
101
102 // Get the mass of the particle to be generated
103 //
104 const HepPDT::ParticleData* particle =
105 m_particleTable->particle( HepPDT::ParticleID( abs( m_pdgCode ) ) );
106 // Some particle can't be found in HepPDT, such as geantino
107 m_mass = particle ? particle->mass().value() : 0;
108
109 //
110 // Make sure the parameters are in a sensible range...
111 //
112 switch ( m_Emode )
113 {
115 if ( !m_PtGenMode && ( m_minPt > m_requestedPt || m_maxPt < m_requestedPt ) ||
116 m_maxPt < m_minPt )
117 {
118 log << MSG::ERROR << " Pt min and max out of range. \n"
119 << " Will set Pt mode to Fixed!!!" << endmsg;
121 }
122 if ( !m_ThetaGenMode &&
123 ( m_minTheta > m_requestedTheta || m_maxTheta < m_requestedTheta ) ||
124 m_maxTheta < m_minTheta )
125 {
126 log << MSG::ERROR << " Theta min and max out of range. \n"
127 << " Will set Theta mode to Fixed!!!" << endmsg;
129 }
130 if ( !m_PhiGenMode && ( m_minPhi > m_requestedPhi || m_maxPhi < m_requestedPhi ) ||
131 m_maxPhi < m_minPhi )
132 {
133 log << MSG::ERROR << " Phi min and max out of range. \n"
134 << " Will set Phi mode to Fixed!!!" << endmsg;
136 }
137 break;
139 if ( !m_EGenMode && ( m_minE > m_requestedE || m_maxE < m_requestedE ) || m_maxE < m_minE )
140 {
141 log << MSG::ERROR << " E min and max out of range. \n"
142 << " Will set E mode to Fixed!!!" << endmsg;
144 }
145 if ( !m_ThetaGenMode &&
146 ( m_minTheta > m_requestedTheta || m_maxTheta < m_requestedTheta ) ||
147 m_maxTheta < m_minTheta )
148 {
149 log << MSG::ERROR << " Theta min and max out of range. \n"
150 << " Will set Theta mode to Fixed!!!" << endmsg;
152 }
153 if ( !m_PhiGenMode && ( m_minPhi > m_requestedPhi || m_maxPhi < m_requestedPhi ) ||
154 m_maxPhi < m_minPhi )
155 {
156 log << MSG::ERROR << " Phi min and max out of range. \n"
157 << " Will set Phi mode to Fixed!!!" << endmsg;
159 }
160 break;
161 }
162 m_events = 0;
163 return StatusCode::SUCCESS;
164}
165
166//---------------------------------------------------------------------------
168 //---------------------------------------------------------------------------
169
170 ++m_events;
171 // Save the random number seeds in the event
172 CLHEP::HepRandomEngine* engine = p_BesRndmGenSvc->GetEngine( "SINGLE" );
173 const long* s = engine->getSeeds();
174 m_seeds.clear();
175 m_seeds.push_back( s[0] );
176 m_seeds.push_back( s[1] );
177
178 // Generate values for pt, theta and phi
179 //
180 double pt, phi, theta, E, px, py, pz, p;
181 switch ( m_Emode )
182 {
183
185 pt = generateValue( m_PtGenMode, m_requestedPt, m_sigmaPt, m_minPt, m_maxPt );
186 theta = generateValue( m_ThetaGenMode, m_requestedTheta, m_sigmaTheta, m_minTheta,
187 m_maxTheta );
188 phi = generateValue( m_PhiGenMode, m_requestedPhi, m_sigmaPhi, m_minPhi, m_maxPhi );
189
190 // Transform to x,y,z coordinates
191 //
192 px = pt * cos( phi );
193 py = pt * sin( phi );
194 pz = pt / tan( theta );
195 m_fourMom.setVectM( CLHEP::Hep3Vector( px, py, pz ), m_mass );
196 m_fourPos.set( m_requestedX, m_requestedY, m_requestedZ, m_requestedT );
197 return StatusCode::SUCCESS;
198
200 E = generateValue( m_EGenMode, m_requestedE, m_sigmaE, m_minE, m_maxE );
201 theta = generateValue( m_ThetaGenMode, m_requestedTheta, m_sigmaTheta, m_minTheta,
202 m_maxTheta );
203 phi = generateValue( m_PhiGenMode, m_requestedPhi, m_sigmaPhi, m_minPhi, m_maxPhi );
204
205 // Transform to x,y,z coordinates
206 //
207 if ( E * E - m_mass * m_mass < 0. )
208 {
209 MsgStream log( msgSvc(), name() );
210 log << MSG::ERROR
211 << "You have Generated a Tachyon!! Increase energy or change particle ID" << endmsg;
212 return StatusCode::FAILURE;
213 }
214 p = sqrt( E * E - m_mass * m_mass );
215 px = p * sin( theta ) * cos( phi );
216 py = p * sin( theta ) * sin( phi );
217 pz = p * cos( theta );
218
219 m_fourMom.setVectM( CLHEP::Hep3Vector( px, py, pz ), m_mass );
220 m_fourPos.set( m_requestedX, m_requestedY, m_requestedZ, m_requestedT );
221 return StatusCode::SUCCESS;
222 }
223 return StatusCode::SUCCESS;
224}
225
226//---------------------------------------------------------------------------
228 //---------------------------------------------------------------------------
229 return StatusCode::SUCCESS;
230}
231
232//---------------------------------------------------------------------------
233StatusCode SingleParticleGun::fillEvt( GenEvent* evt ) {
234 //---------------------------------------------------------------------------
235 // Note: The vertex is owned by the event so the event is responsible
236 // for deleting its memory
237 evt->set_event_number( m_events ); // Set the event number
238 GenVertex* v1 = new GenVertex( m_fourPos );
239
240 std::cout << " SingleParticleGun::fillEvt --> " << std::endl;
241 std::cout << " Event number:: " << m_events << std::endl;
242 std::cout << " vertex.x = " << m_fourPos.x() << " vertex.y = " << m_fourPos.y()
243 << " vertex.z = " << m_fourPos.z() << " vertex.t = " << m_fourPos.t() << std::endl;
244
245 std::cout << " momentum.x = " << m_fourMom.x() << " momentum.y = " << m_fourMom.y()
246 << " momentum.z = " << m_fourMom.z() << " momentum.t = " << m_fourMom.t()
247 << std::endl;
248
249 evt->add_vertex( v1 );
250
251 v1->add_particle_out( new GenParticle( m_fourMom, m_pdgCode, 1 ) );
252
253 std::cout << " particles_size = " << evt->particles_size()
254 << " vertices_size = " << evt->vertices_size() << std::endl;
255
256 evt->set_signal_process_id( SINGLE );
257 evt->set_random_states( m_seeds );
258
259 return StatusCode::SUCCESS;
260}
261
262//---------------------------------------------------------------------------
263double SingleParticleGun::generateValue( int mode, double val, double sigma, double min,
264 double max ) {
265 //---------------------------------------------------------------------------
266 double tmp;
267 int i = 0;
268 CLHEP::HepRandomEngine* engine = p_BesRndmGenSvc->GetEngine( "SINGLE" );
269 const int maxtries = 100;
270 switch ( mode )
271 {
274 tmp = max + 1.0;
275 i = 0;
276 do {
277 // tmp = m_pGaussGenerator->fire((HepDouble) val,(HepDouble) sigma);
278 tmp = CLHEP::RandGauss::shoot( engine, (HepDouble)val, (HepDouble)sigma );
279 i++;
280 } while ( ( tmp < min ) || ( tmp > max ) && ( i < maxtries ) );
281 if ( i > maxtries )
282 {
283 MsgStream log( msgSvc(), name() );
284 log << MSG::ERROR << "Cant generate value in range (min, max) " << val << "\t" << min
285 << "\t" << max << endmsg;
286 }
287 return tmp;
289 // tmp = m_pFlatGenerator->fire((HepDouble) min,(HepDouble) max);
290 tmp = CLHEP::RandFlat::shoot( engine, (HepDouble)min, (HepDouble)max );
291 return tmp;
292 default:
293 MsgStream log( msgSvc(), name() );
294 log << MSG::ERROR << "Unknown Generation Mode" << endmsg;
295 return 0.;
296 }
297}
DECLARE_COMPONENT(BesBdkRc)
#define min(a, b)
#define max(a, b)
double HepDouble
Definition EvtVub.cc:37
XmlRpcServer s
IMessageSvc * msgSvc()
HepPDT::ParticleDataTable * m_particleTable
GenModule(const std::string &name, ISvcLocator *pSvcLocator)
Definition GenModule.cxx:37
virtual CLHEP::HepRandomEngine * GetEngine(const std::string &StreamName)=0
Interface to the CLHEP engine.
virtual StatusCode fillEvt(GenEvent *evt)
virtual StatusCode genFinalize()
virtual StatusCode genInitialize()
virtual StatusCode callGenerator()
SingleParticleGun(const std::string &name, ISvcLocator *pSvcLocator)