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