32 import modularAnalysis
as ma
33 import flavorTagger
as ft
34 from dft
import DeepFlavorTagger
38 from ROOT
import Belle2
43 def getCommandLineOptions():
44 """ Parses the command line options for the CPV validation and returns the corresponding arguments. """
46 parser = argparse.ArgumentParser(description=
'Script for the validation of CPV tools:\
47 it defines the procedure to sample the training set, train and test the flavor tagger\
48 as well as to reconstruct the vertices of B0-> J/psi K_S0 and of the tag-side B0\
49 using the tagV module.\n\
50 Usage: basf2 -i inputMDST.root flavorTaggerVertexingValidation.py -- -m Sampler -dc JPsiKs')
52 parser.add_argument(
'-bob2',
'--belleOrBelle2Flag', dest=
'belleOrBelle2Flag',
53 type=str, default=
'Belle2', choices=[
'Belle',
'Belle2'],
54 help=
'Choose Belle for converted Belle data or MC, otherwise choose Belle2.')
55 parser.add_argument(
'-m',
'--mode', dest=
'mode', type=str, required=
True,
56 choices=[
'Sampler',
'Teacher',
'Expert'],
57 help=
'Working mode of the flavor tagger. Choose Sampler, Teacher or Expert.')
58 parser.add_argument(
'-trc',
'--decayChannelTrainedOn', dest=
'decayChannelTrainedOn',
59 type=str, default=
'nunubar',
60 help=
'Decay channel of the weight files. Official samples available are JPsiKs or nunubar.')
61 parser.add_argument(
'-dc',
'--decayChannel', dest=
'decayChannel', type=str, required=
True,
62 choices=[
'JPsiKs',
'nunubar'], help=
'Decay channel that will be reconstructed. Choose JPsiKs or nunubar.')
63 parser.add_argument(
'-mct',
'--mcType', dest=
'mcType', type=str, default=
'BGx1',
64 choices=[
'BGx0',
'BGx1'], help=
'Type of files. Choose BGx0 for background free Belle II MC. \n' +
65 'Otherwise choose BGx1 for BelleII MC with bkg. or for converted Belle data or MC.')
66 parser.add_argument(
'-fn',
'--fileNumber', dest=
'fileNumber', type=str, default=
'',
67 help=
'A file number (when sampling in parallel).')
68 parser.add_argument(
'-wd',
'--workingDirectory', dest=
'workingDirectory', type=str, default=
'.',
69 help=
'Path where the training samples and the weight files are saved.')
70 parser.add_argument(
'-sd',
'--savingDirectory', dest=
'savingDirectory', type=str, default=
'.',
71 help=
'Path where the analyzed output files are saved.')
72 parser.add_argument(
'-dv',
'--doVertex', dest=
'doVertex', type=bool, default=
False,
73 help=
'Reconstruct B vertices True or False')
74 parser.add_argument(
'-bd',
'--belleData', dest=
'belleData', type=str, default=
'',
75 choices=[
'',
'BelleDataConv'], help=
'Choose BelleDataConv only for Belle Data in Expert mode.')
76 args = parser.parse_args()
78 if args.belleData ==
"BelleDataConv":
79 if args.belleOrBelle2Flag !=
"Belle":
80 b2.B2FATAL(
"BelleDataConv only for Belle Data.")
81 if args.mode !=
"Expert":
82 b2.B2FATAL(
"BelleDataConv only in Expert mode.")
83 if args.mcType !=
"BGx1":
84 b2.B2FATAL(
"When using BelleDataConv, mcType must be set to BGx1.")
89 def setEnvironment(belleOrBelle2Flag="Belle2"):
91 Sets the environment to analyse the mdst files for validation.'
93 @param belleOrBelle2Flag Default is 'Belle2' but 'Belle' is possible.
96 environmentType =
"default"
98 if belleOrBelle2Flag ==
"Belle":
100 from b2biiConversion
import convertBelleMdstToBelleIIMdst
102 os.environ[
'BELLE_POSTGRES_SERVER'] =
'can51'
103 os.environ[
'USE_GRAND_REPROCESS_DATA'] =
'1'
105 environmentType =
"Belle"
109 inputFileList.append(str(iFile))
111 convertBelleMdstToBelleIIMdst(inputBelleMDSTFile=inputFileList, path=cp_val_path)
114 ma.inputMdstList(environmentType=environmentType, filelist=[], path=cp_val_path)
117 def reconstructB2JpsiKs_mu(belleOrBelle2Flag='Belle2'):
119 Defines the reconstruction procedure for the benchmark channel 'B0 -> J/psi K_S0'
121 @param belleOrBelle2Flag Default is 'Belle2' but 'Belle' is possible.
125 ma.fillParticleList(decayString=
'mu+:all', cut=
'', path=cp_val_path)
126 ma.reconstructDecay(decayString=
'J/psi:mumu -> mu+:all mu-:all', cut=
'abs(dM) < 0.11', path=cp_val_path)
127 ma.matchMCTruth(list_name=
'J/psi:mumu', path=cp_val_path)
129 if belleOrBelle2Flag ==
"Belle":
132 ma.matchMCTruth(list_name=
'K_S0:mdst', path=cp_val_path)
135 ma.reconstructDecay(decayString=
'B0:sig -> J/psi:mumu K_S0:mdst', cut=
'Mbc > 5.2 and abs(deltaE) < 0.15', path=cp_val_path)
137 if belleOrBelle2Flag ==
"Belle2":
140 ma.fillParticleList(decayString=
'pi+:all', cut=
'', path=cp_val_path)
141 ma.reconstructDecay(decayString=
'K_S0:pipi -> pi+:all pi-:all', cut=
'abs(dM) < 0.25', path=cp_val_path)
144 ma.reconstructDecay(decayString=
'B0:sig -> J/psi:mumu K_S0:pipi', cut=
'Mbc > 5.2 and abs(deltaE) < 0.15', path=cp_val_path)
147 def reconstructB2nunubar():
149 Defines the procedure to create a B0 list for the benchmark channel 'B0 -> nu_tau anti-nu_tau'
152 ma.fillParticleListFromMC(
'nu_tau:MC',
'', path=cp_val_path)
153 ma.reconstructMCDecay(
'B0:sig -> nu_tau:MC anti-nu_tau:MC',
'', writeOut=
True, path=cp_val_path)
156 def mcMatchAndBuildROE(belleOrBelle2Flag='Belle2'):
158 Runs the mc matching and creates the rest of event for the signal particle list.'
160 @param belleOrBelle2Flag Default is 'Belle2' but 'Belle' is possible.
164 ma.matchMCTruth(list_name=
'B0:sig', path=cp_val_path)
167 ma.buildRestOfEvent(target_list_name=
'B0:sig', path=cp_val_path)
170 def applyCPVTools(mode='Expert'):
172 Defines the procedure to use the flavor tagger and tagV on the signal 'B0:sig' list.
173 It saves also all variables to nTuples needed for evaluation of the performance
175 @param mode Default is 'Expert' but also needed for 'Sampler' mode.
178 if mode ==
'Sampler':
181 particleLists=[
'B0:sig'],
183 weightFiles=
'B2' + decayChannelTrainedOn + mcType,
184 combinerMethods=[
'TMVA-FBDT',
'FANN-MLP'],
185 useOnlyLocalWeightFiles=
True,
186 downloadFromDatabaseIfNotFound=
False,
187 workingDirectory=workingDirectory,
188 samplerFileId=str(fileNumber),
194 particleLists=[
'B0:sig'],
195 combinerMethods=[
'TMVA-FBDT',
'FANN-MLP'],
196 weightFiles=
'B2' + decayChannelTrainedOn + mcType,
197 useOnlyLocalWeightFiles=
True,
198 downloadFromDatabaseIfNotFound=
False,
199 workingDirectory=workingDirectory,
200 samplerFileId=str(fileNumber),
206 dnnIdentifier =
"FlavorTagger_" + belleOrBelle2Flag +
"_B2nunubarBGx1OptimizedForDataDNN"
207 if belleOrBelle2Flag ==
"Belle":
208 dnnIdentifier =
"FlavorTagger_" + belleOrBelle2Flag +
"_B2nunubarBGx1DNN"
209 b2.conditions.append_globaltag(
"analysis_tools_release-04-00")
210 DeepFlavorTagger.DeepFlavorTagger(
'B0:sig',
213 uniqueIdentifier=dnnIdentifier,
216 if doVertex
or mode ==
'Expert':
219 if decayChannel ==
"JPsiKs":
222 vx.treeFit(list_name=
'B0:sig', conf_level=-2, path=cp_val_path)
223 vx.TagV(list_name=
'B0:sig', MCassociation=
'breco', path=cp_val_path)
224 print(
"TagV will be used")
227 fs_vars = vc.pid + vc.track + vc.track_hits + vc.mc_truth
228 jpsiandk0s_vars = vc.mc_truth
229 vertex_vars = vc.vertex + vc.mc_vertex + vc.kinematics + vc.mc_kinematics
230 bvars = vc.reco_stats + \
233 vc.roe_multiplicities + \
238 if decayChannel ==
"JPsiKs":
240 vu.create_aliases_for_selected(list_of_variables=fs_vars,
241 decay_string=
'B0 -> [J/psi -> ^mu+ ^mu-] [K_S0 -> ^pi+ ^pi-]') + \
242 vu.create_aliases_for_selected(list_of_variables=jpsiandk0s_vars,
243 decay_string=
'B0 -> [^J/psi -> mu+ mu-] [^K_S0 -> pi+ pi-]') + \
244 vu.create_aliases_for_selected(list_of_variables=vertex_vars,
245 decay_string=
'B0 -> [^J/psi -> ^mu+ ^mu-] [^K_S0 -> ^pi+ ^pi-]')
247 bvars += ft.flavor_tagging + [
'DNN_qrCombined',
'extraInfo(dnn_output)']
249 vu._variablemanager.addAlias(
'qrMC',
'isRelatedRestOfEventB0Flavor')
253 ma.variablesToNtuple(decayString=
'B0:sig',
255 filename=savingDirectory +
'/' +
'B2A801-FlavorTagger' +
256 mode + str(fileNumber) + belleOrBelle2Flag + mcType + belleData +
'.root',
260 ma.summaryOfLists(particleLists=[
'B0:sig'], path=cp_val_path)
263 if __name__ ==
'__main__':
265 args = getCommandLineOptions()
267 belleOrBelle2Flag = args.belleOrBelle2Flag
269 decayChannelTrainedOn = args.decayChannelTrainedOn
270 decayChannel = args.decayChannel
272 fileNumber = args.fileNumber
273 workingDirectory = args.workingDirectory
274 savingDirectory = args.savingDirectory
275 doVertex = args.doVertex
276 belleData = args.belleData
278 if decayChannelTrainedOn ==
'JPsiKs':
279 decayChannelTrainedOn =
'JpsiKs_mu'
281 cp_val_path = b2.Path()
283 if mode ==
"Sampler" or mode ==
"Expert":
285 setEnvironment(belleOrBelle2Flag=belleOrBelle2Flag)
287 if decayChannel ==
"nunubar":
288 reconstructB2nunubar()
290 elif decayChannel ==
"JPsiKs":
291 reconstructB2JpsiKs_mu(belleOrBelle2Flag=belleOrBelle2Flag)
293 mcMatchAndBuildROE(belleOrBelle2Flag=belleOrBelle2Flag)
294 applyCPVTools(mode=mode)
295 b2.process(cp_val_path)
298 if mode ==
"Teacher":
303 weightFiles=
'B2' + decayChannelTrainedOn + mcType,
304 combinerMethods=[
'TMVA-FBDT',
'FANN-MLP'],
305 useOnlyLocalWeightFiles=
True,
306 downloadFromDatabaseIfNotFound=
False,
307 uploadToDatabaseAfterTraining=
True,
308 workingDirectory=workingDirectory,
static Environment & Instance()
Static method to get a reference to the Environment instance.