10from basf2
import B2INFO, B2ERROR
12import modularAnalysis
as ma
14from variables
import utils
17def add_default_ks_Selector_aliases():
19 This function is used to set up variables aliases for ks Selector variables.
21 B2INFO(
'KsSelector: creating variables alias.')
22 variables.variables.addAlias(
'M_lambda_p',
'useAlternativeDaughterHypothesis(M, 0:p+)')
23 variables.variables.addAlias(
'M_lambda_antip',
'useAlternativeDaughterHypothesis(M, 1:anti-p-)')
24 variables.variables.addAlias(
'daughtersDeltaZ',
'daughterDiffOf(0, 1, dz)')
25 variables.variables.addAlias(
'cosVertexMomentum',
'cosAngleBetweenMomentumAndVertexVector')
26 variables.variables.addAlias(
'pip_nPXDHits',
'daughter(0,nPXDHits)')
27 variables.variables.addAlias(
'pin_nPXDHits',
'daughter(1,nPXDHits)')
28 variables.variables.addAlias(
'pip_nSVDHits',
'daughter(0,nSVDHits)')
29 variables.variables.addAlias(
'pin_nSVDHits',
'daughter(1,nSVDHits)')
30 variables.variables.addAlias(
'daughterAngleDiffInMother',
'useRestFrame(daughterAngle(0, 1))')
31 variables.variables.addAlias(
'pip_p',
'daughter(0,p)')
32 variables.variables.addAlias(
'pin_p',
'daughter(1,p)')
33 variables.variables.addAlias(
'pip_dr',
'daughter(0,dr)')
34 variables.variables.addAlias(
'pin_dr',
'daughter(1,dr)')
35 variables.variables.addAlias(
'pip_cosTheta',
'daughter(0,cosTheta)')
36 variables.variables.addAlias(
'pin_cosTheta',
'daughter(1,cosTheta)')
37 variables.variables.addAlias(
'pip_protonID',
'daughter(0,protonID)')
38 variables.variables.addAlias(
'pin_protonID',
'daughter(1,protonID)')
41def add_variable_collection():
43 Call this function to add variable collection for ksSelector.
45 add_default_ks_Selector_aliases()
46 inputVariablesList = [
49 'significanceOfDistance',
50 'cosHelicityAngleMomentum',
54 'daughterAngleDiffInMother',
56 'pip_nSVDHits',
'pip_nPXDHits',
57 'pin_nSVDHits',
'pin_nPXDHits',
59 'pip_protonID',
'pin_protonID',
60 'M_lambda_p',
'M_lambda_antip',
62 'pip_cosTheta',
'pin_cosTheta',
63 'ArmenterosLongitudinalMomentumAsymmetry',
64 'ArmenterosDaughter1Qt',
65 'ArmenterosDaughter2Qt'
67 utils.add_collection(inputVariablesList,
'ks_selector_info')
70def LightGBM2ONNX(dumping_file_name,
75 Convert trained LightGBM payload to onnx format. Only work for (binary or regression) loss
76 @param dumping_file_name file name for trained LightGBM payload
77 @param output_file_name file name for output onnx payload
78 @param input_variable_list model input variables list
86 with ROOT.TFile(dumping_file_name)
as f:
87 w = ROOT.Belle2.MVA.Weightfile.loadFromStream(ROOT.stringstream(f.Get(
"Weightfile").m_data))
89 with open(
"temp_scripts.py",
"w")
as f:
90 f.write(pickle.loads(base64.b64decode(w.getElement[
"std::string"](
"Python_Steeringfile")+
"====")))
92 w.getFile(
"Python_Weightfile",
"Python_Weightfile.pkl")
94 with open(
"temp_scripts.py")
as f:
95 exec(f.read(), basf2_mva_python_interface.lightgbm.__dict__)
97 with open(
"Python_Weightfile.pkl",
"rb")
as f:
102 from onnxmltools
import convert_lightgbm
103 from onnxmltools.convert.common.data_types
import FloatTensorType
105 num_features = len(input_variable_list)
106 initial_type = [(
'input', FloatTensorType([
None, num_features]))]
108 onnx_model = convert_lightgbm(model, initial_types=initial_type)
110 with open(
"temp_model.onnx",
"wb")
as f:
111 f.write(onnx_model.SerializeToString())
113 from basf2_mva_util
import create_onnx_mva_weightfile
114 weightfile = create_onnx_mva_weightfile(
116 variables=input_variable_list,
117 target_variable=
"isSignal",
120 os.remove(
"temp_model.onnx")
121 os.remove(
"Python_Weightfile.pkl")
122 os.remove(
"temp_scripts.py")
123 weightfile.save(output_file_name)
126def V0Selector_Training(
129 mva_identifier="MVAFastBDT_V0Selector.root",
130 target_variable="isSignal",
135 Defines the configuration of V0Selector Training.
136 The training data should contain K_S0 and misreconstructed K_S0 without Lambda0.
138 @param train_data Root file containing Ks information to be trained.
139 @param tree_name Tree name for variables.
140 @param mva_identifier Name for output MVA weight file.
141 @param target_variable Target variable for MVA training.
142 @param parameters hyperparameter for LGBM
143 @param options MVA options
148 'significanceOfDistance',
149 'cosHelicityAngleMomentum',
153 'daughterAngleDiffInMother',
155 'pip_nSVDHits',
'pin_nSVDHits',
159 general_options = basf2_mva.GeneralOptions()
160 general_options.m_datafiles = basf2_mva.vector(train_data)
161 general_options.m_treename = tree_name
162 general_options.m_identifier = mva_identifier
163 general_options.m_variables = basf2_mva.vector(*trainVars)
164 general_options.m_target_variable = target_variable
165 general_options.m_max_events = 0
if 'max_events' not in options
else options[
'max_events']
167 python_options = basf2_mva.PythonOptions()
168 python_options.m_framework =
"lightgbm"
171 param = {
'num_leaves': 256,
172 'learning_rate': 0.1,
173 'device_type':
"cpu",
174 'deterministic':
True,
178 'path': mva_identifier+
'.txt',
181 'trainFraction': 0.8,
182 'min_data_in_leaf': 4000,
184 'objective':
'cross_entropy',
187 if isinstance(parameters, dict):
188 param.update(parameters)
189 config_string = json.dumps(param)
190 print(
"The json config string", config_string)
191 python_options.m_config = config_string
193 python_options.m_training_fraction = 1
194 python_options.m_normalize =
False
195 python_options.m_nIterations = 1
196 python_options.m_mini_batch_size = 0
198 basf2_mva.teacher(general_options, python_options)
201def LambdaVeto_Training(
204 mva_identifier="MVAFastBDT_LambdaVeto.root",
205 target_variable="isSignal",
210 Defines the configuration of LambdaVeto Training.
211 The training data should contain only K_S0 and Lambda0.
213 @param train_data Root file containing Ks information to be trained.
214 @param tree_name Tree name for variables.
215 @param mva_identifier Name for output MVA weight file.
216 @param target_variable Target variable for MVA training.
217 @param parameters hyperparameter for LGBM
218 @param options MVA options
227 'ArmenterosLongitudinalMomentumAsymmetry',
228 'ArmenterosDaughter1Qt',
229 'ArmenterosDaughter2Qt'
232 general_options = basf2_mva.GeneralOptions()
233 general_options.m_datafiles = basf2_mva.vector(train_data)
234 general_options.m_treename = tree_name
235 general_options.m_identifier = mva_identifier
236 general_options.m_variables = basf2_mva.vector(*trainVars)
237 general_options.m_target_variable = target_variable
238 general_options.m_max_events = 0
if 'max_events' not in options
else options[
'max_events']
240 python_options = basf2_mva.PythonOptions()
241 python_options.m_framework =
"lightgbm"
244 param = {
'num_leaves': 256,
245 'learning_rate': 0.2,
246 'device_type':
"cpu",
247 'deterministic':
True,
251 'path': mva_identifier+
'.txt',
254 'trainFraction': 0.8,
255 'min_data_in_leaf': 300,
257 'objective':
'cross_entropy',
260 if isinstance(parameters, dict):
261 param.update(parameters)
262 config_string = json.dumps(param)
263 print(
"The json config string", config_string)
264 python_options.m_config = config_string
266 python_options.m_training_fraction = 1
267 python_options.m_normalize =
False
268 python_options.m_nIterations = 1
269 python_options.m_mini_batch_size = 0
271 basf2_mva.teacher(general_options, python_options)
280 identifier_Ks="Ks_LGBM_V0Selector_MC16",
281 identifier_vLambda="Ks_LGBM_LambdaVeto_MC16",
282 output_label_name='',
283 extraInfoName_V0Selector='KsSelector_V0Selector',
284 extraInfoName_LambdaVeto='KsSelector_LambdaVeto',
285 useCustomThreshold=False,
286 threshold_V0Selector=0.92,
287 threshold_LambdaVeto=0.11,
291 This function will apply K_S0 selection MVA on the given particleList.
292 By default this function appends MVA output as a extraInfo for the given particleList.
293 You can apply preset cut or custom cut by giving parameters. In this case,
294 a new particleList is created from the original particleList applying cuts on the MVA output.
296 @param particleLists Reconstructed Ks -> pi+ pi- list.
297 @param output_label_name Label of the returned Ks particleList.
298 When empty '', no cut is applied and new particleList is not created.
299 When custom name, the custom threshold is used, and useCustomThreshold
301 When 'standard', 'tight', or 'loose', a cut with Ks efficiency
302 90%, 95%, and 85% is applied.
303 @param extraInfoName_V0Selector Variable name for V0Selector MVA output.
304 @param extraInfoName_LambdaVeto Variable name for LambdaVeto MVA output.
305 @param identifier_Ks Identifier name for V0Selector weight file.
306 @param identifier_vLambda Identifier name for LambdaVeto weight file.
307 @param useCustomThreshold Flag whether threshold_V0Selector and threshold_LambdaVeto are used.
308 @param threshold_V0Selector Threshold for V0Selector.
309 @param threshold_LambdaVeto Threshold for LambdaVeto.
310 @param path Basf2 path to execute.
314 add_default_ks_Selector_aliases()
316 path.add_module(
'MVAMultipleExperts',
317 listNames=[particleListName],
318 extraInfoNames=[extraInfoName_V0Selector, extraInfoName_LambdaVeto],
319 identifiers=[identifier_Ks, identifier_vLambda])
321 _effnames = [
'standard',
'tight',
'loose']
324 if useCustomThreshold:
325 if output_label_name
in _effnames:
326 B2ERROR(
'KsSelector: Specify label name except for \'standard\', \'tight\', and \'loose\' '
327 'when you use custom threshold.')
328 elif output_label_name ==
'':
329 B2ERROR(
'KsSelector: Specify label name when you use custom threshold.')
331 outputListName = particleListName.split(
':')[0] +
':' + output_label_name
332 B2INFO(
'KsSelector: Custom Cut is applied on '+outputListName+
'.')
333 V0_thr = threshold_V0Selector
334 Lambda_thr = threshold_LambdaVeto
335 B2INFO(
'KsSelector: Threshold is (' + str(V0_thr) +
', ' + str(Lambda_thr) +
')')
336 cut_string =
'extraInfo('+extraInfoName_V0Selector+
')>'+str(V0_thr) + \
337 ' and extraInfo('+extraInfoName_LambdaVeto+
')>'+str(Lambda_thr)
338 ma.cutAndCopyLists(outputListName, particleListName, cut=cut_string, path=path)
340 if output_label_name
in _effnames:
341 outputListName = particleListName.split(
':')[0] +
':' + output_label_name
344 if output_label_name ==
'standard':
347 B2INFO(
'KsSelector: Standard Cut for MC16 is applied on '+outputListName+
'.')
349 elif output_label_name ==
'tight':
350 B2INFO(
'KsSelector: Tight Cut for MC16 is applied on '+outputListName+
'.')
354 elif output_label_name ==
'loose':
355 B2INFO(
'KsSelector: Loose Cut for MC 16 is applied on '+outputListName+
'.')
359 B2INFO(
'KsSelector: Threshold is (' + str(V0_thr) +
', ' + str(Lambda_thr) +
')')
360 cut_string =
'extraInfo('+extraInfoName_V0Selector+
')>'+str(V0_thr) + \
361 ' and extraInfo('+extraInfoName_LambdaVeto+
')>'+str(Lambda_thr)
362 ma.cutAndCopyLists(outputListName, particleListName, cut=cut_string, path=path)
363 elif output_label_name ==
'':
364 outputListName = particleListName
366 B2ERROR(
'KsSelector: Label should be \'\', \'standard\', \'tight\', or \'loose\' if you do'
367 'not apply custom threshold')
369 B2INFO(
'KsSelector: ParticleList '+outputListName+
' is returned.')