11 #include <generators/modules/ParticleGunModule.h>
12 #include <framework/gearbox/Unit.h>
13 #include <framework/datastore/StoreArray.h>
14 #include <boost/algorithm/string.hpp>
32 Particle gun to generate simple tracks.
33 This module allows to generate simple events where all tracks have the same
34 momentum, angular and vertex distributions. Several distributions are
35 available for momentum, phi, theta and vertex position generation:
38 Fixed value, only one parameter has to be specified
41 Uniform between two given values
44 Generate flat transverse momentum pt
47 Generate uniformly in the cosine, e.g. flat in cos(theta). Parameters are
48 still the minimum and maximum angle (**not the cosine of the angle**)
49 ``[min_theta, max_theta]``
51 Generate uniformly in the logarithm. Parameters are still the normal
55 Like uniformLog but for the transverse momentum.
57 Normal (Gaussian) distributed
60 Generate normal distributed transverse momentum pt
61 ``[mean_pt, width_pt]``
63 Generate normal distributed cosine of the angle
66 Generate according to a pdf given as polyline, first the sorted x
67 coordinates and then the non-negative y coordinates
68 ``[x1, x2, x3, ... xn, y1, y2, y3, ..., yn]``
70 Like polyline but for pt, not p
72 Like polyline, but for the cos(), not the absolute value
74 Generate uniformly in the inverse of pt, that is uniform in track
78 Discrete Spectrum given as a list of weights and values (useful for
80 ``[weight1, value1, weight2, value2, ...]``
82 same as above but for transverse momentum
87 m_parameters.pdgCodes = { -11, 11};
88 m_parameters.momentumParams = {0.05, 3.0};
89 m_parameters.phiParams = {0.0, 360.0};
90 m_parameters.thetaParams = {17.0, 150.0};
91 m_parameters.xVertexParams = {0.0, 10 * Unit::um};
92 m_parameters.yVertexParams = {0.0, 59 * Unit::nm};
93 m_parameters.zVertexParams = {0.0, 190 * Unit::um};
94 m_parameters.timeParams = {0.0 * Unit::ns};
97 addParam(
"nTracks", m_parameters.nTracks,
98 "The number of tracks to be generated per event. If <=0, one particle will "
99 "be created for each entry in 'pdgCodes'. Otherwise N particles will be "
100 "created and the Particle ID for each particle will be picked randomly "
101 "from 'pdgCodes'", 1.0);
102 addParam(
"pdgCodes", m_parameters.pdgCodes,
103 "PDG codes for generated particles", m_parameters.pdgCodes);
104 addParam(
"varyNTracks", m_parameters.varyNumberOfTracks,
105 "If true, the number of tracks per event is varied using a Poisson "
106 "distribution. Only used if 'nTracks'>0",
false);
107 addParam(
"momentumGeneration", m_momentumDist,
108 "Momentum distribution: one of fixed, uniform, normal, polyline, uniformLog, uniformPt, "
109 "normalPt, inversePt, polylinePt, uniformLogPt or discrete",
string(
"uniform"));
110 addParam(
"phiGeneration", m_phiDist,
111 "Phi distribution: one of fixed, uniform, normal, normalCos, polyline, uniformCos, "
112 "polylineCos or discrete",
string(
"uniform"));
113 addParam(
"thetaGeneration", m_thetaDist,
114 "Theta distribution: one of fixed, uniform, normal, normalCos, polyline, uniformCos, "
115 "polylineCos or discrete",
string(
"uniform"));
116 addParam(
"timeGeneration", m_timeDist,
117 "Time distribution: one of fixed, uniform, normal, normalCos, polyline, uniformCos, "
118 "polylineCos or discrete",
string(
"fixed"));
119 addParam(
"vertexGeneration", m_vertexDist,
120 "Vertex (x,y,z) distribution: one of fixed, uniform, normal, polyline or "
121 "discrete",
string(
"fixed"));
122 addParam(
"xVertexGeneration", m_xVertexDist,
123 "X vertex distribution: same options as 'vertexGeneration'. If this parameter "
124 "is not specified the value from 'vertexGeneration' is used",
string(
""));
125 addParam(
"yVertexGeneration", m_yVertexDist,
126 "Y vertex distribution: same options as 'vertexGeneration'. If this parameter "
127 "is not specified the value from 'vertexGeneration' is used",
string(
""));
128 addParam(
"zVertexGeneration", m_zVertexDist,
129 "Z vertex distribution: same options as 'vertexGeneration'. If this parameter "
130 "is not specified the value from 'vertexGeneration' is used",
string(
""));
131 addParam(
"independentVertices", m_parameters.independentVertices,
132 "If false, all tracks of one event will start from the same vertex, "
133 "otherwise a new vertex is generated for every particle",
false);
134 addParam(
"fixedMomentumPerEvent", m_parameters.fixedMomentumPerEvent,
135 "generates particle momentum according to the specified "
136 "distribution and assigns this momentum to all particles generated "
137 "for one event",
false);
138 addParam(
"momentumParams", m_parameters.momentumParams,
139 "Parameters for the momentum generation. Meaning of the parameters "
140 "depends on the chosen distribution", m_parameters.momentumParams);
141 addParam(
"phiParams", m_parameters.phiParams,
142 "Parameters for the phi generation in degrees. Meaning of the parameters "
143 "depends on the chosen distribution", m_parameters.phiParams);
144 addParam(
"thetaParams", m_parameters.thetaParams,
145 "Parameters for the theta generation in degrees. Meaning of the parameters "
146 "depends on the chosen distribution", m_parameters.thetaParams);
147 addParam(
"xVertexParams", m_parameters.xVertexParams,
148 "Parameters for the x vertex generation. Meaning of the parameters "
149 "depends on the chosen distribution", m_parameters.xVertexParams);
150 addParam(
"yVertexParams", m_parameters.yVertexParams,
151 "Parameters for the y vertex generation. Meaning of the parameters "
152 "depends on the chosen distribution", m_parameters.yVertexParams);
153 addParam(
"zVertexParams", m_parameters.zVertexParams,
154 "Parameters for the z vertex generation. Meaning of the parameters "
155 "depends on the chosen distribution", m_parameters.zVertexParams);
156 addParam(
"timeParams", m_parameters.timeParams,
157 "Time offset", m_parameters.timeParams);
162 boost::to_lower(name);
164 if (name ==
"fixed")
return ParticleGun::c_fixedValue;
165 if (name ==
"uniform")
return ParticleGun::c_uniformDistribution;
166 if (name ==
"uniformpt")
return ParticleGun::c_uniformPtDistribution;
167 if (name ==
"uniformcos")
return ParticleGun::c_uniformCosDistribution;
168 if (name ==
"uniformlog")
return ParticleGun::c_uniformLogDistribution;
169 if (name ==
"uniformlogpt")
return ParticleGun::c_uniformLogPtDistribution;
170 if (name ==
"normal")
return ParticleGun::c_normalDistribution;
171 if (name ==
"normalpt")
return ParticleGun::c_normalPtDistribution;
172 if (name ==
"normalcos")
return ParticleGun::c_normalCosDistribution;
173 if (name ==
"discrete")
return ParticleGun::c_discreteSpectrum;
174 if (name ==
"discretept")
return ParticleGun::c_discretePtSpectrum;
175 if (name ==
"inversept")
return ParticleGun::c_inversePtDistribution;
176 if (name ==
"polyline")
return ParticleGun::c_polylineDistribution;
177 if (name ==
"polylinept")
return ParticleGun::c_polylinePtDistribution;
178 if (name ==
"polylinecos")
return ParticleGun::c_polylineCosDistribution;
179 B2ERROR(
"Unknown distribution '" << name <<
"', using fixed");
180 return ParticleGun::c_fixedValue;
183 void ParticleGunModule::initialize()
187 mcparticle.registerInDataStore();
190 m_parameters.momentumDist = convertDistribution(m_momentumDist);
191 m_parameters.phiDist = convertDistribution(m_phiDist);
192 m_parameters.thetaDist = convertDistribution(m_thetaDist);
193 m_parameters.xVertexDist = convertDistribution(m_vertexDist);
194 m_parameters.yVertexDist = convertDistribution(m_vertexDist);
195 m_parameters.zVertexDist = convertDistribution(m_vertexDist);
196 m_parameters.timeDist = convertDistribution(m_timeDist);
197 if (getParam<std::string>(
"xVertexGeneration").isSetInSteering()) {
198 m_parameters.xVertexDist = convertDistribution(m_xVertexDist);
200 if (getParam<std::string>(
"yVertexGeneration").isSetInSteering()) {
201 m_parameters.yVertexDist = convertDistribution(m_yVertexDist);
203 if (getParam<std::string>(
"zVertexGeneration").isSetInSteering()) {
204 m_parameters.zVertexDist = convertDistribution(m_zVertexDist);
208 if (m_parameters.thetaDist != ParticleGun::c_polylineCosDistribution &&
209 m_parameters.thetaDist != ParticleGun::c_normalCosDistribution) {
210 for (
double& angle : m_parameters.thetaParams) angle *= Unit::deg;
212 if (m_parameters.phiDist != ParticleGun::c_polylineCosDistribution &&
213 m_parameters.phiDist != ParticleGun::c_normalCosDistribution) {
214 for (
double& angle : m_parameters.phiParams) angle *= Unit::deg;
218 m_particleGun.setParameters(m_parameters);
221 void ParticleGunModule::event()
224 m_particleGraph.clear();
225 m_particleGun.generateEvent(m_particleGraph);
226 m_particleGraph.generateList();
227 }
catch (runtime_error& e) {