Belle II Software  release-05-01-25
B2A306-B02RhoGamma-withPi0EtaVeto.py
1 #!/usr/bin/env python3
2 
3 
33 
34 import basf2 as b2
35 import modularAnalysis as ma
36 import variables.collections as vc
37 import variables.utils as vu
38 
39 # create path
40 my_path = b2.create_path()
41 
42 # writePi0EtaVeto uses a payload in analysis global tag.
43 b2.conditions.prepend_globaltag(ma.getAnalysisGlobaltag())
44 
45 # load input ROOT file
46 ma.inputMdst(environmentType='default',
47  filename=b2.find_file('B2rhogamma_rho2pipi.root', 'examples', False),
48  path=my_path)
49 
50 ma.fillParticleList(decayString='gamma:highE',
51  cut='E > 1.5',
52  path=my_path)
53 ma.fillParticleList(decayString='pi+:loose',
54  cut='abs(d0) < 0.5 and abs(z0) < 0.5 and pionID > 0.002',
55  path=my_path)
56 
57 # reconstruct rho -> pi+ pi- decay
58 # keep only candidates with 0.6 < M(pi+pi-) < 1.0 GeV
59 ma.reconstructDecay(decayString='rho0 -> pi+:loose pi-:loose',
60  cut='0.6 < M < 1.0',
61  path=my_path)
62 
63 # reconstruct B0 -> rho0 gamma decay
64 # keep only candidates with Mbc > 5.2 GeV
65 # and -2 < Delta E < 2 GeV
66 ma.reconstructDecay(decayString='B0 -> rho0 gamma:highE',
67  cut='5.2 < Mbc and abs(deltaE) < 2.0',
68  path=my_path)
69 
70 # perform MC matching (MC truth asociation)
71 ma.matchMCTruth(list_name='B0',
72  path=my_path)
73 
74 # build RestOfEvent (ROE) object for each B0 candidate
75 # ROE is required by the veto
76 ma.buildRestOfEvent(target_list_name='B0',
77  path=my_path)
78 
79 # perform pi0/eta veto
80 ma.writePi0EtaVeto(particleList='B0',
81  decayString='B0 -> rho0 ^gamma',
82  workingDirectory='./pi0etaveto',
83  path=my_path)
84 
85 # at this stage the B0 candidates should have
86 # extraInfo(Pi0_Prob) and extraInfo(Eta_Prob) value attached.
87 # extraInfo(Pi0_Prob) means pi0 probability for the B0 candidates whose gamma daughter.
88 # extraInfo(Eta_Prob) means eta probability for the B0 candidates whose gamma daughter.
89 # For the B0 candidates whose gamma daughter could not be combined with
90 # any of the remaining photons to form pi0/eta because of soft photon selection
91 # the extraInfo(Pi0_Prob) and extraInfo(Eta_Prob) does not exist. In these cases
92 # -999 will be written to the extraInfo(Pi0_Prob) branch and extraInfo(Eta_Prob) branch.
93 # You can change extraInfo names of pi0/eta probability by setting pi0vetoname and etavetoname parameters. For example,
94 # writePi0EtaVeto('B0', 'B0 -> rho0 ^gamma', workingDirectory='./pi0etaveto', pi0vetoname='Pi0_Prob2', etavetoname='Eta_Prob2')
95 
96 # You need at least the default weight files: pi0veto.root and etaveto.root for writePi0EtaVeto.
97 # The default files are optimised by MC campaign 9.
98 # If you don't have weight files in your workingDirectory,
99 # these files are downloaded from database to your workingDirectory automatically.
100 # The default workingDirectory is '.'
101 # You can also download them from following directory in KEKCC:
102 # /gpfs/group/belle2/users/akimasa/pi0etaveto
103 # If you train by yourself, you should refer to
104 # B2A701-ContinuumSuppression_Input.py
105 # B2A702-ContinuumSuppression_MVATrain.py
106 
107 
108 # You can also do a simple veto using delta mass ranking as below.
109 
110 # VETO starts here
111 # ----------------
112 
113 # Create a new path (called ROE path) which will be executed for
114 # each ROE in an event.
115 # Note that ROE exists for each B0 candidate, so when we loop
116 # over each ROE, we effectively loop over signal B0 candidates
117 
118 roe_path = b2.create_path()
119 
120 # The ROE objects might in general be related to Particle from multiple
121 # particle lists therfore we need to check if the current ROE object
122 # is related to the Particle from our signal decay. If it is not
123 # the execution of roe_path will be finished (by starting empty,
124 # dead end path). Note that in this example this x-check is not
125 # neccessary, but is anyway added for sake of completness
126 deadEndPath = b2.create_path()
127 
128 # Note again: all actions (modules) included in roe_path will be
129 # executed for each ROE in the event
130 # First we check that the current ROE is related to B0 candidate
131 ma.signalSideParticleFilter(particleList='B0',
132  selection='',
133  roe_path=roe_path,
134  deadEndPath=deadEndPath)
135 
136 # create and fill gamma ParticleList that will contain
137 # all photons found in ROE (not used to reconstruct current B0 candidate)
138 # The photons need to have energy above 50 MeV to be considered
139 # (one can add any cut)
140 ma.fillParticleList(decayString='gamma:roe',
141  cut='isInRestOfEvent == 1 and E > 0.050',
142  path=roe_path)
143 
144 # in order to be able to use modularAnalysis functions (reconstructDecay in particular)
145 # we need a ParticleList containg the photon candidate used to reconstruct the
146 # current B meson as well
147 # The DecayString is used to specify the selected particle (^)
148 ma.fillSignalSideParticleList(outputListName='gamma:sig',
149  decayString='B0 -> rho0 ^gamma',
150  path=roe_path)
151 
152 # make combinations of signal photon candidates with all photons from ROE
153 # keep only combinations in given invariant mass range
154 ma.reconstructDecay(decayString='pi0:veto -> gamma:sig gamma:roe',
155  cut='0.080 < M < 0.200',
156  path=roe_path)
157 
158 # at this point one could use all features provided by the analysis software
159 # to make the veto as effective as possible. For example, one can perform truth
160 # matching, training/applying TMVA classifier, save pi0 candidates with ntuple
161 # maker for offline analysis/study.
162 
163 # in this example the variable, which is used to veto pi0 is very simple:
164 # invariant mass of pi0 that is closest to the pi0's nominal mass
165 # Therfore, we just simply rank pi0 candidates according to their distance
166 # from nominal mass (dM variable) and keep only the best candidate
167 ma.rankByLowest(particleList='pi0:veto',
168  variable='abs(dM)',
169  numBest=1,
170  path=roe_path)
171 
172 # write the invariant mass of the best pi0 candidate to the current B0
173 # candidate as the 'pi0veto' extraInfo
174 ma.variableToSignalSideExtraInfo(particleList='pi0:veto', varToExtraInfo={'M': 'pi0veto'}, path=roe_path)
175 
176 # execute roe_path for each RestOfEvent in the event
177 my_path.for_each('RestOfEvent', 'RestOfEvents', roe_path)
178 
179 # VETO ends here
180 # ----------------
181 
182 # we're now out of the ROE path
183 # at this stage the B0 candidates should have
184 # extraInfo(pi0veto) value attached. For the B0
185 # candidates whose gamma daughter could not be combined with
186 # any of the remaining photons to form pi0 within given mass
187 # range the extraInfo(pi0veto) does not exist. In these cases
188 # -999 will be written to the extraInfo(pi0veto) branch
189 # Select variables that we want to store to ntuple
190 
191 gamma_vars = vc.cluster + \
192  vc.mc_truth + \
193  vc.kinematics
194 
195 rho_vars = vc.cluster + \
196  vc.mc_truth + \
197  vc.kinematics + \
198  vc.inv_mass
199 
200 pi_vars = vc.track
201 
202 b_vars = vc.kinematics + \
203  vc.deltae_mbc + \
204  vc.mc_truth + \
205  vu.create_aliases_for_selected(list_of_variables=gamma_vars,
206  decay_string='B0 -> rho0 ^gamma') + \
207  vu.create_aliases_for_selected(list_of_variables=rho_vars,
208  decay_string='B0 -> ^rho0 gamma') + \
209  vu.create_aliases_for_selected(list_of_variables=rho_vars,
210  decay_string='B0 -> [rho0 -> ^pi+ ^pi-] gamma') + \
211  vu.create_aliases(list_of_variables=['Pi0_Prob', 'Eta_Prob', 'pi0veto'],
212  wrapper='extraInfo({variable})',
213  prefix="B")
214 
215 # Saving variables to ntuple
216 rootOutputFile = "B2A306-B02RhoGamma-withPi0EtaVeto.root"
217 ma.variablesToNtuple(decayString='B0',
218  variables=b_vars,
219  filename=rootOutputFile,
220  treename='b0',
221  path=my_path)
222 
223 # Process the events
224 b2.process(my_path)
225 
226 # print out the summary
227 print(b2.statistics)
variables.utils
Definition: utils.py:1
variables.collections
Definition: collections.py:1