Belle II Software  release-08-01-10
eventSimulation.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 
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': 1,
116  'momentumGeneration': 'uniform',
117  'momentumParams': [0.1, 4],
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 = b2.register_module('EvtGenInput')
135 evtgenInput.logging.log_level = b2.LogLevel.WARNING
136 main.add_module(evtgenInput)
137 
138 
139 # ---------------------------------------------------------------------------------------
140 
141 
142 # Detector Simulation:
143 add_simulation(path=main,
144  usePXDDataReduction=False, # for training one does not want the data reduction
145  components=None) # dont specify components because else not the whole geometry will be loaded!
146 
147 # needed for fitting
148 main.add_module('SetupGenfitExtrapolation')
149 
150 # this adds the clusters for PXD and SVD (was done by the usePXDDataReduction previously) which are needed in the next steps
151 add_pxd_reconstruction(path=main)
152 add_svd_reconstruction(path=main)
153 
154 # ---------------------------------------------------------------------------------------
155 # Setting up the MC based track finder.
156 mctrackfinder = b2.register_module('TrackFinderMCTruthRecoTracks')
157 mctrackfinder.param('UseCDCHits', False)
158 mctrackfinder.param('UseSVDHits', True)
159 # Always use PXD hits! For SVD only, these will be filtered later when converting to SPTrackCand
160 # 15.02.2018: deactivated PXD again as we dont do pxd track finding anymore and to not bias the fit
161 mctrackfinder.param('UsePXDHits', False)
162 mctrackfinder.param('Smearing', False)
163 mctrackfinder.param('MinimalNDF', 6)
164 mctrackfinder.param('WhichParticles', ['primary'])
165 mctrackfinder.param('RecoTracksStoreArrayName', 'MCRecoTracks')
166 # set up the track finder to only use the first half loop of the track and discard all other hits
167 mctrackfinder.param('UseNLoops', 0.5)
168 mctrackfinder.param('discardAuxiliaryHits', True)
169 main.add_module(mctrackfinder)
170 
171 # include a track fit into the chain (sequence adopted from the tracking scripts)
172 # Correct time seed: Do I need it for VXD only tracks ????
173 main.add_module("IPTrackTimeEstimator", recoTracksStoreArrayName="MCRecoTracks", useFittedInformation=False)
174 # track fitting
175 daffitter = b2.register_module("DAFRecoFitter")
176 daffitter.param('recoTracksStoreArrayName', "MCRecoTracks")
177 # daffitter.logging.log_level = LogLevel.DEBUG
178 main.add_module(daffitter)
179 # also used in the tracking sequence (multi hypothesis)
180 # may be overkill
181 main.add_module('TrackCreator', recoTrackColName="MCRecoTracks", pdgCodes=[211, 321, 2212])
182 
183 
184 # build the name of the output file
185 outputFileName = outputDir + './'
186 if os.environ.get('USE_BEAST2_GEOMETRY'):
187  outputFileName += "SimEvts_Beast2"
188 else:
189  outputFileName += "SimEvts_Belle2"
190 outputFileName += '_' + str(rndseed) + '.root'
191 
192 # Root output. Default filename can be overriden with '-o' basf2 option.
193 rootOutput = b2.register_module('RootOutput')
194 rootOutput.param('outputFileName', outputFileName)
195 # to save some space exclude everything except stuff needed for tracking
196 rootOutput.param('excludeBranchNames', ["ARICHAeroHits",
197  "ARICHDigits",
198  "ARICHSimHits",
199  "BKLMDigits",
200  "BKLMSimHitPositions",
201  "BKLMSimHits",
202  "CDCHits",
203  "CDCHits4Trg",
204  "CDCSimHits",
205  "CDCSimHitsToCDCHits4Trg",
206  "ECLDigits",
207  "ECLDsps",
208  "ECLHits",
209  "ECLSimHits",
210  "ECLTrigs",
211  "ECLDiodeHits",
212  "EKLMDigits",
213  "EKLMSimHits",
214  "TOPBarHits",
215  "TOPDigits",
216  "TOPRawDigits",
217  "TOPSimHits"
218  ])
219 main.add_module(rootOutput)
220 
221 b2.log_to_file('createSim.log', append=False)
222 
223 b2.print_path(main)
224 
225 b2.process(main)
226 print(b2.statistics)