Belle II Software development
utils.py
1
8from .constants import EventCode, EventCode_CrossSection, EventCodes
9
10from basf2 import B2FATAL, Module
11from generators import add_aafh_generator, add_koralw_generator, add_phokhara_generator, add_treps_generator
12
13
14def add_low_multiplicity_generator(path, event_code):
15 """
16 Add dedicated generator based on EventCode.
17 Module name is also changed to avoid conflicts
18
19 Parameters:
20 path (basf2.Path): path where generators should be added
21 event_code (EventCode): EventCode integer to identify a channel
22 """
23
24 if event_code not in EventCodes:
25 B2FATAL(f'The event code {event_code} is unknown.')
26 if event_code is EventCode.eetautau:
27 add_aafh_generator(path, 'e+e-tau+tau-', enableTauDecays=False, eventType='eetautau')
28 rename_module_in_path(path, 'AafhInput', 'AAFH_eetautau')
29 elif event_code is EventCode.mumumumu:
30 add_aafh_generator(path, 'mu+mu-mu+mu-', eventType='mumumumu')
31 rename_module_in_path(path, 'AafhInput', 'AAFH_mumumumu')
32 elif event_code is EventCode.mumutautau:
33 add_aafh_generator(path, 'mu+mu-tau+tau-', enableTauDecays=False, eventType='mumutautau')
34 rename_module_in_path(path, 'AafhInput', 'AAFH_mumutautau')
35 elif event_code is EventCode.tautautautau:
36 add_koralw_generator(path, 'tau+tau-tau+tau-', enableTauDecays=False, eventType='tautautautau')
37 rename_module_in_path(path, 'KoralWInput', 'KoralW_tautautautau')
38 elif event_code is EventCode.eepipi:
39 add_treps_generator(path, 'e+e-pi+pi-', eventType='eepipi')
40 rename_module_in_path(path, 'TrepsInput', 'TREPS_eepipi')
41 elif event_code is EventCode.eeKK:
42 add_treps_generator(path, 'e+e-K+K-', eventType='eeKK')
43 rename_module_in_path(path, 'TrepsInput', 'TREPS_eeKK')
44 elif event_code is EventCode.eepp:
45 add_treps_generator(path, 'e+e-ppbar', eventType='eeppbar')
46 rename_module_in_path(path, 'TrepsInput', 'TREPS_eepp')
47 elif event_code is EventCode.pipiISR:
48 add_phokhara_generator(path, 'pi+pi-', eventType='pipiISR')
49 elif event_code is EventCode.pipipi0ISR:
50 add_phokhara_generator(path, 'pi+pi-pi0', eventType='pipipi0ISR')
51 elif event_code is EventCode.pipipipiISR:
52 add_phokhara_generator(path, 'pi+pi-pi+pi-', eventType='pipipipiISR')
53 elif event_code is EventCode.pipipi0pi0ISR:
54 add_phokhara_generator(path, 'pi+pi-pi0pi0', eventType='pipipi0pi0ISR')
55 elif event_code is EventCode.pipietaISR:
56 add_phokhara_generator(path, 'pi+pi-eta', eventType='pipietaISR')
57 elif event_code is EventCode.KKISR:
58 add_phokhara_generator(path, 'K+K-', eventType='KKISR')
59 elif event_code is EventCode.K0K0barISR:
60 add_phokhara_generator(path, 'K0K0bar', eventType='K0K0barISR')
61 elif event_code is EventCode.ppbarISR:
62 add_phokhara_generator(path, 'ppbar', eventType='ppbarISR')
63
64
65def get_event_ranges(events, event_codes=None):
66 """
67 Get event range for channels to be generated. The number of events of each channel is determined by:
68 channel cross-section / total cross-section of all channels assigned to the same basf2 job.
69
70 Parameters:
71 events (int): Total number of events
72 event_codes (Iterable): tuple or list of EventCode.
73 Return:
74 a dictionary with EvenCode as the key and tuple of event range as value.
75 """
76 total_cross_section = sum(EventCode_CrossSection[e] for e in event_codes)
77 lower_range_delimiter = 0
78 return_dict = {}
79 for e in event_codes:
80 weight = EventCode_CrossSection[e] / total_cross_section
81 # Check if this is the last event code: in case, close the range and return.
82 if e == event_codes[len(event_codes) - 1]:
83 return_dict[e] = (lower_range_delimiter, events + 1)
84 return return_dict
85 events_in_range = round(events * weight)
86 return_dict[e] = (lower_range_delimiter, lower_range_delimiter + events_in_range)
87 lower_range_delimiter += events_in_range
88
89
90def rename_module_in_path(path, module_type, new_module_name):
91 """
92 Helper function to rename a module named with its type.
93 Parameters:
94 path (basf2.Path): path where a module to be renamed
95 module_type (str): default module name which is also module.type()
96 new_module_name (str): new module name
97 """
98 for module in path.modules():
99 if module.type() == module_type:
100 module.set_name(new_module_name)
101
102
104 """
105 Module to set ``eventExtraInfo(EventCode)`` according to event range
106 of each channel.
107
108 Parameters:
109 event_codes (Iterable): tuple or list of EventCode.
110 """
111
112 def __init__(self, event_codes):
113 """
114 Initialize the class
115 Parameters:
116 event_codes (Iterable): tuple or list of EventCode.
117 """
118 import ROOT # noqa
119 super().__init__()
120
121 self.event_codes = event_codes
122
123 self.event_extra_info = ROOT.Belle2.PyStoreObj('EventExtraInfo')
124
125 self.event_ranges = None
126
127 self.event_number = -1
128
129 def initialize(self):
130 """
131 Initialize module before any events are processed
132 """
133 import ROOT # noqa
134 self.event_ranges = get_event_ranges(ROOT.Belle2.Environment.Instance().getNumberOfEvents(), self.event_codes)
135 self.event_extra_info.registerInDataStore()
136
137 def beginRun(self):
138 """Begin run method of the module"""
139 self.event_number = -1
140
141 def event(self):
142 """Event method of the module"""
143 self.event_number += 1
144 if not self.event_extra_info.isValid():
145 self.event_extra_info.create()
146 elif self.event_extra_info.hasExtraInfo('EventCode'):
147 B2FATAL('The EventExtraInfo object has already an EventCode field registered.')
148 for event_code, event_range in self.event_ranges.items():
149 if (event_range[0] <= self.event_number < event_range[1]):
150 self.event_extra_info.setExtraInfo('EventCode', event_code.value)
151 self.return_value(event_code.value)
152 return
153 # This should never happen.
154 self.return_value(0)
155
156
158 """
159 Helper module to return True if the value from ``eventExtraInfo(EventCode)``
160 is included in the event_codes parameter.
161
162 Parameters:
163 event_codes (Iterable): tuple or list of EventCode.
164 """
165
166 def __init__(self, event_codes):
167 """
168 Initialize the class
169 Parameters:
170 event_codes (Iterable): tuple or list of EventCode.
171 """
172 import ROOT # noqa
173 super().__init__()
174
175 self.event_codes = [e.value for e in event_codes]
176
177 self.event_extra_info = ROOT.Belle2.PyStoreObj('EventExtraInfo')
178
179 def initialize(self):
180 """
181 Initialize module before any events are processed
182 """
183 self.event_extra_info.isRequired()
184
185 def event(self):
186 """Event method of the module"""
187 if not self.event_extra_info.hasExtraInfo('EventCode'):
188 B2FATAL('The EventExtraInfo object has no EventCode field registered.')
189 if self.event_extra_info.getExtraInfo('EventCode') in self.event_codes:
190 self.return_value(1)
191 else:
192 self.return_value(0)
event_ranges
Dictionary to get number of events for each event code.
Definition: utils.py:125
event_extra_info
PyStoreObj off EventExtraInfo.
Definition: utils.py:123
event_extra_info
PyStoreObj for EventExtraInfo to save event codes.
Definition: utils.py:177