Belle II Software  release-06-00-14
ParticleGunModule.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <generators/modules/ParticleGunModule.h>
10 #include <framework/gearbox/Unit.h>
11 #include <framework/datastore/StoreArray.h>
12 #include <boost/algorithm/string.hpp>
13 
14 using namespace std;
15 using namespace Belle2;
16 
17 //-----------------------------------------------------------------
18 // Register the Module
19 //-----------------------------------------------------------------
21 
22 //-----------------------------------------------------------------
23 // Implementation
24 //-----------------------------------------------------------------
25 
27 {
28  //Set module properties
29  setDescription(R"DOC(
30 Particle gun to generate simple tracks.
31 This module allows to generate simple events where all tracks have the same
32 momentum, angular and vertex distributions. Several distributions are
33 available for momentum, phi, theta and vertex position generation:
34 
35 fixed:
36  Fixed value, only one parameter has to be specified
37  ``[value]``
38 uniform:
39  Uniform between two given values
40  ``[min, max]``
41 uniformPt:
42  Generate flat transverse momentum pt
43  ``[min_pt, max_pt]``
44 uniformCos:
45  Generate uniformly in the cosine, e.g. flat in cos(theta). Parameters are
46  still the minimum and maximum angle (**not the cosine of the angle**)
47  ``[min_theta, max_theta]``
48 uniformLog:
49  Generate uniformly in the logarithm. Parameters are still the normal
50  values
51  ``[min, max]``
52 uniformLogPt:
53  Like uniformLog but for the transverse momentum.
54 normal:
55  Normal (Gaussian) distributed
56  ``[mean, width]``
57 normalPt:
58  Generate normal distributed transverse momentum pt
59  ``[mean_pt, width_pt]``
60 normalCos:
61  Generate normal distributed cosine of the angle
62  ``[mean, width]``
63 polyline:
64  Generate according to a pdf given as polyline, first the sorted x
65  coordinates and then the non-negative y coordinates
66  ``[x1, x2, x3, ... xn, y1, y2, y3, ..., yn]``
67 polylinePt:
68  Like polyline but for pt, not p
69 polylineCos:
70  Like polyline, but for the cos(), not the absolute value
71 inversePt:
72  Generate uniformly in the inverse of pt, that is uniform in track
73  curvature
74  ``[min_pt, max_pt]``
75 discrete:
76  Discrete Spectrum given as a list of weights and values (useful for
77  radioactive sources)
78  ``[weight1, value1, weight2, value2, ...]``
79 discretePt:
80  same as above but for transverse momentum
81 )DOC");
82  setPropertyFlags(c_Input);
83 
84  //Set default values for parameters
85  m_parameters.pdgCodes = { -11, 11};
86  m_parameters.momentumParams = {0.05, 3.0};
87  m_parameters.phiParams = {0.0, 360.0};
88  m_parameters.thetaParams = {17.0, 150.0};
89  m_parameters.xVertexParams = {0.0, 10 * Unit::um};
90  m_parameters.yVertexParams = {0.0, 59 * Unit::nm};
91  m_parameters.zVertexParams = {0.0, 190 * Unit::um};
92  m_parameters.timeParams = {0.0 * Unit::ns};
93 
94  //Parameter definition
95  addParam("nTracks", m_parameters.nTracks,
96  "The number of tracks to be generated per event. If <=0, one particle will "
97  "be created for each entry in 'pdgCodes'. Otherwise N particles will be "
98  "created and the Particle ID for each particle will be picked randomly "
99  "from 'pdgCodes'", 1.0);
100  addParam("pdgCodes", m_parameters.pdgCodes,
101  "PDG codes for generated particles", m_parameters.pdgCodes);
102  addParam("varyNTracks", m_parameters.varyNumberOfTracks,
103  "If true, the number of tracks per event is varied using a Poisson "
104  "distribution. Only used if 'nTracks'>0", false);
105  addParam("momentumGeneration", m_momentumDist,
106  "Momentum distribution: one of fixed, uniform, normal, polyline, uniformLog, uniformPt, "
107  "normalPt, inversePt, polylinePt, uniformLogPt or discrete", string("uniform"));
108  addParam("phiGeneration", m_phiDist,
109  "Phi distribution: one of fixed, uniform, normal, normalCos, polyline, uniformCos, "
110  "polylineCos or discrete", string("uniform"));
111  addParam("thetaGeneration", m_thetaDist,
112  "Theta distribution: one of fixed, uniform, normal, normalCos, polyline, uniformCos, "
113  "polylineCos or discrete", string("uniform"));
114  addParam("timeGeneration", m_timeDist,
115  "Time distribution: one of fixed, uniform, normal, normalCos, polyline, uniformCos, "
116  "polylineCos or discrete", string("fixed"));
117  addParam("vertexGeneration", m_vertexDist,
118  "Vertex (x,y,z) distribution: one of fixed, uniform, normal, polyline or "
119  "discrete", string("fixed"));
120  addParam("xVertexGeneration", m_xVertexDist,
121  "X vertex distribution: same options as 'vertexGeneration'. If this parameter "
122  "is not specified the value from 'vertexGeneration' is used", string(""));
123  addParam("yVertexGeneration", m_yVertexDist,
124  "Y vertex distribution: same options as 'vertexGeneration'. If this parameter "
125  "is not specified the value from 'vertexGeneration' is used", string(""));
126  addParam("zVertexGeneration", m_zVertexDist,
127  "Z vertex distribution: same options as 'vertexGeneration'. If this parameter "
128  "is not specified the value from 'vertexGeneration' is used", string(""));
129  addParam("independentVertices", m_parameters.independentVertices,
130  "If false, all tracks of one event will start from the same vertex, "
131  "otherwise a new vertex is generated for every particle", false);
132  addParam("fixedMomentumPerEvent", m_parameters.fixedMomentumPerEvent,
133  "generates particle momentum according to the specified "
134  "distribution and assigns this momentum to all particles generated "
135  "for one event", false);
136  addParam("momentumParams", m_parameters.momentumParams,
137  "Parameters for the momentum generation. Meaning of the parameters "
138  "depends on the chosen distribution", m_parameters.momentumParams);
139  addParam("phiParams", m_parameters.phiParams,
140  "Parameters for the phi generation in degrees. Meaning of the parameters "
141  "depends on the chosen distribution", m_parameters.phiParams);
142  addParam("thetaParams", m_parameters.thetaParams,
143  "Parameters for the theta generation in degrees. Meaning of the parameters "
144  "depends on the chosen distribution", m_parameters.thetaParams);
145  addParam("xVertexParams", m_parameters.xVertexParams,
146  "Parameters for the x vertex generation. Meaning of the parameters "
147  "depends on the chosen distribution", m_parameters.xVertexParams);
148  addParam("yVertexParams", m_parameters.yVertexParams,
149  "Parameters for the y vertex generation. Meaning of the parameters "
150  "depends on the chosen distribution", m_parameters.yVertexParams);
151  addParam("zVertexParams", m_parameters.zVertexParams,
152  "Parameters for the z vertex generation. Meaning of the parameters "
153  "depends on the chosen distribution", m_parameters.zVertexParams);
154  addParam("timeParams", m_parameters.timeParams,
155  "Time offset", m_parameters.timeParams);
156 }
157 
158 ParticleGun::EDistribution ParticleGunModule::convertDistribution(std::string name)
159 {
160  boost::to_lower(name);
161  boost::trim(name);
162  if (name == "fixed") return ParticleGun::c_fixedValue;
163  if (name == "uniform") return ParticleGun::c_uniformDistribution;
164  if (name == "uniformpt") return ParticleGun::c_uniformPtDistribution;
165  if (name == "uniformcos") return ParticleGun::c_uniformCosDistribution;
166  if (name == "uniformlog") return ParticleGun::c_uniformLogDistribution;
167  if (name == "uniformlogpt") return ParticleGun::c_uniformLogPtDistribution;
168  if (name == "normal") return ParticleGun::c_normalDistribution;
169  if (name == "normalpt") return ParticleGun::c_normalPtDistribution;
170  if (name == "normalcos") return ParticleGun::c_normalCosDistribution;
171  if (name == "discrete") return ParticleGun::c_discreteSpectrum;
172  if (name == "discretept") return ParticleGun::c_discretePtSpectrum;
173  if (name == "inversept") return ParticleGun::c_inversePtDistribution;
174  if (name == "polyline") return ParticleGun::c_polylineDistribution;
175  if (name == "polylinept") return ParticleGun::c_polylinePtDistribution;
176  if (name == "polylinecos") return ParticleGun::c_polylineCosDistribution;
177  B2ERROR("Unknown distribution '" << name << "', using fixed");
178  return ParticleGun::c_fixedValue;
179 }
180 
181 void ParticleGunModule::initialize()
182 {
183  //Initialize MCParticle collection
184  StoreArray<MCParticle> mcparticle;
185  mcparticle.registerInDataStore();
186 
187  //Convert string representations to distribution values
188  m_parameters.momentumDist = convertDistribution(m_momentumDist);
189  m_parameters.phiDist = convertDistribution(m_phiDist);
190  m_parameters.thetaDist = convertDistribution(m_thetaDist);
191  m_parameters.xVertexDist = convertDistribution(m_vertexDist);
192  m_parameters.yVertexDist = convertDistribution(m_vertexDist);
193  m_parameters.zVertexDist = convertDistribution(m_vertexDist);
194  m_parameters.timeDist = convertDistribution(m_timeDist);
195  if (getParam<std::string>("xVertexGeneration").isSetInSteering()) {
196  m_parameters.xVertexDist = convertDistribution(m_xVertexDist);
197  }
198  if (getParam<std::string>("yVertexGeneration").isSetInSteering()) {
199  m_parameters.yVertexDist = convertDistribution(m_yVertexDist);
200  }
201  if (getParam<std::string>("zVertexGeneration").isSetInSteering()) {
202  m_parameters.zVertexDist = convertDistribution(m_zVertexDist);
203  }
204 
205  //Convert degree to radian
206  if (m_parameters.thetaDist != ParticleGun::c_polylineCosDistribution &&
207  m_parameters.thetaDist != ParticleGun::c_normalCosDistribution) {
208  for (double& angle : m_parameters.thetaParams) angle *= Unit::deg;
209  }
210  if (m_parameters.phiDist != ParticleGun::c_polylineCosDistribution &&
211  m_parameters.phiDist != ParticleGun::c_normalCosDistribution) {
212  for (double& angle : m_parameters.phiParams) angle *= Unit::deg;
213  }
214 
215  //Assign parameters
216  m_particleGun.setParameters(m_parameters);
217 }
218 
219 void ParticleGunModule::event()
220 {
221  try {
222  m_particleGraph.clear();
223  m_particleGun.generateEvent(m_particleGraph);
224  m_particleGraph.generateList();
225  } catch (runtime_error& e) {
226  B2ERROR(e.what());
227  }
228 }
Base class for Modules.
Definition: Module.h:72
The ParticleGun module.
Class to generate tracks in the particle gun and store them in a MCParticle graph.
Definition: ParticleGun.h:26
EDistribution
enum containing all known distributions available for generation of values
Definition: ParticleGun.h:29
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
@ c_Input
Input Process.
Abstract base class for different kinds of events.