Belle II Software  release-05-01-25
B2A801-FlavorTagger.py
1 #!/usr/bin/env python3
2 
3 
25 
26 import basf2 as b2
27 import modularAnalysis as ma
28 import flavorTagger as ft
29 import vertex as vx
30 import variables.collections as vc
31 import variables.utils as vu
32 
33 
34 # create path
35 cp_val_path = b2.Path()
36 
37 # Environment of the MC or data sample
38 environmentType = "default"
39 
40 # For Belle data/MC use
41 # from b2biiConversion import convertBelleMdstToBelleIIMdst
42 # import os
43 
44 # os.environ['PGUSER'] = 'g0db'
45 # os.environ['USE_GRAND_REPROCESS_DATA'] = '1'
46 
47 # environmentType = "Belle"
48 
49 # # You can use Belle MC/data as input calling this script as basf2 -i 'YourConvertedBelleData*.root' B2A801-FlavorTagger.py
50 # ma.inputMdstList(environmentType=environmentType, filelist=[], path=cp_val_path)
51 
52 
53 # load input ROOT file
54 ma.inputMdst(environmentType='default',
55  filename=b2.find_file('analysis/mdst11_BGx1_b2jpsiks.root', 'validation', False),
56  path=cp_val_path)
57 
58 
59 # Creates Muon particle list
60 ma.fillParticleList(decayString='mu+:all', cut='', path=cp_val_path)
61 
62 # reconstruct J/psi -> mu+ mu- decay
63 # keep only candidates with dM<0.11
64 ma.reconstructDecay(decayString='J/psi:mumu -> mu+:all mu-:all', cut='dM<0.11', path=cp_val_path)
65 
66 
67 # For Belle data/MC use
68 # # use the existent K_S0:mdst list to reconstruct B0 -> J/psi Ks decay
69 # ma.reconstructDecay(decayString='B0:sig -> J/psi:mumu K_S0:mdst', cut='Mbc > 5.2 and abs(deltaE)<0.15', path=cp_val_path)
70 
71 
72 # reconstruct Ks from standard pi+ particle list
73 ma.fillParticleList(decayString='pi+:all', cut='', path=cp_val_path)
74 ma.reconstructDecay(decayString='K_S0:pipi -> pi+:all pi-:all', cut='dM<0.25', path=cp_val_path)
75 
76 # reconstruct B0 -> J/psi Ks decay
77 ma.reconstructDecay(decayString='B0:sig -> J/psi:mumu K_S0:pipi', cut='Mbc > 5.2 and abs(deltaE)<0.15', path=cp_val_path)
78 
79 # Does the matching between reconstructed and MC particles
80 ma.matchMCTruth(list_name='B0:sig', path=cp_val_path)
81 
82 # build the rest of the event associated to the B0
83 ma.buildRestOfEvent(target_list_name='B0:sig',
84  path=cp_val_path)
85 
86 b2.conditions.append_globaltag(ma.getAnalysisGlobaltag())
87 
88 # The default working directory is '.'
89 # Note that if you also train by yourself the weights of the trained Methods are saved therein.
90 # To save CPU time the weight files should be saved in the same server were you run.
91 #
92 # NEVER set uploadToDatabaseAfterTraining to True if you are not a librarian!!!
93 #
94 # BGx1 stays for MC generated with machine Background.
95 # The official weight files are trained using B0-> nu_tau anti-nu_tau as signal channel (no CP violation)
96 # to avoid that the flavor tagger learns asymmetries on the tag side.
97 # Only this kind of weight files are supported since release-03-01-00.
98 
99 weightfiles = 'B2nunubarBGx1'
100 
101 # Flavor Tagging Function. Default Expert mode to use the official weight files.
102 ft.flavorTagger(
103  particleLists=['B0:sig'],
104  weightFiles=weightfiles,
105  path=cp_val_path)
106 
107 # By default the flavorTagger trains and applies two methods, 'TMVA-FBDT' and 'FANN-MLP', for the combiner.
108 # If you want to train or test the Flavor Tagger only for one of them you have to specify it like:
109 #
110 # combinerMethods=['TMVA-FBDT']
111 #
112 # All available categories are:
113 # [
114 # 'Electron',
115 # 'IntermediateElectron',
116 # 'Muon',
117 # 'IntermediateMuon',
118 # 'KinLepton',
119 # 'IntermediateKinLepton',
120 # 'Kaon',
121 # 'SlowPion',
122 # 'FastHadron',
123 # 'Lambda',
124 # 'FSC',
125 # 'MaximumPstar',
126 # 'KaonPion']
127 #
128 # If you want to train yourself, have a look at the scritps under analysis/release-validation/CPVTools/
129 # in principle you need only to run CPVToolsValidatorInParalell.sh
130 # If you train the event and combiner levels, you need two different samples of at least 500k events (one for each sampler).
131 # The different samples are needed to avoid biases between levels.
132 # We mean 500k of correctly corrected and MC matched neutral Bs. (isSignal > 0)
133 # You can also train the event level for all categories and then train the combiner
134 # for a specific combination (last two runs).
135 # It is also possible to train different combiners consecutively using the same weightFiles name.
136 # You just need always to specify the desired category combination while using the expert mode as:
137 #
138 # flavorTagger(particleLists=['B0:sig'], mode = 'Expert', weightFiles='B2JpsiKs_mu',
139 # categories=['Electron', 'Muon', 'Kaon', ... etc.])
140 #
141 # Another possibility is to train a combiner for a specific category combination using the default weight files
142 #
143 # Attention: to train the flavor tagger you need MC samples generated without built-in CP violation!
144 # The best sample for this is B0-> nu_tau anti-nu_tau .
145 # You can apply cuts using the flavor Tagger: qrOutput(FBDT) > -2 rejects all events which do not
146 # provide flavor information using the tag side
147 ma.applyCuts(list_name='B0:sig',
148  cut='qrOutput(FBDT) > -2',
149  path=cp_val_path)
150 
151 # If you applied the cut on qrOutput(FBDT) > -2 before then you can rank by highest r- factor
152 ma.rankByHighest(particleList='B0:sig',
153  variable='abs(qrOutput(FBDT))',
154  numBest=0,
155  outputVariable='Dilution_rank',
156  path=cp_val_path)
157 
158 # Fit vertex of the B0 on the signal side
159 vx.raveFit(list_name='B0:sig', conf_level=0.0, decay_string='B0:sig -> [J/psi:mumu -> ^mu+ ^mu-] K_S0',
160  constraint='', path=cp_val_path)
161 
162 
163 # Fit Vertex of the B0 on the tag side
164 vx.TagV(list_name='B0:sig', MCassociation='breco', path=cp_val_path)
165 
166 # Select variables that will be stored to ntuple
167 fs_vars = vc.pid + vc.track + vc.track_hits + vc.mc_truth
168 jpsiandk0s_vars = vc.mc_truth
169 vertex_vars = vc.vertex + vc.mc_vertex + vc.kinematics + vc.mc_kinematics
170 bvars = vc.reco_stats + \
171  vc.deltae_mbc + \
172  vc.mc_truth + \
173  vc.roe_multiplicities + \
174  vc.tag_vertex + \
175  vc.mc_tag_vertex + \
176  vertex_vars
177 
178 # Attention: the collection of flavor tagging variables is defined in the flavorTagger
179 bvars += ft.flavor_tagging
180 
181 # Create aliases to save information for different particles
182 bvars = bvars + \
183  vu.create_aliases_for_selected(list_of_variables=fs_vars,
184  decay_string='B0 -> [J/psi -> ^mu+ ^mu-] [K_S0 -> ^pi+ ^pi-]') + \
185  vu.create_aliases_for_selected(list_of_variables=jpsiandk0s_vars,
186  decay_string='B0 -> [^J/psi -> mu+ mu-] [^K_S0 -> pi+ pi-]') + \
187  vu.create_aliases_for_selected(list_of_variables=vertex_vars,
188  decay_string='B0 -> [^J/psi -> ^mu+ ^mu-] [^K_S0 -> ^pi+ ^pi-]')
189 
190 # Saving variables to ntuple
191 output_file = 'B2A801-FlavorTagger.root'
192 ma.variablesToNtuple(decayString='B0:sig',
193  variables=bvars,
194  filename=output_file,
195  treename='B0tree',
196  path=cp_val_path)
197 
198 # Summary of created Lists
199 ma.summaryOfLists(particleLists=['J/psi:mumu', 'B0:sig'],
200  path=cp_val_path)
201 
202 # Process the events
203 b2.process(cp_val_path)
204 
205 # print out the summary
206 print(b2.statistics)
207 
208 # If you want to calculate the efficiency of the FlavorTagger on your own
209 # File use the script analysis/release-validation/CPVTools/flavorTaggerEfficiency.py giving
210 # your file and the treename as arguments:
211 
212 # basf2 flavorTaggerEfficiency.py 'YourFilesWithWildCards.root' 'B0tree'
variables.utils
Definition: utils.py:1
variables.collections
Definition: collections.py:1