31import modularAnalysis
as ma
32import flavorTagger
as ft
33from dft
import DeepFlavorTagger
37from ROOT
import Belle2
42def 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.")
88def setEnvironment(belleOrBelle2Flag="Belle2"):
90 Sets the environment to analyse the mdst files for validation.
'
91 @param belleOrBelle2Flag Default
is 'Belle2' but
'Belle' is possible.
94 environmentType = "default"
96 if belleOrBelle2Flag ==
"Belle":
98 from b2biiConversion
import convertBelleMdstToBelleIIMdst
100 os.environ[
'BELLE_POSTGRES_SERVER'] =
'can51'
101 os.environ[
'USE_GRAND_REPROCESS_DATA'] =
'1'
103 environmentType =
"Belle"
107 inputFileList.append(str(iFile))
109 convertBelleMdstToBelleIIMdst(inputBelleMDSTFile=inputFileList, path=cp_val_path)
112 ma.inputMdstList(environmentType=environmentType, filelist=[], path=cp_val_path)
115def reconstructB2JpsiKs_mu(belleOrBelle2Flag='Belle2'):
117 Defines the reconstruction procedure for the benchmark channel
'B0 -> J/psi K_S0'
119 @param belleOrBelle2Flag Default
is 'Belle2' but
'Belle' is possible.
123 ma.fillParticleList(decayString=
'mu+:all', cut=
'', path=cp_val_path)
124 ma.reconstructDecay(decayString=
'J/psi:mumu -> mu+:all mu-:all', cut=
'abs(dM) < 0.11', path=cp_val_path)
125 ma.matchMCTruth(list_name=
'J/psi:mumu', path=cp_val_path)
127 if belleOrBelle2Flag ==
"Belle":
130 ma.matchMCTruth(list_name=
'K_S0:mdst', path=cp_val_path)
133 ma.reconstructDecay(decayString=
'B0:sig -> J/psi:mumu K_S0:mdst', cut=
'Mbc > 5.2 and abs(deltaE) < 0.15', path=cp_val_path)
135 if belleOrBelle2Flag ==
"Belle2":
138 ma.fillParticleList(decayString=
'pi+:all', cut=
'', path=cp_val_path)
139 ma.reconstructDecay(decayString=
'K_S0:pipi -> pi+:all pi-:all', cut=
'abs(dM) < 0.25', path=cp_val_path)
142 ma.reconstructDecay(decayString=
'B0:sig -> J/psi:mumu K_S0:pipi', cut=
'Mbc > 5.2 and abs(deltaE) < 0.15', path=cp_val_path)
145def reconstructB2nunubar():
147 Defines the procedure to create a B0 list for the benchmark channel
'B0 -> nu_tau anti-nu_tau'
150 ma.fillParticleListFromMC('nu_tau:MC',
'', path=cp_val_path)
151 ma.reconstructMCDecay(
'B0:sig -> nu_tau:MC anti-nu_tau:MC',
'', writeOut=
True, path=cp_val_path)
154def mcMatchAndBuildROE(belleOrBelle2Flag='Belle2'):
156 Runs the mc matching and creates the rest of event
for the signal particle list.
'
158 @param belleOrBelle2Flag Default
is 'Belle2' but
'Belle' is possible.
162 ma.matchMCTruth(list_name=
'B0:sig', path=cp_val_path)
165 ma.buildRestOfEvent(target_list_name=
'B0:sig', path=cp_val_path)
168def applyCPVTools(mode='Expert'):
170 Defines the procedure to use the flavor tagger and tagV on the signal
'B0:sig' list.
171 It saves also all variables to nTuples needed
for evaluation of the performance
173 @param mode Default
is 'Expert' but also needed
for 'Sampler' mode.
176 if mode ==
'Sampler':
179 particleLists=[
'B0:sig'],
181 weightFiles=
'B2' + decayChannelTrainedOn + mcType,
182 combinerMethods=[
'TMVA-FBDT',
'FANN-MLP'],
183 useOnlyLocalWeightFiles=
True,
184 downloadFromDatabaseIfNotFound=
False,
185 workingDirectory=workingDirectory,
186 samplerFileId=str(fileNumber),
192 particleLists=[
'B0:sig'],
193 combinerMethods=[
'TMVA-FBDT',
'FANN-MLP'],
194 weightFiles=
'B2' + decayChannelTrainedOn + mcType,
195 useOnlyLocalWeightFiles=
True,
196 downloadFromDatabaseIfNotFound=
False,
197 workingDirectory=workingDirectory,
198 samplerFileId=str(fileNumber),
204 dnnIdentifier =
"FlavorTagger_" + belleOrBelle2Flag +
"_B2nunubarBGx1OptimizedForDataDNN"
205 if belleOrBelle2Flag ==
"Belle":
206 dnnIdentifier =
"FlavorTagger_" + belleOrBelle2Flag +
"_B2nunubarBGx1DNN"
207 b2.conditions.append_globaltag(
"analysis_tools_release-04-00")
208 DeepFlavorTagger.DeepFlavorTagger(
'B0:sig',
211 uniqueIdentifier=dnnIdentifier,
214 if doVertex
or mode ==
'Expert':
217 if decayChannel ==
"JPsiKs":
220 vx.treeFit(list_name=
'B0:sig', conf_level=-2, path=cp_val_path)
221 vx.TagV(list_name=
'B0:sig', MCassociation=
'breco', path=cp_val_path)
222 print(
"TagV will be used")
225 fs_vars = vc.pid + vc.track + vc.track_hits + vc.mc_truth
226 jpsiandk0s_vars = vc.mc_truth
227 vertex_vars = vc.vertex + vc.mc_vertex + vc.kinematics + vc.mc_kinematics
228 bvars = vc.reco_stats + \
231 vc.roe_multiplicities + \
236 if decayChannel ==
"JPsiKs":
238 vu.create_aliases_for_selected(list_of_variables=fs_vars,
239 decay_string=
'B0 -> [J/psi -> ^mu+ ^mu-] [K_S0 -> ^pi+ ^pi-]') + \
240 vu.create_aliases_for_selected(list_of_variables=jpsiandk0s_vars,
241 decay_string=
'B0 -> [^J/psi -> mu+ mu-] [^K_S0 -> pi+ pi-]') + \
242 vu.create_aliases_for_selected(list_of_variables=vertex_vars,
243 decay_string=
'B0 -> [^J/psi -> ^mu+ ^mu-] [^K_S0 -> ^pi+ ^pi-]')
245 bvars += ft.flavor_tagging + [
'DNN_qrCombined',
'extraInfo(dnn_output)']
247 vu._variablemanager.addAlias(
'qrMC',
'isRelatedRestOfEventB0Flavor')
251 ma.variablesToNtuple(decayString=
'B0:sig',
253 filename=savingDirectory +
'/' +
'B2A801-FlavorTagger' +
254 mode + str(fileNumber) + belleOrBelle2Flag + mcType + belleData +
'.root',
258 ma.summaryOfLists(particleLists=[
'B0:sig'], path=cp_val_path)
261if __name__ ==
'__main__':
263 args = getCommandLineOptions()
265 belleOrBelle2Flag = args.belleOrBelle2Flag
267 decayChannelTrainedOn = args.decayChannelTrainedOn
268 decayChannel = args.decayChannel
270 fileNumber = args.fileNumber
271 workingDirectory = args.workingDirectory
272 savingDirectory = args.savingDirectory
273 doVertex = args.doVertex
274 belleData = args.belleData
276 if decayChannelTrainedOn ==
'JPsiKs':
277 decayChannelTrainedOn =
'JpsiKs_mu'
279 cp_val_path = b2.Path()
281 if mode ==
"Sampler" or mode ==
"Expert":
283 setEnvironment(belleOrBelle2Flag=belleOrBelle2Flag)
285 if decayChannel ==
"nunubar":
286 reconstructB2nunubar()
288 elif decayChannel ==
"JPsiKs":
289 reconstructB2JpsiKs_mu(belleOrBelle2Flag=belleOrBelle2Flag)
291 mcMatchAndBuildROE(belleOrBelle2Flag=belleOrBelle2Flag)
292 applyCPVTools(mode=mode)
293 b2.process(cp_val_path)
296 if mode ==
"Teacher":
301 weightFiles=
'B2' + decayChannelTrainedOn + mcType,
302 combinerMethods=[
'TMVA-FBDT',
'FANN-MLP'],
303 useOnlyLocalWeightFiles=
True,
304 downloadFromDatabaseIfNotFound=
False,
305 uploadToDatabaseAfterTraining=
True,
306 workingDirectory=workingDirectory,
static Environment & Instance()
Static method to get a reference to the Environment instance.