Belle II Software  release-08-01-10
eventSimulationBhabha.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 
11 
12 
34 
35 
36 import basf2 as b2
37 from beamparameters import add_beamparameters
38 from simulation import add_simulation
39 
40 import os
41 import sys
42 import random
43 
44 from pxd import add_pxd_reconstruction
45 from svd import add_svd_reconstruction
46 from generators import add_babayaganlo_generator
47 
48 # ---------------------------------------------------------------------------------------
49 
50 # Set Random Seed for reproducable simulation. 0 means really random.
51 rndseed = 12345
52 # assume the first argument is the random seed
53 if(len(sys.argv) > 1):
54  rndseed = sys.argv[1]
55 
56 outputDir = './'
57 # assume second argument is the output directory
58 if(len(sys.argv) > 2):
59  outputDir = sys.argv[2]
60 
61 b2.set_random_seed(rndseed)
62 
63 
64 # Set log level. Can be overridden with the "-l LEVEL" flag for basf2.
65 b2.set_log_level(b2.LogLevel.ERROR)
66 
67 # ---------------------------------------------------------------------------------------
68 main = b2.create_path()
69 
70 eventinfosetter = b2.register_module('EventInfoSetter')
71 # default phase3 geometry:
72 exp_number = 0
73 # if environment variable is set then phase2 (aka Beast2) geometry will be taken
74 if os.environ.get('USE_BEAST2_GEOMETRY'):
75  exp_number = 1002
76 eventinfosetter.param("expList", [exp_number])
77 main.add_module(eventinfosetter)
78 
79 eventinfoprinter = b2.register_module('EventInfoPrinter')
80 main.add_module(eventinfoprinter)
81 
82 progress = b2.register_module('Progress')
83 main.add_module(progress)
84 
85 # ---------------------------------------------------------------------------------------
86 # Simulation Settings:
87 
88 
89 # randomize the vertex position (flatly distributed) to make the sectormap more robust wrt. changing beam position
90 # minima and maxima of the beam position given in cm
91 random.seed(rndseed)
92 vertex_x_min = -0.1
93 vertex_x_max = 0.1
94 vertex_y_min = -0.1
95 vertex_y_max = 0.1
96 vertex_z_min = -0.5
97 vertex_z_max = 0.5
98 
99 vertex_x = random.uniform(vertex_x_min, vertex_x_max)
100 vertex_y = random.uniform(vertex_y_min, vertex_y_max)
101 vertex_z = random.uniform(vertex_z_min, vertex_z_max)
102 
103 print("WARNING: setting non-default beam vertex at x= " + str(vertex_x) + " y= " + str(vertex_y) + " z= " + str(vertex_z))
104 
105 # Particle Gun:
106 # One can add more particle gun modules if wanted.
107 
108 # additional flatly smear the muon vertex between +/- this value
109 vertex_delta = 0.005 # in cm
110 
111 particlegun = b2.register_module('ParticleGun')
112 particlegun.logging.log_level = b2.LogLevel.WARNING
113 param_pGun = {
114  'pdgCodes': [13, -13], # 13 = muon --> negatively charged!
115  'nTracks': 8,
116  'momentumGeneration': 'uniform',
117  'momentumParams': [0.1, 7],
118  'vertexGeneration': 'uniform',
119  'xVertexParams': [vertex_x - vertex_delta, vertex_x + vertex_delta], # in cm...
120  'yVertexParams': [vertex_y - vertex_delta, vertex_y + vertex_delta],
121  'zVertexParams': [vertex_z - vertex_delta, vertex_z + vertex_delta]
122 }
123 
124 particlegun.param(param_pGun)
125 main.add_module(particlegun)
126 
127 # EvtGen Simulation:
128 # TODO: There are newer convenience functions for this task -> Include them!
129 # Beam parameters
130 beamparameters = add_beamparameters(main, "Y4S")
131 beamparameters.param("vertex", [vertex_x, vertex_y, vertex_z])
132 # print_params(beamparameters)
133 
134 # evtgenInput = register_module('EvtGenInput')
135 # evtgenInput.logging.log_level = LogLevel.WARNING
136 # main.add_module(evtgenInput)
137 
138 # generate some Bhabha
139 add_babayaganlo_generator(path=main, finalstate='ee')
140 
141 
142 # ---------------------------------------------------------------------------------------
143 
144 
145 # Detector Simulation:
146 add_simulation(path=main,
147  usePXDDataReduction=False, # for training one does not want the data reduction
148  components=None) # dont specify components because else not the whole geometry will be loaded!
149 
150 # needed for fitting
151 main.add_module('SetupGenfitExtrapolation')
152 
153 # this adds the clusters for PXD and SVD (was done by the usePXDDataReduction previously) which are needed in the next steps
154 add_pxd_reconstruction(path=main)
155 add_svd_reconstruction(path=main)
156 
157 # ---------------------------------------------------------------------------------------
158 # Setting up the MC based track finder.
159 mctrackfinder = b2.register_module('TrackFinderMCTruthRecoTracks')
160 mctrackfinder.param('UseCDCHits', False)
161 mctrackfinder.param('UseSVDHits', True)
162 # Always use PXD hits! For SVD only, these will be filtered later when converting to SPTrackCand
163 # 15.02.2018: deactivated PXD again as we dont do pxd track finding anymore and to not bias the fit
164 mctrackfinder.param('UsePXDHits', False)
165 mctrackfinder.param('Smearing', False)
166 mctrackfinder.param('MinimalNDF', 6)
167 mctrackfinder.param('WhichParticles', ['primary'])
168 mctrackfinder.param('RecoTracksStoreArrayName', 'MCRecoTracks')
169 # set up the track finder to only use the first half loop of the track and discard all other hits
170 mctrackfinder.param('UseNLoops', 0.5)
171 mctrackfinder.param('discardAuxiliaryHits', True)
172 main.add_module(mctrackfinder)
173 
174 # include a track fit into the chain (sequence adopted from the tracking scripts)
175 # Correct time seed: Do I need it for VXD only tracks ????
176 main.add_module("IPTrackTimeEstimator", recoTracksStoreArrayName="MCRecoTracks", useFittedInformation=False)
177 # track fitting
178 daffitter = b2.register_module("DAFRecoFitter")
179 daffitter.param('recoTracksStoreArrayName', "MCRecoTracks")
180 # daffitter.logging.log_level = LogLevel.DEBUG
181 main.add_module(daffitter)
182 # also used in the tracking sequence (multi hypothesis)
183 # may be overkill
184 main.add_module('TrackCreator', recoTrackColName="MCRecoTracks", pdgCodes=[211, 321, 2212])
185 
186 
187 # build the name of the output file
188 outputFileName = outputDir + './'
189 if os.environ.get('USE_BEAST2_GEOMETRY'):
190  outputFileName += "SimEvts_Beast2"
191 else:
192  outputFileName += "SimEvts_Belle2"
193 outputFileName += '_' + str(rndseed) + '.root'
194 
195 # Root output. Default filename can be overriden with '-o' basf2 option.
196 rootOutput = b2.register_module('RootOutput')
197 rootOutput.param('outputFileName', outputFileName)
198 # to save some space exclude everything except stuff needed for tracking
199 rootOutput.param('excludeBranchNames', ["ARICHAeroHits",
200  "ARICHDigits",
201  "ARICHSimHits",
202  "BKLMDigits",
203  "BKLMSimHitPositions",
204  "BKLMSimHits",
205  "CDCHits",
206  "CDCHits4Trg",
207  "CDCSimHits",
208  "CDCSimHitsToCDCHits4Trg",
209  "ECLDigits",
210  "ECLDsps",
211  "ECLHits",
212  "ECLSimHits",
213  "ECLTrigs",
214  "ECLDiodeHits",
215  "EKLMDigits",
216  "EKLMSimHits",
217  "TOPBarHits",
218  "TOPDigits",
219  "TOPRawDigits",
220  "TOPSimHits"
221  ])
222 main.add_module(rootOutput)
223 
224 b2.log_to_file('createSim.log', append=False)
225 
226 b2.print_path(main)
227 
228 b2.process(main)
229 print(b2.statistics)