Belle II Software  release-06-01-15
ParticleGunFull.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 
11 
12 from basf2 import set_log_level, register_module, process, LogLevel, \
13  set_random_seed, print_params, create_path, statistics
14 from simulation import add_simulation
15 from reconstruction import add_reconstruction
16 
17 # suppress messages and warnings during processing:
18 set_log_level(LogLevel.WARNING)
19 
20 # to run the framework the used modules need to be registered
21 particlegun = register_module('ParticleGun')
22 
23 # ============================================================================
24 # Setting the random seed for particle generation
25 set_random_seed(123)
26 
27 # ============================================================================
28 # Setting the list of particle codes (PDG codes) for the generated particles
29 # the codes are given in an array, if only one code is used, the brackets
30 # should be kept:
31 # particlegun.param('pdgCodes', [11])
32 
33 # there is no limit on how many codes can be given the particle gun will select
34 # randomly amongst the PDGcodes using a uniform distribution if nTracks>0,
35 # otherwise there will be one particle for each code in the list default is
36 # [-11, 11]
37 particlegun.param('pdgCodes', [-11, 11])
38 
39 # ============================================================================
40 # Setting the number of tracks to be generated per event: this number can be
41 # any int>=0 default is 1
42 particlegun.param('nTracks', 10)
43 
44 # a value o 0 means that a track should be created for each entry in the
45 # pdgCodes list, e.g. the following two lines would create two electrons and
46 # one pion per event.
47 # particlegun.param('pdgCodes', [11,11,211])
48 # particlegun.param('nTracks', 0)
49 
50 # ============================================================================
51 # Varying the number of tracks per event can be achieved by setting varyNTacks
52 # to True. If so, the number of tracks will be randomized using possion
53 # distribution around the value of nTracks. Only valid if nTracks>0, default
54 # is False
55 particlegun.param('varyNTracks', False)
56 
57 # ============================================================================
58 # Each particle has a total momentum, a direction given as theta and phi and a
59 # vertex position in x, y and z. For each variable we need to specify the
60 # distribution and the parameters for the distribution. The number of
61 # parameters depends on the chosen distribution. All available distributions
62 # are listed here with required parameters are given in []. The distributions
63 # with suffix "Pt" can only be used for momentum generation and the ones with
64 # suffix "Cos" can only used for the generation of theta and phi.
65 #
66 # - fixed: always use the exact same value [value]
67 # - uniform: uniform distribution between min and max [min, max]
68 # - uniformPt: uniform distribution of transverse momentum between a given
69 # minimal and maximum value [min, max]
70 # - uniformCos: uniform distribution of the cosine of the angle between min
71 # and max of the absolute value [min, max]
72 # - normal: normal (gaussian) distribution around mean with width of sigma
73 # [mean, sigma]
74 # - normalPt: normal distribution of transverse momentum [mean, sigma]
75 # - normalCos: normal distribution of the cosine of the angle, not the
76 # absolute value [mean, sigma]
77 # - inversePt: generate momentum to obtain a flat distribution of the track
78 # curvature (inverse transverse momentum) between a minimal and
79 # maximal transverse momentum, [min_pt, max_pt]
80 # - polyline: create the momentum to follow an arbitrary distribution given
81 # as a list of x and y coordinates. All y coordinates must be
82 # non-negative and at leas one y coordinate must be positive
83 # [x1, x2, ..., xn, y1, y2, ..., yn]
84 # - polylinePt: same as polyline but for the transverse momentum, not the
85 # total momentum.
86 # [x1, x2, ..., xn, y1, y2, ..., yn]
87 # - polylineCos: same as polyline but for the cosine of the angle, not the
88 # absolute value
89 # [x1, x2, ..., xn, y1, y2, ..., yn]
90 # - discrete: a discrete spectrum consisting of possible values xi and their
91 # weights wi (useful e.g. for radioactive sources)
92 # [x1, x2, ..., xn, w1, w2, ..., wn]
93 
94 # ============================================================================
95 # Momentum generation
96 #
97 # The default is a uniform momentum distribution between 0.05 and 3 GeV
98 particlegun.param('momentumGeneration', 'uniform')
99 particlegun.param('momentumParams', [0.05, 3])
100 
101 # we could also generate a fixed momentum of 1 GeV
102 # particlegun.param('momentumGeneration', "fixed")
103 # particlegun.param('momentumParams', [1.0])
104 
105 # or we could generate a normal distributed transverse momentum around 2 GeV
106 # with a width of 0.5 GeV
107 # particlegun.param('momentumGeneration', "normalPt")
108 # particlegun.param('momentumParams', [2.0, 0.5])
109 
110 # to generate the momentum according to a cadmium 109
111 # source we could use
112 # particlegun.param('momentumGeneration', 'discreteSpectrum'),
113 # particlegun.param('momentumParams', [
114 # 22.1e-6, 25.0e-6, 88.0e-6, # photon energies
115 # 82.6, 14.7, 3.65, # weights
116 # ])
117 
118 # ============================================================================
119 # polar angle, theta
120 # The default is a uniform theta distribution between 17 and 150 degree
121 
122 particlegun.param('thetaGeneration', 'uniform')
123 particlegun.param('thetaParams', [17, 150])
124 
125 # We could also generate between 17 and 150 degrees with a flat distribution in
126 # cos(theta)
127 # particlegun.param('thetaGeneration', 'uniformCos')
128 # particlegun.param('thetaParams', [17, 150])
129 
130 # or we could create a theta angle between 17 and 150 degree where the
131 # cos(theta) distribution is flat
132 # particlegun.param('thetaGeneration', "normal")
133 # particlegun.param('thetaParams', [90,5])
134 
135 # Finally, we could use numpy to create events where the cos(theta)
136 # distribution follows a parabolic shape:
137 # import numpy as np
138 # # Create a set of 1000 x values spread uniformly over -1, 1
139 # x = np.linspace(-1,1,1000)
140 # # Create the corresponding distribution
141 # y = 1-x**2
142 # # Set the parameters by concatenating the x and y positions
143 # particlegun.param('thetaGeneration', "polylineCos")
144 # particlegun.param('thetaParams', list(x) + list(y))
145 
146 # ============================================================================
147 # azimuth angle, phi
148 # The default is a uniform theta distribution between 0 and 360 degree
149 
150 particlegun.param('phiGeneration', 'uniform')
151 particlegun.param('phiParams', [0, 360])
152 
153 # or we could create a normal distributed phi angle around 90 degrees with a
154 # width of 5 degrees
155 # particlegun.param('phiGeneration', "normal")
156 # particlegun.param('phiParams', [90,5])
157 
158 # ============================================================================
159 # Vertex generation
160 # The default is a fixed vertex at (0,0,0) for all tracks
161 particlegun.param('vertexGeneration', 'fixed')
162 particlegun.param('xVertexParams', [0])
163 particlegun.param('yVertexParams', [0])
164 particlegun.param('zVertexParams', [0])
165 
166 # We could also generate a normal distributed vertex with mean at (0,0,0) and
167 # width of 10µm, 60nm and 190 µm in x, y and z respectively
168 # particlegun.param('vertexGeneration', 'fixed')
169 # particlegun.param('xVertexParams', [0, 10e-4])
170 # particlegun.param('yVertexParams', [0, 60e-7])
171 # particlegun.param('zVertexParams', [0, 190e-4])
172 
173 # We can also specify a different distribution for any of the three axes, e.g.
174 # to make the z-vertex uniform between -10 and 10 cm and the xy vertex normal
175 # distributed around zero with a width of 0.1 cm we could use
176 # particlegun.param('vertexGeneration', 'normal')
177 # particlegun.param('xVertexParams', [0, 0.1])
178 # particlegun.param('yVertexParams', [0, 0.1])
179 # particlegun.param('zVertexGeneration', 'uniform')
180 # particlegun.param('zVertexParams', [-10, 10])
181 
182 # ============================================================================
183 # Setting independent vertices for each particle The default is to create one
184 # event vertex for all particles per event. By setting independentVertices to
185 # True, a new vertex will be created for each particle default is False
186 particlegun.param('independentVertices', False)
187 
188 # ============================================================================
189 # Print the parameters of the particle gun
190 print_params(particlegun)
191 
192 # ============================================================================
193 # Now lets create the necessary modules to perform a simulation
194 #
195 # Create Event information
196 eventinfosetter = register_module('EventInfoSetter')
197 # Show progress of processing
198 progress = register_module('Progress')
199 # Load parameters
200 gearbox = register_module('Gearbox')
201 # Create geometry
202 geometry = register_module('Geometry')
203 # Save output of simulation
204 output = register_module('RootOutput')
205 
206 # Setting the option for all non particle gun modules: want to process 100 MC
207 # events
208 eventinfosetter.param({'evtNumList': [100], 'runList': [1]})
209 
210 # Set output filename
211 output.param('outputFileName', 'ParticleGunOutput.root')
212 
213 # ============================================================================
214 main = create_path()
215 main.add_module(eventinfosetter)
216 main.add_module(progress)
217 main.add_module(particlegun)
218 
219 main.add_module(output)
220 
221 # Process events
222 process(main)
223 
224 # Print call statistics
225 print(statistics)