31 import modularAnalysis
as ma
32 import flavorTagger
as ft
33 from dft
import DeepFlavorTagger
37 from ROOT
import Belle2
42 def getCommandLineOptions():
43 """ Parses the command line options for the CPV validation and returns the corresponding arguments. """
45 parser = argparse.ArgumentParser(description=
'Script for the validation of CPV tools:\
46 it defines the procedure to sample the training set, train and test the flavor tagger\
47 as well as to reconstruct the vertices of B0-> J/psi K_S0 and of the tag-side B0\
48 using the tagV module.\n\
49 Usage: basf2 -i inputMDST.root flavorTaggerVertexingValidation.py -- -m Sampler -dc JPsiKs')
51 parser.add_argument(
'-bob2',
'--belleOrBelle2Flag', dest=
'belleOrBelle2Flag',
52 type=str, default=
'Belle2', choices=[
'Belle',
'Belle2'],
53 help=
'Choose Belle for converted Belle data or MC, otherwise choose Belle2.')
54 parser.add_argument(
'-m',
'--mode', dest=
'mode', type=str, required=
True,
55 choices=[
'Sampler',
'Teacher',
'Expert'],
56 help=
'Working mode of the flavor tagger. Choose Sampler, Teacher or Expert.')
57 parser.add_argument(
'-trc',
'--decayChannelTrainedOn', dest=
'decayChannelTrainedOn',
58 type=str, default=
'nunubar',
59 help=
'Decay channel of the weight files. Official samples available are JPsiKs or nunubar.')
60 parser.add_argument(
'-dc',
'--decayChannel', dest=
'decayChannel', type=str, required=
True,
61 choices=[
'JPsiKs',
'nunubar'], help=
'Decay channel that will be reconstructed. Choose JPsiKs or nunubar.')
62 parser.add_argument(
'-mct',
'--mcType', dest=
'mcType', type=str, default=
'BGx1',
63 choices=[
'BGx0',
'BGx1'], help=
'Type of files. Choose BGx0 for background free Belle II MC. \n' +
64 'Otherwise choose BGx1 for BelleII MC with bkg. or for converted Belle data or MC.')
65 parser.add_argument(
'-fn',
'--fileNumber', dest=
'fileNumber', type=str, default=
'',
66 help=
'A file number (when sampling in parallel).')
67 parser.add_argument(
'-wd',
'--workingDirectory', dest=
'workingDirectory', type=str, default=
'.',
68 help=
'Path where the training samples and the weight files are saved.')
69 parser.add_argument(
'-sd',
'--savingDirectory', dest=
'savingDirectory', type=str, default=
'.',
70 help=
'Path where the analyzed output files are saved.')
71 parser.add_argument(
'-dv',
'--doVertex', dest=
'doVertex', type=bool, default=
False,
72 help=
'Reconstruct B vertices True or False')
73 parser.add_argument(
'-bd',
'--belleData', dest=
'belleData', type=str, default=
'',
74 choices=[
'',
'BelleDataConv'], help=
'Choose BelleDataConv only for Belle Data in Expert mode.')
75 args = parser.parse_args()
77 if args.belleData ==
"BelleDataConv":
78 if args.belleOrBelle2Flag !=
"Belle":
79 b2.B2FATAL(
"BelleDataConv only for Belle Data.")
80 if args.mode !=
"Expert":
81 b2.B2FATAL(
"BelleDataConv only in Expert mode.")
82 if args.mcType !=
"BGx1":
83 b2.B2FATAL(
"When using BelleDataConv, mcType must be set to BGx1.")
88 def setEnvironment(belleOrBelle2Flag="Belle2"):
90 Sets the environment to analyse the mdst files for validation.'
92 @param belleOrBelle2Flag Default is 'Belle2' but 'Belle' is possible.
95 environmentType =
"default"
97 if belleOrBelle2Flag ==
"Belle":
99 from b2biiConversion
import convertBelleMdstToBelleIIMdst
101 os.environ[
'BELLE_POSTGRES_SERVER'] =
'can51'
102 os.environ[
'USE_GRAND_REPROCESS_DATA'] =
'1'
104 environmentType =
"Belle"
108 inputFileList.append(str(iFile))
110 convertBelleMdstToBelleIIMdst(inputBelleMDSTFile=inputFileList, path=cp_val_path)
113 ma.inputMdstList(environmentType=environmentType, filelist=[], path=cp_val_path)
116 def reconstructB2JpsiKs_mu(belleOrBelle2Flag='Belle2'):
118 Defines the reconstruction procedure for the benchmark channel 'B0 -> J/psi K_S0'
120 @param belleOrBelle2Flag Default is 'Belle2' but 'Belle' is possible.
124 ma.fillParticleList(decayString=
'mu+:all', cut=
'', path=cp_val_path)
125 ma.reconstructDecay(decayString=
'J/psi:mumu -> mu+:all mu-:all', cut=
'abs(dM) < 0.11', path=cp_val_path)
126 ma.matchMCTruth(list_name=
'J/psi:mumu', path=cp_val_path)
128 if belleOrBelle2Flag ==
"Belle":
131 ma.matchMCTruth(list_name=
'K_S0:mdst', path=cp_val_path)
134 ma.reconstructDecay(decayString=
'B0:sig -> J/psi:mumu K_S0:mdst', cut=
'Mbc > 5.2 and abs(deltaE) < 0.15', path=cp_val_path)
136 if belleOrBelle2Flag ==
"Belle2":
139 ma.fillParticleList(decayString=
'pi+:all', cut=
'', path=cp_val_path)
140 ma.reconstructDecay(decayString=
'K_S0:pipi -> pi+:all pi-:all', cut=
'abs(dM) < 0.25', path=cp_val_path)
143 ma.reconstructDecay(decayString=
'B0:sig -> J/psi:mumu K_S0:pipi', cut=
'Mbc > 5.2 and abs(deltaE) < 0.15', path=cp_val_path)
146 def reconstructB2nunubar():
148 Defines the procedure to create a B0 list for the benchmark channel 'B0 -> nu_tau anti-nu_tau'
151 ma.fillParticleListFromMC(
'nu_tau:MC',
'', path=cp_val_path)
152 ma.reconstructMCDecay(
'B0:sig -> nu_tau:MC anti-nu_tau:MC',
'', writeOut=
True, path=cp_val_path)
155 def mcMatchAndBuildROE(belleOrBelle2Flag='Belle2'):
157 Runs the mc matching and creates the rest of event for the signal particle list.'
159 @param belleOrBelle2Flag Default is 'Belle2' but 'Belle' is possible.
163 ma.matchMCTruth(list_name=
'B0:sig', path=cp_val_path)
166 ma.buildRestOfEvent(target_list_name=
'B0:sig', path=cp_val_path)
169 def applyCPVTools(mode='Expert'):
171 Defines the procedure to use the flavor tagger and tagV on the signal 'B0:sig' list.
172 It saves also all variables to nTuples needed for evaluation of the performance
174 @param mode Default is 'Expert' but also needed for 'Sampler' mode.
177 if mode ==
'Sampler':
180 particleLists=[
'B0:sig'],
182 weightFiles=
'B2' + decayChannelTrainedOn + mcType,
183 combinerMethods=[
'TMVA-FBDT',
'FANN-MLP'],
184 useOnlyLocalWeightFiles=
True,
185 downloadFromDatabaseIfNotFound=
False,
186 workingDirectory=workingDirectory,
187 samplerFileId=str(fileNumber),
193 particleLists=[
'B0:sig'],
194 combinerMethods=[
'TMVA-FBDT',
'FANN-MLP'],
195 weightFiles=
'B2' + decayChannelTrainedOn + mcType,
196 useOnlyLocalWeightFiles=
True,
197 downloadFromDatabaseIfNotFound=
False,
198 workingDirectory=workingDirectory,
199 samplerFileId=str(fileNumber),
205 dnnIdentifier =
"FlavorTagger_" + belleOrBelle2Flag +
"_B2nunubarBGx1OptimizedForDataDNN"
206 if belleOrBelle2Flag ==
"Belle":
207 dnnIdentifier =
"FlavorTagger_" + belleOrBelle2Flag +
"_B2nunubarBGx1DNN"
208 b2.conditions.append_globaltag(
"analysis_tools_release-04-00")
209 DeepFlavorTagger.DeepFlavorTagger(
'B0:sig',
212 uniqueIdentifier=dnnIdentifier,
215 if doVertex
or mode ==
'Expert':
218 if decayChannel ==
"JPsiKs":
221 vx.treeFit(list_name=
'B0:sig', conf_level=-2, path=cp_val_path)
222 vx.TagV(list_name=
'B0:sig', MCassociation=
'breco', path=cp_val_path)
223 print(
"TagV will be used")
226 fs_vars = vc.pid + vc.track + vc.track_hits + vc.mc_truth
227 jpsiandk0s_vars = vc.mc_truth
228 vertex_vars = vc.vertex + vc.mc_vertex + vc.kinematics + vc.mc_kinematics
229 bvars = vc.reco_stats + \
232 vc.roe_multiplicities + \
237 if decayChannel ==
"JPsiKs":
239 vu.create_aliases_for_selected(list_of_variables=fs_vars,
240 decay_string=
'B0 -> [J/psi -> ^mu+ ^mu-] [K_S0 -> ^pi+ ^pi-]') + \
241 vu.create_aliases_for_selected(list_of_variables=jpsiandk0s_vars,
242 decay_string=
'B0 -> [^J/psi -> mu+ mu-] [^K_S0 -> pi+ pi-]') + \
243 vu.create_aliases_for_selected(list_of_variables=vertex_vars,
244 decay_string=
'B0 -> [^J/psi -> ^mu+ ^mu-] [^K_S0 -> ^pi+ ^pi-]')
246 bvars += ft.flavor_tagging + [
'DNN_qrCombined',
'extraInfo(dnn_output)']
248 vu._variablemanager.addAlias(
'qrMC',
'isRelatedRestOfEventB0Flavor')
252 ma.variablesToNtuple(decayString=
'B0:sig',
254 filename=savingDirectory +
'/' +
'B2A801-FlavorTagger' +
255 mode + str(fileNumber) + belleOrBelle2Flag + mcType + belleData +
'.root',
259 ma.summaryOfLists(particleLists=[
'B0:sig'], path=cp_val_path)
262 if __name__ ==
'__main__':
264 args = getCommandLineOptions()
266 belleOrBelle2Flag = args.belleOrBelle2Flag
268 decayChannelTrainedOn = args.decayChannelTrainedOn
269 decayChannel = args.decayChannel
271 fileNumber = args.fileNumber
272 workingDirectory = args.workingDirectory
273 savingDirectory = args.savingDirectory
274 doVertex = args.doVertex
275 belleData = args.belleData
277 if decayChannelTrainedOn ==
'JPsiKs':
278 decayChannelTrainedOn =
'JpsiKs_mu'
280 cp_val_path = b2.Path()
282 if mode ==
"Sampler" or mode ==
"Expert":
284 setEnvironment(belleOrBelle2Flag=belleOrBelle2Flag)
286 if decayChannel ==
"nunubar":
287 reconstructB2nunubar()
289 elif decayChannel ==
"JPsiKs":
290 reconstructB2JpsiKs_mu(belleOrBelle2Flag=belleOrBelle2Flag)
292 mcMatchAndBuildROE(belleOrBelle2Flag=belleOrBelle2Flag)
293 applyCPVTools(mode=mode)
294 b2.process(cp_val_path)
297 if mode ==
"Teacher":
302 weightFiles=
'B2' + decayChannelTrainedOn + mcType,
303 combinerMethods=[
'TMVA-FBDT',
'FANN-MLP'],
304 useOnlyLocalWeightFiles=
True,
305 downloadFromDatabaseIfNotFound=
False,
306 uploadToDatabaseAfterTraining=
True,
307 workingDirectory=workingDirectory,
static Environment & Instance()
Static method to get a reference to the Environment instance.