Belle II Software  release-05-02-19
generators.py
1 '''
2 This module contains convenience functions to setup most commonly used physics
3 generators correctly with their default settings. More information can be found
4 in `BELLE2-NOTE-PH-2015-006`_
5 
6 Contact: Torben Ferber (ferber@physics.ubc.ca)
7 
8 .. _BELLE2-NOTE-PH-2015-006: https://docs.belle2.org/record/282
9 '''
10 
11 from basf2 import *
12 from ROOT import Belle2
13 import os
14 import pdg
15 
16 
18  """Return the default DECAY.dec for Belle2"""
19  return Belle2.FileSystem.findFile("decfiles/dec/DECAY_BELLE2.DEC")
20 
21 
23  path,
24  emptypath,
25  nChargedMin=0,
26  nChargedMax=999,
27  MinChargedP=-1.0,
28  MinChargedPt=-1.0,
29  MinChargedTheta=0.0,
30  MaxChargedTheta=180.0,
31  nPhotonMin=0,
32  nPhotonMax=999,
33  MinPhotonEnergy=-1,
34  MinPhotonTheta=0.0,
35  MaxPhotonTheta=180.0,
36  applyInCMS=False,
37  stableParticles=False):
38  """
39  Adds generator preselection.
40  Should be added to the path after the generator.add_abc_generator but before simulation.add_simulation modules
41  It uses all particles from the event generator (i.e. primary, non-virtual, non-initial particles).
42  It checks if the required conditions are fullfilled.
43  If not, the events are given to the emptypath.
44  The main usecase is a reduction of simulation time.
45  Note that you have to multiply the generated cross section by the retention fraction of the preselection.
46 
47  Parameters:
48  path (basf2.Path): path where the generator should be added
49  emptypath (basf2.Path): path where the skipped events are given to
50  nChargedMin (int): minimum number of charged particles
51  nChargedMax (int): maximum number of charged particles
52  MinChargedP (float): minimum charged momentum [GeV]
53  MinChargedPt (float): minimum charged transverse momentum (pt) [GeV]
54  MinChargedTheta (float): minimum polar angle of charged particle [deg]
55  MaxChargedTheta (float): maximum polar angle of charged particle [deg]
56  nPhotonMin (int): minimum number of photons
57  nPhotonMax (int): maximum number of photons
58  MinPhotonEnergy (float): minimum photon energy [GeV]
59  MinPhotonTheta (float): minimum polar angle of photon [deg]
60  MaxPhotonTheta (float): maximum polar angle of photon [deg]
61  applyInCMS (bool): if true apply the P,Pt,theta, and energy cuts in the center of mass frame
62  stableParticles (bool): if true apply the selection criteria for stable particles in the generator
63  """
64 
65  generatorpreselection = path.add_module('GeneratorPreselection',
66  nChargedMin=nChargedMin,
67  nChargedMax=nChargedMax,
68  MinChargedP=MinChargedP,
69  MinChargedPt=MinChargedPt,
70  MinChargedTheta=MinChargedTheta,
71  MaxChargedTheta=MaxChargedTheta,
72  nPhotonMin=nPhotonMin,
73  nPhotonMax=nPhotonMax,
74  MinPhotonEnergy=MinPhotonEnergy,
75  MinPhotonTheta=MinPhotonTheta,
76  MaxPhotonTheta=MaxPhotonTheta,
77  stableParticles=stableParticles
78  )
79 
80  # empty path for unwanted events
81  generatorpreselection.if_value('<11', emptypath)
82 
83 
85  path,
86  finalstate='',
87  preselection=False,
88  enableTauDecays=True,
89  minmass=0.5,
90  subweights=[],
91  maxsubweight=1,
92  maxfinalweight=3.0):
93  """
94  Add the default two photon generator for four fermion final states
95 
96  Parameters:
97  path (basf2.Path): path where the generator should be added
98  finalstate (str): either "e+e-e+e-", "e+e-mu+mu-", "e+e-tau+tau-", "mu+mu-mu+mu-" or "mu+mu-tau+tau-"
99  preselection (bool): if True, select events with at least one medium pt particle in the CDC acceptance
100  enableTauDecays (bool): if True, allow tau leptons to decay (using EvtGen)
101  """
102 
103  if finalstate == 'e+e-e+e-':
104  aafh_mode = 5
105  if not subweights: # default subweights are for minmass=0.5
106  aafh_subgeneratorWeights = [1.0, 7.986e+01, 5.798e+04, 3.898e+05, 1.0, 1.664e+00, 2.812e+00, 7.321e-01]
107  else:
108  aafh_subgeneratorWeights = subweights
109  if abs(minmass - 0.5) > 0.01 and not subweights:
110  B2WARNING("add_aafh_generator: non default invariant mass cut without updated subweights requested!")
111  elif finalstate == 'e+e-mu+mu-':
112  aafh_mode = 3
113  if not subweights: # default subweights are for minmass=0.5
114  aafh_subgeneratorWeights = [1.000e+00, 1.520e+01, 3.106e+03, 6.374e+03, 1.000e+00, 1.778e+00, 6.075e+00, 6.512e+00]
115  else:
116  aafh_subgeneratorWeights = subweights
117  if abs(minmass - 0.5) > 0.01 and not subweights:
118  B2WARNING("add_aafh_generator: non default invariant mass cut without updated subweights requested!")
119  elif finalstate == 'e+e-tau+tau-':
120  aafh_mode = 4
121  particle = 'tau-'
122  minmass = 0
123  if not subweights:
124  aafh_subgeneratorWeights = [1.000e+00, 2.214e+00, 1.202e+01, 1.536e+01, 1.000e+00, 1.664e+00, 1.680e+01, 6.934e+00]
125  else:
126  aafh_subgeneratorWeights = subweights
127  if preselection:
128  B2WARNING(
129  f"You requested a generator preselection for the final state {finalstate}: "
130  "please consider to remove it, since the cross section is small.")
131  elif finalstate == 'mu+mu-mu+mu-':
132  aafh_mode = 2
133  minmass = 0
134  maxsubweight = 3
135  if not subweights:
136  aafh_subgeneratorWeights = [0.000e+00, 0.000e+00, 1.000e+00, 3.726e+00, 1.000e+00, 1.778e+00, 1.000e+00, 1.094e+00]
137  else:
138  aafh_subgeneratorWeights = subweights
139  if preselection:
140  B2WARNING(
141  f"You requested a generator preselection for the final state {finalstate}: "
142  "please consider to remove it, since the cross section is small.")
143  elif finalstate == 'mu+mu-tau+tau-':
144  aafh_mode = 1
145  particle = 'tau-'
146  minmass = 0
147  maxsubweight = 3
148  if not subweights:
149  aafh_subgeneratorWeights = [0.000e+00, 0.000e+00, 1.000e+00, 1.715e+00, 1.000e+00, 1.778e+00, 1.000e+00, 6.257e-01]
150  else:
151  aafh_subgeneratorWeights = subweights
152  if preselection:
153  B2WARNING(
154  f"You requested a generator preselection for the final state {finalstate}: "
155  "please consider to remove it, since the cross section is small.")
156  elif finalstate == 'tau+tau-tau+tau-':
157  B2FATAL(f"AAFH is not able to generate the {finalstate} final state. Please use KoralW instead.")
158  else:
159  B2FATAL(f"add_aafh_generator final state not supported: {finalstate}")
160 
161  aafh_maxSubgeneratorWeight = maxsubweight
162  aafh_maxFinalWeight = maxfinalweight
163 
164  path.add_module(
165  'AafhInput',
166  mode=aafh_mode,
167  rejection=2,
168  maxSubgeneratorWeight=aafh_maxSubgeneratorWeight,
169  maxFinalWeight=aafh_maxFinalWeight,
170  subgeneratorWeights=aafh_subgeneratorWeights,
171  suppressionLimits=[1e100] * 4,
172  minMass=minmass
173  )
174 
175  if preselection:
176  generator_emptypath = create_path()
178  path=path,
179  emptypath=generator_emptypath,
180  nChargedMin=1,
181  MinChargedPt=0.1,
182  MinChargedTheta=17.0,
183  MaxChargedTheta=150.0)
184 
185  if 'tau+tau-' in finalstate:
186  if enableTauDecays:
187  path.add_module('EvtGenDecay')
188  else:
189  B2WARNING("The tau decays will not be generated.")
190 
191 
192 def add_kkmc_generator(path, finalstate='', signalconfigfile='', useTauolaBelle=False, tauinputfile=''):
193  """
194  Add the default muon pair and tau pair generator KKMC.
195  For tau decays, TauolaBelle and TauolaBelle2 are available.
196  Signal events can be produced setting a configuration file. Please notice that the configuration files for
197  TauolaBelle and TauolaBelle2 has a very different structure (see the examples below generators/examples).
198 
199  Parameters:
200  path (basf2.Path): path where the generator should be added
201  finalstate(str): either "mu-mu+" or "tau-tau+"
202  signalconfigfile(str): File with configuration of the signal event to generate. It doesn't affect mu-mu+ decays.
203  useTauolaBelle(bool): If true, tau decay is driven by TauolaBelle. Otherwise TauolaBelle2 is used.
204  It doesn't affect mu-mu+ decays.
205  tauinputfile(str) : File to override KK2f_defaults. Only [sometimes] needed when tau decay is driven by TauolaBelle.
206  """
207 
208 
209  kkmc_inputfile = Belle2.FileSystem.findFile('data/generators/kkmc/tauola_bbb.input.dat')
210 
211 
212  kkmc_logfile = 'kkmc_tautau.txt'
213 
214 
215  kkmc_config = Belle2.FileSystem.findFile('data/generators/kkmc/KK2f_defaults.dat')
216 
217 
218  kkmc_tauconfigfile = ''
219 
220  if finalstate == 'tau+tau-':
221  B2WARNING("add_kkmc_generator: please set finalstate as 'tau-tau+'. 'tau+tau-' will be deprecated in the future"
222  " for consistency in the configuration files.")
223  finalstate = 'tau-tau+'
224  if finalstate == 'mu+mu-':
225  B2WARNING("add_kkmc_generator: please set finalstate as 'mu-mu+'. 'mu+mu-' will be deprecated in the future for"
226  " consistency in the configuration files.")
227  finalstate = 'mu-mu+'
228 
229  if finalstate == 'tau-tau+':
230  if useTauolaBelle:
231  B2INFO("Generating tau pair events with TauolaBelle")
232 
233  kkmc_inputfile = Belle2.FileSystem.findFile('data/generators/kkmc/tau.input.dat')
234  kkmc_tauconfigfile = Belle2.FileSystem.findFile('data/generators/kkmc/tau_decaytable.dat')
235 
236  if not signalconfigfile == '':
237  B2INFO(f"Using config file defined by user: {signalconfigfile}")
238  if useTauolaBelle:
239  kkmc_tauconfigfile = find_file(signalconfigfile)
240  else:
241  kkmc_inputfile = find_file(signalconfigfile)
242 
243  if not tauinputfile == '':
244  kkmc_inputfile = find_file(tauinputfile)
245 
246  elif finalstate == 'mu-mu+':
247  kkmc_inputfile = Belle2.FileSystem.findFile('data/generators/kkmc/mu.input.dat')
248  kkmc_logfile = 'kkmc_mumu.txt'
249 
250  else:
251  B2FATAL("add_kkmc_generator final state not supported: {}".format(finalstate))
252 
253  # use KKMC to generate lepton pairs
254  kkgeninput = path.add_module(
255  'KKGenInput',
256  tauinputFile=kkmc_inputfile,
257  KKdefaultFile=kkmc_config,
258  taudecaytableFile=kkmc_tauconfigfile,
259  kkmcoutputfilename=kkmc_logfile,
260  )
261 
262 
263 def add_evtgen_generator(path, finalstate='', signaldecfile=None, coherentMixing=True, parentParticle='Upsilon(4S)'):
264  """
265  Add EvtGen for mixed and charged BB
266 
267  Parameters:
268  path (basf2.Path): path where the generator should be added
269  finalstate (str): Either "charged" for B+/B- or "mixed" for B0/anti-B0
270  coherentMixing: Either True or False. Switches on or off the coherent decay of the B0-B0bar pair.
271  It should always be True, unless you are generating Y(5,6S) -> BBar. In the latter case,
272  setting it False solves the interla limiation of Evtgen that allows to make a
273  coherent decay only starting from the Y(4S).
274  parentParticle (str): initial state (used only if it is not Upsilon(4S).
275  """
276  evtgen_userdecfile = Belle2.FileSystem.findFile('data/generators/evtgen/charged.dec')
277 
278  if parentParticle != 'Upsilon(3S)' and parentParticle != 'Upsilon(4S)'\
279  and parentParticle != 'Upsilon(5S)' and parentParticle != 'Upsilon(6S)':
280  B2FATAL("add_evtgen_generator initial state not supported: {}".format(parentParticle))
281 
282  if finalstate == 'charged':
283  pass
284  elif finalstate == 'mixed':
285  evtgen_userdecfile = Belle2.FileSystem.findFile('data/generators/evtgen/mixed.dec')
286  elif finalstate == 'signal':
287  evtgen_userdecfile = signaldecfile
288  else:
289  B2FATAL("add_evtgen_generator final state not supported: {}".format(finalstate))
290 
291  if signaldecfile and finalstate in ['charged', 'mixed']:
292  B2WARNING("ignoring decfile: {}".format(signaldecfile))
293 
294  # use EvtGen
295  if parentParticle == 'Upsilon(3S)':
296  if finalstate != 'signal':
297  B2FATAL("add_evtgen_generator initial state {} is supported only with 'signal' final state".format(parentParticle))
298  if coherentMixing:
299  coherentMixing = False
300  B2WARNING("add_evtgen_generator initial state {} has no BB mixing, now switching coherentMixing OFF"
301  .format(parentParticle))
302 
303  if parentParticle == 'Upsilon(5S)':
304  if finalstate != 'signal':
305  B2FATAL("add_evtgen_generator initial state {} is supported only with 'signal' final state".format(parentParticle))
306  if coherentMixing:
307  coherentMixing = False
308  B2WARNING(
309  "add_evtgen_generator initial state {} is supported only with false coherentMixing, now switching it OFF"
310  .format(parentParticle))
311  pdg.load(Belle2.FileSystem.findFile('decfiles/dec/Y5S.pdl'))
312 
313  if parentParticle == 'Upsilon(6S)':
314  if finalstate != 'signal':
315  B2FATAL("add_evtgen_generator initial state {} is supported only with 'signal' final state".format(parentParticle))
316  if coherentMixing:
317  coherentMixing = False
318  B2WARNING(
319  "add_evtgen_generator initial state {} is supported only with false coherentMixing, now switching it OFF"
320  .format(parentParticle))
321  pdg.load(Belle2.FileSystem.findFile('decfiles/dec/Y6S.pdl'))
322 
323  evtgen = path.add_module(
324  'EvtGenInput',
325  userDECFile=evtgen_userdecfile,
326  CoherentMixing=coherentMixing,
327  ParentParticle=parentParticle
328  )
329 
330 
331 def add_continuum_generator(path, finalstate, userdecfile='', *, skip_on_failure=True):
332  """
333  Add the default continuum generators KKMC + PYTHIA including their default decfiles and PYTHIA settings
334 
335  See Also:
336  `add_inclusive_continuum_generator()` to add continuum generation with preselected particles
337 
338  Parameters:
339  path (basf2.Path): path where the generator should be added
340  finalstate (str): uubar, ddbar, ssbar, ccbar
341  userdecfile (str): EvtGen decfile used for particle decays
342  skip_on_failure (bool): If True stop event processing right after
343  fragmentation fails. Otherwise continue normally
344  """
345 
346 
347  kkmc_inputfile = Belle2.FileSystem.findFile('data/generators/kkmc/uubar_nohadronization.input.dat')
348 
349 
350  kkmc_logfile = 'kkmc_uubar.txt'
351 
352 
353  pythia_config = Belle2.FileSystem.findFile('data/generators/modules/fragmentation/pythia_belle2.dat')
354 
355 
356  decay_user = Belle2.FileSystem.findFile('data/generators/modules/fragmentation/dec_belle2_qqbar.dec')
357  if userdecfile == '':
358  pass
359  else:
360  B2INFO('Replacing default user decfile: {}'.format(userdecfile))
361  decay_user = userdecfile
362 
363 
364  kkmc_config = Belle2.FileSystem.findFile('data/generators/kkmc/KK2f_defaults.dat')
365 
366 
367  decay_file = get_default_decayfile()
368 
369  if finalstate == 'uubar':
370  pass
371  elif finalstate == 'ddbar':
372  kkmc_inputfile = Belle2.FileSystem.findFile('data/generators/kkmc/ddbar_nohadronization.input.dat')
373  kkmc_logfile = 'kkmc_ddbar.txt'
374  elif finalstate == 'ssbar':
375  kkmc_inputfile = Belle2.FileSystem.findFile('data/generators/kkmc/ssbar_nohadronization.input.dat')
376  kkmc_logfile = 'kkmc_ssbar.txt'
377  elif finalstate == 'ccbar':
378  kkmc_inputfile = Belle2.FileSystem.findFile('data/generators/kkmc/ccbar_nohadronization.input.dat')
379  pythia_config = Belle2.FileSystem.findFile('data/generators/modules/fragmentation/pythia_belle2_charm.dat')
380  kkmc_logfile = 'kkmc_ccbar.txt'
381  else:
382  B2FATAL("add_continuum_generator final state not supported: {}".format(finalstate))
383 
384  # use KKMC to generate qqbar events (no fragmentation at this stage)
385  kkgeninput = path.add_module(
386  'KKGenInput',
387  tauinputFile=kkmc_inputfile,
388  KKdefaultFile=kkmc_config,
389  taudecaytableFile='',
390  kkmcoutputfilename=kkmc_logfile,
391  )
392 
393  # add the fragmentation module to fragment the generated quarks into hadrons
394  # using PYTHIA8
395  fragmentation = path.add_module(
396  'Fragmentation',
397  ParameterFile=pythia_config,
398  ListPYTHIAEvent=0,
399  UseEvtGen=1,
400  DecFile=decay_file,
401  UserDecFile=decay_user,
402  )
403 
404  if skip_on_failure:
405  # branch to an empty path if PYTHIA failed, this will change the number of events
406  # but the file meta data will contain the total number of generated events
407  generator_emptypath = create_path()
408  fragmentation.if_value('<1', generator_emptypath)
409 
410 
411 def add_inclusive_continuum_generator(path, finalstate, particles, userdecfile='',
412  *, include_conjugates=True, max_iterations=100000):
413  """
414  Add continuum generation but require at least one of the given particles be
415  present in the event.
416 
417  For example to only generate ccbar events which contain a "D*+" or an
418  electron one could would use
419 
420  >>> add_inclusive_continuum_generator(path, "ccbar", ["D*+", 11])
421 
422  If you are unsure how the particles are named in Belle II please have a look
423  at the ``b2help-particles`` executable or the `pdg` python module.
424 
425  See Also:
426  `add_continuum_generator()` to add continuum generation without preselection
427 
428  Parameters:
429  finalstate (str): uubar, ddbar, ssbar, ccbar
430  particles (list): A list of particle names or pdg codes. An event is
431  only accepted if at lease one of those particles appears in the event.
432  userdecfile (str): EvtGen decfile used for particle decays
433  include_conjugates (bool): If True (default) accept the event also if a
434  charge conjugate of the given particles is found
435  max_iterations (int): maximum tries per event to generate the requested
436  particle. If exceeded processing will be stopped with a
437  `FATAL <LogLevel.FATAL>` error so for rare particles one might need a
438  larger number.
439  """
440  loop_path = create_path()
441  # we might run this more than once so make sure we remove any particles
442  # before generating new ones
443  loop_path.add_module("PruneDataStore", keepMatchedEntries=False, matchEntries=["MCParticles"])
444  # add the generator but make sure it doesn't stop processing on
445  # fragmentation failure as is this currently not supported by do_while
446  add_continuum_generator(loop_path, finalstate, userdecfile, skip_on_failure=False)
447  # check for the particles we want
448  loop_path.add_module("InclusiveParticleChecker", particles=particles, includeConjugates=include_conjugates)
449  # Done, add this to the path and iterate it until we found our particle
450  path.do_while(loop_path, max_iterations=max_iterations)
451 
452 
453 def add_bhwide_generator(path, minangle=0.5):
454  """
455  Add the high precision QED generator BHWIDE to the path. Settings are the default L1/HLT study settings
456  with a cross section of about 124000 nb (!)
457 
458  Parameters:
459  path (basf2.Path): path where the generator should be added
460  minangle (float): minimum angle of the outgoing electron/positron in the CMS in degrees
461  """
462 
463  if minangle < 0.0 or minangle > 180.0:
464  B2FATAL("add_bhwide_generator minimum angle too small (<0.0) or too large (>180): {}".format(minangle))
465 
466  bhwide = path.add_module("BHWideInput")
467  bhwide.param('ScatteringAngleRangePositron', [minangle, 180.0 - minangle])
468  bhwide.param('ScatteringAngleRangeElectron', [minangle, 180.0 - minangle])
469  bhwide.param('MaxAcollinearity', 180.0)
470  bhwide.param('MinEnergy', 0.10)
471  bhwide.param('VacuumPolarization', 'burkhardt')
472  bhwide.param('WeakCorrections', True)
473  bhwide.param('WtMax', 3.0)
474 
475 
476 def add_babayaganlo_generator(path, finalstate='', minenergy=0.01, minangle=10.0, fmax=-1.0, generateInECLAcceptance=False):
477  '''
478  Add the high precision QED generator BabaYaga@NLO to the path.
479 
480  Parameters:
481  path (basf2.Path): path where the generator should be added.
482  finalstate (str): ee (e+e-) or gg (gammagamma).
483  minenergy (float): minimum particle (leptons for 'ee', photons for 'gg') energy in GeV.
484  minangle (float): angular range from minangle to 180-minangle for primary particles (in degrees).
485  fmax (float): maximum of differential cross section weight. This parameter should be set only by experts.
486  generateInECLAcceptance (bool): if True, the GeneratorPreselection module is used to select only events
487  with both the primary particles within the ECL acceptance.
488  '''
489 
490  babayaganlo = path.add_module('BabayagaNLOInput')
491 
492  if not (fmax == -1.0):
493  B2WARNING(f'The BabayagaNLOInput parameter "FMax" will be set to {fmax} instead to the default value (-1.0). '
494  'Please do not do this, unless you are extremely sure about this choice.')
495 
496  if finalstate == 'ee':
497  babayaganlo.param('FinalState', 'ee')
498  babayaganlo.param('ScatteringAngleRange', [minangle, 180.0 - minangle])
499  babayaganlo.param('MinEnergy', minenergy)
500  babayaganlo.param('FMax', fmax)
501 
502  elif finalstate == 'gg':
503  babayaganlo.param('FinalState', 'gg')
504  babayaganlo.param('ScatteringAngleRange', [minangle, 180.0 - minangle])
505  babayaganlo.param('MinEnergy', minenergy)
506  babayaganlo.param('FMax', fmax)
507 
508  else:
509  B2FATAL(f'add_babayaganlo_generator final state not supported: {finalstate}')
510 
511  if generateInECLAcceptance:
512  B2INFO(f'The final state {finalstate} is preselected requiring both primary particles within the ECL acceptance.')
513  emptypath = Path()
514  add_generator_preselection(path=path,
515  emptypath=emptypath,
516  applyInCMS=False)
517  if finalstate == 'ee':
518  set_module_parameters(path=path,
519  name='GeneratorPreselection',
520  nChargedMin=2,
521  MinChargedTheta=12.4,
522  MaxChargedTheta=155.1,)
523  elif finalstate == 'gg':
524  set_module_parameters(path=path,
525  name='GeneratorPreselection',
526  nPhotonMin=2,
527  MinPhotonTheta=12.4,
528  MaxPhotonTheta=155.1)
529 
530 
531 def add_phokhara_generator(path, finalstate=''):
532  """
533  Add the high precision QED generator PHOKHARA to the path. Almost full
534  acceptance settings for photons and hadrons/muons.
535 
536  Parameters:
537  path (basf2.Path): path where the generator should be added
538  finalstate (str): One of the possible final state "mu+mu-", "pi+pi-", "pi+pi-pi0"
539  """
540 
541  phokhara = path.add_module('PhokharaInput')
542 
543  if finalstate == 'mu+mu-':
544  phokhara.param('FinalState', 0)
545  phokhara.param('LO', 0) # force ISR production, no non-radiative production
546  phokhara.param('NLO', 1) # use full two loop corrections
547  phokhara.param('QED', 0) # use ISR only, no FSR, no interference
548 
549  elif finalstate == 'pi+pi-':
550  phokhara.param('FinalState', 1)
551  phokhara.param('LO', 0) # force ISR production, no non-radiative production
552  phokhara.param('NLO', 1) # use full two loop corrections
553  phokhara.param('QED', 0) # use ISR only, no FSR, no interference
554 
555  elif finalstate == 'pi+pi-pi0':
556  phokhara.param('FinalState', 8)
557  phokhara.param('LO', 0) # force ISR production, no non-radiative production
558  phokhara.param('NLO', 0) # no two loop corrections
559  phokhara.param('QED', 0) # use ISR only, no FSR, no interference
560  else:
561  B2FATAL("add_phokhara_generator final state not supported: {}".format(finalstate))
562 
563 
565  path, final_state_particles, user_decay_file,
566  beam_energy_spread=True):
567  """
568  Add combination of PHOKHARA and EvtGen to the path. Phokhara is
569  acting as ISR generator by generating e+ e- -> mu+ mu-, the muon pair is
570  then replaced by a virtual photon. Finally, the virtual photon is
571  decayed by EvtGen.
572 
573  Parameters:
574  path (basf2.Path): Path where the generator should be added.
575  final_state_particles (list): List of final-state particles of
576  the virtual-photon decay. It is necessary to define the correct
577  mass threshold in PHOKHARA. For example, for the process
578  e+ e- -> J/psi eta_c, the list should be ['J/psi', 'eta_c'];
579  it does not depend on subsequent J/psi or eta_c decays.
580  user_decay_file (str): Name of EvtGen user decay file. The initial
581  particle must be the virtual photon (vpho).
582  """
583 
584  import pdg
585 
586  phokhara = path.add_module('PhokharaInput')
587 
588  # Generate muons and replace them by a virtual photon.
589  phokhara.param('FinalState', 0)
590  phokhara.param('ReplaceMuonsByVirtualPhoton', True)
591 
592  # Simulate beam-energy spread. This performs initialization for every
593  # event, and, thus, very slow, but usually necessary except for testing.
594  phokhara.param('BeamEnergySpread', beam_energy_spread)
595 
596  # Soft photon cutoff.
597  phokhara.param('Epsilon', 0.0001)
598 
599  # Maximum search.
600  phokhara.param('SearchMax', 5000)
601 
602  # Number of generation attempts for event.
603  phokhara.param('nMaxTrials', 25000)
604 
605  # Use NNLO.
606  phokhara.param('LO', 1)
607  phokhara.param('NLO', 1)
608 
609  # Use ISR only.
610  phokhara.param('QED', 0)
611 
612  # No interference.
613  phokhara.param('NLOIFI', 0)
614 
615  # Vacuum polarization by Fred Jegerlehner.
616  phokhara.param('Alpha', 1)
617 
618  # Do not include narrow resonances.
619  phokhara.param('NarrowRes', 0)
620 
621  # Angular ragnes.
622  phokhara.param('ScatteringAngleRangePhoton', [0., 180.])
623  phokhara.param('ScatteringAngleRangeFinalStates', [0., 180.])
624 
625  # Minimal invariant mass of the muons and tagged photon combination.
626  phokhara.param('MinInvMassHadronsGamma', 0.)
627 
628  # Minimal squared invariant mass of muons (final state).
629  # Force application of this cut.
630  mass = 0
631  for particle in final_state_particles:
632  p = pdg.get(particle)
633  mass = mass + p.Mass()
634  phokhara.param('MinInvMassHadrons', mass * mass)
635  phokhara.param('ForceMinInvMassHadronsCut', True)
636 
637  # Maximal squared invariant mass of muons (final state) (st to lagre
638  phokhara.param('MaxInvMassHadrons', 200.0)
639 
640  # Minimal photon energy.
641  phokhara.param('MinEnergyGamma', 0.01)
642 
643  # EvtGen.
644  evtgen_decay = path.add_module('EvtGenDecay')
645  evtgen_decay.param('UserDecFile', user_decay_file)
646 
647 
648 def add_koralw_generator(path, finalstate='', enableTauDecays=True):
649  """
650  Add KoralW generator for radiative four fermion final states (only four leptons final states are currently supported).
651 
652  Parameters:
653  path (basf2.Path): path where the generator should be added
654  finalstate (str): either 'e+e-e+e-', 'e+e-mu+mu-', 'e+e-tau+tau-', 'mu+mu-mu+mu-', 'mu+mu-tau+tau-' or 'tau+tau-tau+tau-'
655  enableTauDecays (bool): if True, allow tau leptons to decay (using EvtGen)
656  """
657 
658  decayFile = ''
659  if finalstate == 'e+e-e+e-':
660  decayFile = Belle2.FileSystem.findFile('data/generators/koralw/KoralW_eeee.data')
661  elif finalstate == 'e+e-mu+mu-':
662  decayFile = Belle2.FileSystem.findFile('data/generators/koralw/KoralW_eeMuMu.data')
663  elif finalstate == 'e+e-tau+tau-':
664  decayFile = Belle2.FileSystem.findFile('data/generators/koralw/KoralW_eeTauTau.data')
665  elif finalstate == 'mu+mu-mu+mu-':
666  decayFile = Belle2.FileSystem.findFile('data/generators/koralw/KoralW_MuMuMuMu.data')
667  elif finalstate == 'mu+mu-tau+tau-':
668  decayFile = Belle2.FileSystem.findFile('data/generators/koralw/KoralW_MuMuTauTau.data')
669  elif finalstate == 'tau+tau-tau+tau-':
670  decayFile = Belle2.FileSystem.findFile('data/generators/koralw/KoralW_TauTauTauTau.data')
671  else:
672  B2FATAL(f'add_koralw_generator final state not supported: {finalstate}')
673 
674  path.add_module('KoralWInput',
675  UserDataFile=decayFile)
676 
677  if 'tau+tau-' in finalstate:
678  if enableTauDecays:
679  path.add_module('EvtGenDecay')
680  else:
681  B2WARNING('The tau decays will not be generated.')
682 
683 
684 def add_cosmics_generator(path, components=None,
685  global_box_size=None, accept_box=None, keep_box=None,
686  geometry_xml_file='geometry/Beast2_phase2.xml',
687  cosmics_data_dir='data/generators/modules/cryinput/',
688  setup_file='generators/scripts/cry.setup',
689  data_taking_period='gcr2017', top_in_counter=False):
690  """
691  Add the cosmics generator CRY with the default parameters to the path.
692 
693  Warning:
694  Please remember to also change the reconstruction accordingly, if you
695  set "special" parameters here!
696 
697  Parameters:
698  path (basf2.Path): path where the generator should be added
699  components (list(str)): list of geometry components to add in the
700  geometry module, or None for all components.
701  global_box_size (tuple(float, float, float)): sets global length, width
702  and height (in meters) in which to generate.
703  Default is ``[100, 100, 100]``
704  accept_box (tuple(float, float, float)): sets the size of the accept box in meter.
705  As a default it is set to ``[8.0, 8.0, 8.0]`` (the Belle II detector size).
706  keep_box (tuple(float, float, float)): sets the size of the keep box (keep box >= accept box).
707  geometry_xml_file (str): Name of the xml file to use for the geometry.
708  cosmics_data_dir (str): parameter CosmicDataDir for the cry module (absolute or relative to the basf2 repo).
709  setup_file (str): location of the cry.setup file (absolute or relative to the basf2 repo)
710  data_taking_period (str): The cosmics generation will be added using the
711  parameters, that where used in this period of data taking. The
712  periods can be found in ``cdc/cr/__init__.py``.
713  top_in_counter (bool): time of propagation from the hit point to the PMT in the trigger counter is subtracted
714  (assuming PMT is put at -z of the counter).
715  """
716 
717  B2FATAL('''The function "add_cosmics_generator()" is outdated and it is currently not working: please replace
718 
719  add_cosmics_generator(path=path)
720 
721 with
722 
723  path.add_module('CRYInput')
724 
725 in your steering file (the module parameter "acceptance" has to be set, see the module docummentation).''')
726 
727  import cdc.cr as cosmics_setup
728 
729  if global_box_size is None:
730  global_box_size = [100, 100, 100]
731  if accept_box is None:
732  accept_box = [8, 8, 8]
733  if keep_box is None:
734  keep_box = [8, 8, 8]
735 
736  cosmics_setup.set_cdc_cr_parameters(data_taking_period)
737 
738  if cosmics_setup.cosmics_period == "201607":
739  B2FATAL("The data taking period 201607 is very special (geometry setup, PMTs etc). This is not handled "
740  "by this script! Please ask the CDC group, if you want to simulate this.")
741 
742  if 'Gearbox' not in path:
743  override = [("/Global/length", str(global_box_size[0]), "m"),
744  ("/Global/width", str(global_box_size[1]), "m"),
745  ("/Global/height", str(global_box_size[2]), "m")]
746 
747  if cosmics_setup.globalPhi:
748  override += [("/DetectorComponent[@name='CDC']//GlobalPhiRotation", str(cosmics_setup.globalPhi), "deg")]
749 
750  path.add_module('Gearbox', override=override, fileName=geometry_xml_file,)
751 
752  # detector geometry
753  if 'Geometry' not in path:
754  geometry = path.add_module('Geometry')
755  if components:
756  geometry.param('components', components)
757 
758  cry = path.add_module('CRYInput')
759 
760  # cosmic data input
761  cry.param('CosmicDataDir', Belle2.FileSystem.findFile(cosmics_data_dir))
762 
763  # user input file
764  cry.param('SetupFile', Belle2.FileSystem.findFile(setup_file))
765 
766  # acceptance half-lengths - at least one particle has to enter that box to use that event
767  cry.param('acceptLength', accept_box[0])
768  cry.param('acceptWidth', accept_box[1])
769  cry.param('acceptHeight', accept_box[2])
770  cry.param('maxTrials', 100000)
771 
772  # keep half-lengths - all particles that do not enter the box are removed (keep box >= accept box)
773  # default was 6.0
774  cry.param('keepLength', keep_box[0])
775  cry.param('keepWidth', keep_box[1])
776  cry.param('keepHeight', keep_box[2])
777 
778  # minimal kinetic energy - all particles below that energy are ignored
779  cry.param('kineticEnergyThreshold', 0.01)
780 
781  # TODO: I still do not fully understand, when the cosmics selector is needed and when not
782  if cosmics_setup.cosmics_period not in ["normal", "gcr2017"]:
783  # Selector module.
784  cosmics_selector = register_module('CDCCosmicSelector',
785  lOfCounter=cosmics_setup.lengthOfCounter,
786  wOfCounter=cosmics_setup.widthOfCounter,
787  xOfCounter=cosmics_setup.triggerPos[0],
788  yOfCounter=cosmics_setup.triggerPos[1],
789  zOfCounter=cosmics_setup.triggerPos[2],
790  phiOfCounter=0.,
791  TOP=top_in_counter,
792  propSpeed=cosmics_setup.lightPropSpeed,
793  TOF=1,
794  cryGenerator=True
795  )
796 
797  path.add_module(cosmics_selector)
798 
799  empty_path = create_path()
800  cosmics_selector.if_false(empty_path)
801 
802 
803 def add_treps_generator(path, finalstate='', useDiscreteAndSortedW=False):
804  """
805  Add TREPS generator to produce hadronic two-photon processes.
806 
807  Parameters:
808  path (basf2.Path): path where the generator should be added
809  finalstate(str): "e+e-pi+pi-", "e+e-K+K-" or "e+e-ppbar"
810  useDiscreteAndSortedW(bool): if True, wListTableFile is used for discrete and sorted W. evtNumList must be set proper value.
811  """
812 
813  if finalstate == 'e+e-pi+pi-':
814  parameterFile = Belle2.FileSystem.findFile('generators/treps/data/parameterFiles/treps_par_pipi.dat')
815  differentialCrossSectionFile = Belle2.FileSystem.findFile('generators/treps/data/differentialCrossSectionFiles/pipidcs.dat')
816  wListTableFile = Belle2.FileSystem.findFile('generators/treps/data/wListFiles/wlist_table_pipi.dat')
817  elif finalstate == 'e+e-K+K-':
818  parameterFile = Belle2.FileSystem.findFile('generators/treps/data/parameterFiles/treps_par_kk.dat')
819  differentialCrossSectionFile = Belle2.FileSystem.findFile('generators/treps/data/differentialCrossSectionFiles/kkdcs.dat')
820  wListTableFile = Belle2.FileSystem.findFile('generators/treps/data/wListFiles/wlist_table_kk.dat')
821  elif finalstate == 'e+e-ppbar':
822  parameterFile = Belle2.FileSystem.findFile('generators/treps/data/parameterFiles/treps_par_ppbar.dat')
823  differentialCrossSectionFile = Belle2.FileSystem.findFile(
824  'generators/treps/data/differentialCrossSectionFiles/ppbardcs.dat')
825  wListTableFile = Belle2.FileSystem.findFile('generators/treps/data/wListFiles/wlist_table_ppbar.dat')
826  else:
827  B2FATAL("add_treps_generator final state not supported: {}".format(finalstate))
828 
829  # use TREPS to generate two-photon events.
830  trepsinput = path.add_module(
831  'TrepsInput',
832  ParameterFile=parameterFile,
833  DifferentialCrossSectionFile=differentialCrossSectionFile,
834  WListTableFile=wListTableFile,
835  UseDiscreteAndSortedW=useDiscreteAndSortedW,
836  MaximalQ2=1.0,
837  MaximalAbsCosTheta=1.01,
838  ApplyCosThetaCutCharged=True,
839  MinimalTransverseMomentum=0,
840  ApplyTransverseMomentumCutCharged=True,
841  )
generators.add_generator_preselection
def add_generator_preselection(path, emptypath, nChargedMin=0, nChargedMax=999, MinChargedP=-1.0, MinChargedPt=-1.0, MinChargedTheta=0.0, MaxChargedTheta=180.0, nPhotonMin=0, nPhotonMax=999, MinPhotonEnergy=-1, MinPhotonTheta=0.0, MaxPhotonTheta=180.0, applyInCMS=False, stableParticles=False)
Definition: generators.py:22
generators.add_inclusive_continuum_generator
def add_inclusive_continuum_generator(path, finalstate, particles, userdecfile='', *include_conjugates=True, max_iterations=100000)
Definition: generators.py:411
pdg.get
def get(name)
Definition: pdg.py:35
generators.add_bhwide_generator
def add_bhwide_generator(path, minangle=0.5)
Definition: generators.py:453
generators.add_phokhara_evtgen_combination
def add_phokhara_evtgen_combination(path, final_state_particles, user_decay_file, beam_energy_spread=True)
Definition: generators.py:564
generators.add_evtgen_generator
def add_evtgen_generator(path, finalstate='', signaldecfile=None, coherentMixing=True, parentParticle='Upsilon(4S)')
Definition: generators.py:263
generators.add_phokhara_generator
def add_phokhara_generator(path, finalstate='')
Definition: generators.py:531
generators.get_default_decayfile
def get_default_decayfile()
Definition: generators.py:17
pdg.load
def load(filename)
Definition: pdg.py:109
cr
generators.add_koralw_generator
def add_koralw_generator(path, finalstate='', enableTauDecays=True)
Definition: generators.py:648
generators.add_babayaganlo_generator
def add_babayaganlo_generator(path, finalstate='', minenergy=0.01, minangle=10.0, fmax=-1.0, generateInECLAcceptance=False)
Definition: generators.py:476
generators.add_treps_generator
def add_treps_generator(path, finalstate='', useDiscreteAndSortedW=False)
Definition: generators.py:803
generators.add_kkmc_generator
def add_kkmc_generator(path, finalstate='', signalconfigfile='', useTauolaBelle=False, tauinputfile='')
Definition: generators.py:192
Belle2::FileSystem::findFile
static std::string findFile(const std::string &path, bool silent=false)
Search for given file or directory in local or central release directory, and return absolute path if...
Definition: FileSystem.cc:147
generators.add_continuum_generator
def add_continuum_generator(path, finalstate, userdecfile='', *skip_on_failure=True)
Definition: generators.py:331
generators.add_aafh_generator
def add_aafh_generator(path, finalstate='', preselection=False, enableTauDecays=True, minmass=0.5, subweights=[], maxsubweight=1, maxfinalweight=3.0)
Definition: generators.py:84
generators.add_cosmics_generator
def add_cosmics_generator(path, components=None, global_box_size=None, accept_box=None, keep_box=None, geometry_xml_file='geometry/Beast2_phase2.xml', cosmics_data_dir='data/generators/modules/cryinput/', setup_file='generators/scripts/cry.setup', data_taking_period='gcr2017', top_in_counter=False)
Definition: generators.py:684