Belle II Software  release-05-02-19
ParticleGunModule.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2010 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Susanne Koblitz, Martin Ritter *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <generators/modules/ParticleGunModule.h>
12 #include <framework/gearbox/Unit.h>
13 #include <framework/datastore/StoreArray.h>
14 #include <boost/algorithm/string.hpp>
15 
16 using namespace std;
17 using namespace Belle2;
18 
19 //-----------------------------------------------------------------
20 // Register the Module
21 //-----------------------------------------------------------------
23 
24 //-----------------------------------------------------------------
25 // Implementation
26 //-----------------------------------------------------------------
27 
29 {
30  //Set module properties
31  setDescription(R"DOC(
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:
36 
37 fixed:
38  Fixed value, only one parameter has to be specified
39  ``[value]``
40 uniform:
41  Uniform between two given values
42  ``[min, max]``
43 uniformPt:
44  Generate flat transverse momentum pt
45  ``[min_pt, max_pt]``
46 uniformCos:
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]``
50 uniformLog:
51  Generate uniformly in the logarithm. Parameters are still the normal
52  values
53  ``[min, max]``
54 uniformLogPt:
55  Like uniformLog but for the transverse momentum.
56 normal:
57  Normal (Gaussian) distributed
58  ``[mean, width]``
59 normalPt:
60  Generate normal distributed transverse momentum pt
61  ``[mean_pt, width_pt]``
62 normalCos:
63  Generate normal distributed cosine of the angle
64  ``[mean, width]``
65 polyline:
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]``
69 polylinePt:
70  Like polyline but for pt, not p
71 polylineCos:
72  Like polyline, but for the cos(), not the absolute value
73 inversePt:
74  Generate uniformly in the inverse of pt, that is uniform in track
75  curvature
76  ``[min_pt, max_pt]``
77 discrete:
78  Discrete Spectrum given as a list of weights and values (useful for
79  radioactive sources)
80  ``[weight1, value1, weight2, value2, ...]``
81 discretePt:
82  same as above but for transverse momentum
83 )DOC");
84  setPropertyFlags(c_Input);
85 
86  //Set default values for parameters
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};
95 
96  //Parameter definition
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);
158 }
159 
160 ParticleGun::EDistribution ParticleGunModule::convertDistribution(std::string name)
161 {
162  boost::to_lower(name);
163  boost::trim(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;
181 }
182 
183 void ParticleGunModule::initialize()
184 {
185  //Initialize MCParticle collection
186  StoreArray<MCParticle> mcparticle;
187  mcparticle.registerInDataStore();
188 
189  //Convert string representations to distribution values
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);
199  }
200  if (getParam<std::string>("yVertexGeneration").isSetInSteering()) {
201  m_parameters.yVertexDist = convertDistribution(m_yVertexDist);
202  }
203  if (getParam<std::string>("zVertexGeneration").isSetInSteering()) {
204  m_parameters.zVertexDist = convertDistribution(m_zVertexDist);
205  }
206 
207  //Convert degree to radian
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;
211  }
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;
215  }
216 
217  //Assign parameters
218  m_particleGun.setParameters(m_parameters);
219 }
220 
221 void ParticleGunModule::event()
222 {
223  try {
224  m_particleGraph.clear();
225  m_particleGun.generateEvent(m_particleGraph);
226  m_particleGraph.generateList();
227  } catch (runtime_error& e) {
228  B2ERROR(e.what());
229  }
230 }
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::ParticleGunModule
The ParticleGun module.
Definition: ParticleGunModule.h:41
Belle2::Module
Base class for Modules.
Definition: Module.h:74
Belle2::ProcType::c_Input
@ c_Input
Input Process.
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::ParticleGun::EDistribution
EDistribution
enum containing all known distributions available for generation of values
Definition: ParticleGun.h:39
Belle2::StoreArray< MCParticle >
Belle2::ParticleGun
Class to generate tracks in the particle gun and store them in a MCParticle graph.
Definition: ParticleGun.h:36