Belle II Software  light-2212-foldex
ksSelector.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 
11 
12 from basf2 import B2INFO, B2ERROR
13 import basf2_mva
14 import modularAnalysis as ma
15 import variables
16 from variables import utils
17 
18 
19 def add_default_ks_Selector_aliases():
20  """
21  This function is used to set up variables aliases for ks Selector variables.
22  """
23  B2INFO('KsSelector: creating variables alias.')
24  variables.variables.addAlias('M_lambda_p', 'useAlternativeDaughterHypothesis(M, 0:p+)')
25  variables.variables.addAlias('M_lambda_antip', 'useAlternativeDaughterHypothesis(M, 1:anti-p-)')
26  variables.variables.addAlias('daughtersDeltaZ', 'daughterDiffOf(0, 1, dz)')
27  variables.variables.addAlias('cosVertexMomentum', 'cosAngleBetweenMomentumAndVertexVector')
28  variables.variables.addAlias('pip_nPXDHits', 'daughter(0,nPXDHits)')
29  variables.variables.addAlias('pin_nPXDHits', 'daughter(1,nPXDHits)')
30  variables.variables.addAlias('pip_nSVDHits', 'daughter(0,nSVDHits)')
31  variables.variables.addAlias('pin_nSVDHits', 'daughter(1,nSVDHits)')
32  variables.variables.addAlias('daughterAngleDiffInMother', 'useRestFrame(daughterAngle(0, 1))')
33  variables.variables.addAlias('pip_p', 'daughter(0,p)')
34  variables.variables.addAlias('pin_p', 'daughter(1,p)')
35  variables.variables.addAlias('pip_dr', 'daughter(0,dr)')
36  variables.variables.addAlias('pin_dr', 'daughter(1,dr)')
37  variables.variables.addAlias('pip_cosTheta', 'daughter(0,cosTheta)')
38  variables.variables.addAlias('pin_cosTheta', 'daughter(1,cosTheta)')
39  variables.variables.addAlias('pip_protonID', 'daughter(0,protonID)')
40  variables.variables.addAlias('pin_protonID', 'daughter(1,protonID)')
41 
42 
43 def add_variable_collection():
44  """
45  Call this function to add variable collection for ksSelector.
46  """
47  add_default_ks_Selector_aliases()
48  inputVariablesList = [
49  'cosVertexMomentum',
50  'flightDistance',
51  'significanceOfDistance',
52  'cosHelicityAngleMomentum',
53  'ImpactXY',
54  'decayAngle(0)',
55  'decayAngle(1)',
56  'daughterAngleDiffInMother',
57  'daughtersDeltaZ',
58  'pip_nSVDHits', 'pip_nPXDHits',
59  'pin_nSVDHits', 'pin_nPXDHits',
60  'pip_dr', 'pin_dr',
61  'pip_protonID', 'pin_protonID',
62  'M_lambda_p', 'M_lambda_antip',
63  'pip_p', 'pin_p',
64  'pip_cosTheta', 'pin_cosTheta',
65  ]
66  utils.add_collection(inputVariablesList, 'ks_selector_info')
67 
68 
69 def V0Selector_Training(
70  train_data,
71  tree_name="tree",
72  mva_identifier="MVAFastBDT_V0Selector.root",
73  target_variable="isSignal"
74 ):
75  """
76  Defines the configuration of V0Selector Training.
77  The training data should contain K_S0 and misreconstructed K_S0 without Lambda0.
78 
79  @param train_data Root file containing Ks information to be trained.
80  @param tree_name Tree name for variables.
81  @param mva_identifier Name for output MVA weight file.
82  @param target_variable Target variable for MVA training.
83  """
84  trainVars = [
85  'cosVertexMomentum',
86  'flightDistance',
87  'significanceOfDistance',
88  'cosHelicityAngleMomentum',
89  'ImpactXY',
90  'decayAngle(0)',
91  'decayAngle(1)',
92  'daughterAngleDiffInMother',
93  'daughtersDeltaZ',
94  'pip_nSVDHits', 'pip_nPXDHits',
95  'pin_nSVDHits', 'pin_nPXDHits',
96  'pip_dr', 'pin_dr',
97  ]
98 
99  general_options = basf2_mva.GeneralOptions()
100  general_options.m_datafiles = basf2_mva.vector(train_data)
101  general_options.m_treename = tree_name
102  general_options.m_identifier = mva_identifier
103  general_options.m_variables = basf2_mva.vector(*trainVars)
104  general_options.m_target_variable = target_variable
105  fastbdt_options = basf2_mva.FastBDTOptions()
106  basf2_mva.teacher(general_options, fastbdt_options)
107 
108 
109 def LambdaVeto_Training(
110  train_data,
111  tree_name="tree",
112  mva_identifier="MVAFastBDT_LambdaVeto.root",
113  target_variable="isSignal"
114 ):
115  """
116  Defines the configuration of LambdaVeto Training.
117  The training data should contain only K_S0 and Lambda0.
118 
119  @param train_data Root file containing Ks information to be trained.
120  @param tree_name Tree name for variables.
121  @param mva_identifier Name for output MVA weight file.
122  @param target_variable Target variable for MVA training.
123  """
124  trainVars = [
125  'pip_protonID',
126  'pin_protonID',
127  'M_lambda_p',
128  'M_lambda_antip',
129  'pip_p',
130  'pin_p',
131  'pip_cosTheta',
132  'pin_cosTheta',
133  ]
134  general_options = basf2_mva.GeneralOptions()
135  general_options.m_datafiles = basf2_mva.vector(train_data)
136  general_options.m_treename = tree_name
137  general_options.m_identifier = mva_identifier
138  general_options.m_variables = basf2_mva.vector(*trainVars)
139  general_options.m_target_variable = target_variable
140  fastbdt_options = basf2_mva.FastBDTOptions()
141  basf2_mva.teacher(general_options, fastbdt_options)
142 
143 # ****************************************
144 # KS Selector MAIN FUNCTION
145 # ****************************************
146 
147 
148 def ksSelector(
149  particleListName,
150  identifier_Ks,
151  identifier_vLambda,
152  output_label_name='',
153  extraInfoName_V0Selector='KsSelector_V0Selector',
154  extraInfoName_LambdaVeto='KsSelector_LambdaVeto',
155  useCustomThreshold=False,
156  threshold_V0Selector=0.90,
157  threshold_LambdaVeto=0.11,
158  path=None
159 ):
160  """
161  This function will apply K_S0 selection MVA on the given particleList.
162  By default this function appends MVA output as a extraInfo for the given particleList.
163  You can apply preset cut or custom cut by giving parameters. In this case,
164  a new particleList is created from the original particleList applying cuts on the MVA output.
165 
166  @param particleLists Reconstructed Ks -> pi+ pi- list.
167  @param output_label_name Label of the returned Ks particleList.
168  When empty '', no cut is applied and new particleList is not created.
169  When custom name, the custom threshold is used, and useCustomThreshold
170  must be True.
171  When 'standard', 'tight', or 'loose', a cut with Ks efficiency
172  90%, 95%, and 85% is applied.
173  @param extraInfoName_V0Selector Variable name for V0Selector MVA output.
174  @param extraInfoName_LambdaVeto Variable name for LambdaVeto MVA output.
175  @param identifier_Ks Identifier name for V0Selector weight file.
176  @param identifier_vLambda Identifier name for LambdaVeto weight file.
177  @param useCustomThreshold Flag whether threshold_V0Selector and threshold_LambdaVeto are used.
178  @param threshold_V0Selector Threshold for V0Selector.
179  @param threshold_LambdaVeto Threshold for LambdaVeto.
180  @param path Basf2 path to execute.
181 
182  """
183 
184  add_default_ks_Selector_aliases()
185 
186  path.add_module('MVAMultipleExperts',
187  listNames=[particleListName],
188  extraInfoNames=[extraInfoName_V0Selector, extraInfoName_LambdaVeto],
189  identifiers=[identifier_Ks, identifier_vLambda])
190 
191  _effnames = ['standard', 'tight', 'loose']
192  outputListName = ''
193 
194  if useCustomThreshold:
195  if output_label_name in _effnames:
196  B2ERROR('KsSelector: Specify label name except for \'standard\', \'tight\', and \'loose\' '
197  'when you use custom threshold.')
198  elif output_label_name == '':
199  B2ERROR('KsSelector: Specify label name when you use custom threshold.')
200  else:
201  outputListName = particleListName.split(':')[0] + ':' + output_label_name
202  B2INFO('KsSelector: Custom Cut is applied on '+outputListName+'.')
203  V0_thr = threshold_V0Selector
204  Lambda_thr = threshold_LambdaVeto
205  B2INFO('KsSelector: Threshold is (' + str(V0_thr) + ', ' + str(Lambda_thr) + ')')
206  cut_string = 'extraInfo('+extraInfoName_V0Selector+')>'+str(V0_thr) + \
207  ' and extraInfo('+extraInfoName_LambdaVeto+')>'+str(Lambda_thr)
208  ma.cutAndCopyLists(outputListName, particleListName, cut=cut_string, path=path)
209  else:
210  if output_label_name in _effnames:
211  outputListName = particleListName.split(':')[0] + ':' + output_label_name
212  V0_thr = 0
213  Lambda_thr = 0
214  if output_label_name == 'standard':
215  B2INFO('KsSelector: Standard Cut is applied on '+outputListName+'.')
216  V0_thr = 0.90
217  Lambda_thr = 0.11
218  elif output_label_name == 'tight':
219  B2INFO('KsSelector: Tight Cut is applied on '+outputListName+'.')
220  V0_thr = 0.96
221  Lambda_thr = 0.27
222  elif output_label_name == 'loose':
223  B2INFO('KsSelector: Loose Cut is applied on '+outputListName+'.')
224  V0_thr = 0.49
225  Lambda_thr = 0.02
226  B2INFO('KsSelector: Threshold is (' + str(V0_thr) + ', ' + str(Lambda_thr) + ')')
227  cut_string = 'extraInfo('+extraInfoName_V0Selector+')>'+str(V0_thr) + \
228  ' and extraInfo('+extraInfoName_LambdaVeto+')>'+str(Lambda_thr)
229  ma.cutAndCopyLists(outputListName, particleListName, cut=cut_string, path=path)
230  elif output_label_name == '':
231  outputListName = particleListName
232  else:
233  B2ERROR('KsSelector: Label should be \'\', \'standard\', \'tight\', or \'loose\' if you do'
234  'not apply custom threshold')
235 
236  B2INFO('KsSelector: ParticleList '+outputListName+' is returned.')