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