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