Belle II Software release-09-00-07
analysisDQM.py
1# !/usr/bin/env python3
2
3
10
11"""
12This module defines functions to add analysis DQM modules.
13"""
14
15import basf2 as b2
16from stdPi0s import stdPi0s
17from stdCharged import stdPi, stdK
18import modularAnalysis as ma
19import stdV0s
20import vertex
21
22
23def add_analysis_dqm(path):
24 """Add the analysis DQM modules to the ``path``.
25 Builds a list of muons, pi0's, Kshorts and the Fox Wolfram event shape variables. Also M(mumu) for nominal beam energy monitoring.
26
27 Parameters:
28 path (basf2.Path): modules are loaded onto this path
29 """
30
31 # muons, Kshorts and pi0s
32 ma.fillParticleList('mu+:KLMDQM', 'p>1.5', path=path)
33 ma.fillParticleList('mu+:KLMDQM2', 'p>1.5 and abs(d0) < 2 and abs(z0) < 4', path=path)
34 ma.fillParticleList('gamma:physDQM', 'E > 0.15', path=path)
35 ma.fillParticleList('mu+:physDQM', 'pt>2. and abs(d0) < 2 and abs(z0) < 4', path=path)
36 ma.reconstructDecay('pi0:physDQM -> gamma:physDQM gamma:physDQM', '0.10 < M < 0.15', 1, True, path)
37 # std Kshorts-TreeFit
38 stdV0s.stdKshorts(path=path, fitter='TreeFit', updateAllDaughters=True, writeOut=True, addSuffix=True)
39 ma.reconstructDecay('Upsilon:physDQM -> mu-:physDQM mu+:physDQM', '9 < M < 12', 1, True, path)
40 # bhabha,hadrons
41 ma.fillParticleList('e+:physDQM', 'pt>0.2 and abs(d0) < 2 and abs(z0) < 4 and thetaInCDCAcceptance', path=path)
42 ma.reconstructDecay('Upsilon:ephysDQM -> e-:physDQM e+:physDQM', '4 < M < 12', 1, True, path)
43 ma.fillParticleList('pi+:hadbphysDQM', 'p>0.1 and abs(d0) < 2 and abs(z0) < 4 and thetaInCDCAcceptance', path=path)
44
45 # have to manually create "all" lists of pi+ and photons to use inside buildEventShape
46 # to avoid loading the photons' beamBackgroundMVA variable on the DQM
47 ma.fillParticleList('pi+:evtshape', '', path=path)
48 ma.fillParticleList('gamma:evtshape', '', path=path)
49 ma.buildEventShape(
50 path=path,
51 inputListNames=['pi+:evtshape', 'gamma:evtshape'],
52 default_cleanup=False, # do not want any clean up
53 foxWolfram=True,
54 cleoCones=False,
55 collisionAxis=False,
56 harmonicMoments=False,
57 jets=False,
58 sphericity=False,
59 thrust=False)
60
61 dqm = b2.register_module('PhysicsObjectsDQM')
62 dqm.param('PI0PListName', 'pi0:physDQM')
63 dqm.param('KS0PListName', 'K_S0:merged_TreeFit')
64 dqm.param('UpsPListName', 'Upsilon:physDQM')
65 # bhabha,hadrons
66 dqm.param('UpsBhabhaPListName', 'Upsilon:ephysDQM')
67 dqm.param('UpsHadPListName', 'pi+:hadbphysDQM')
68
69 path.add_module(dqm)
70
71
72def add_mirabelle_dqm(path):
73 """Add the mirabelle DQM modules to the ``path``.
74 Runs on conditional paths depending on the software trigger results.
75 Building D*'s or dimuons on the conditional paths.
76
77 Parameters:
78 path (basf2.Path): modules are loaded onto this path
79 """
80 # Software Trigger to divert the path
81 MiraBelleMumu_path = b2.create_path()
82 MiraBelleZ0_path = b2.create_path()
83 MiraBelleDst1_path = b2.create_path()
84 MiraBelleNotDst1_path = b2.create_path()
85 MiraBelleDst2_path = b2.create_path()
86 # bhabha,hadrons
87 MiraBelleBhabha_path = b2.create_path()
88 MiraBellehadronb2_path = b2.create_path()
89
90 trigger_skim_mumutight = path.add_module(
91 "TriggerSkim",
92 triggerLines=["software_trigger_cut&skim&accept_mumutight"],
93 resultOnMissing=0,
94 )
95 trigger_skim_mumutight.if_value("==1", MiraBelleMumu_path, b2.AfterConditionPath.CONTINUE)
96
97 trigger_skim_singlemuon = path.add_module(
98 "TriggerSkim",
99 triggerLines=["software_trigger_cut&filter&single_muon"],
100 resultOnMissing=0,
101 )
102 trigger_skim_singlemuon.if_value("==1", MiraBelleZ0_path, b2.AfterConditionPath.CONTINUE)
103
104 trigger_skim_dstar_1 = path.add_module(
105 "TriggerSkim",
106 triggerLines=["software_trigger_cut&skim&accept_dstar_1"],
107 resultOnMissing=0,
108 )
109 trigger_skim_dstar_1.if_value("==1", MiraBelleDst1_path, b2.AfterConditionPath.CONTINUE)
110
111 trigger_skim_not_dstar_1 = path.add_module(
112 "TriggerSkim",
113 triggerLines=["software_trigger_cut&skim&accept_dstar_1"],
114 expectedResult=0,
115 resultOnMissing=0,
116 )
117 trigger_skim_not_dstar_1.if_value("==1", MiraBelleNotDst1_path, b2.AfterConditionPath.CONTINUE)
118 trigger_skim_dstar_2 = MiraBelleNotDst1_path.add_module(
119 "TriggerSkim",
120 triggerLines=["software_trigger_cut&skim&accept_dstar_2"],
121 resultOnMissing=0,
122 )
123 trigger_skim_dstar_2.if_value("==1", MiraBelleDst2_path, b2.AfterConditionPath.CONTINUE)
124 # bhabha,hadrons
125 trigger_skim_bhabhaall = path.add_module(
126 "TriggerSkim",
127 triggerLines=["software_trigger_cut&skim&accept_bhabha_all"],
128 resultOnMissing=0,
129 )
130 trigger_skim_bhabhaall.if_value("==1", MiraBelleBhabha_path, b2.AfterConditionPath.CONTINUE)
131 trigger_skim_hadronb2 = path.add_module(
132 "TriggerSkim",
133 triggerLines=["software_trigger_cut&skim&accept_hadronb2"],
134 resultOnMissing=0,
135 )
136 trigger_skim_hadronb2.if_value("==1", MiraBellehadronb2_path, b2.AfterConditionPath.CONTINUE)
137
138 # MiraBelle di-muon path
139 ma.fillParticleList('mu+:physMiraBelle', '', path=MiraBelleMumu_path)
140 ma.reconstructDecay('Upsilon:physMiraBelle -> mu+:physMiraBelle mu-:physMiraBelle', '9 < M < 12', path=MiraBelleMumu_path)
141 MiraBelleMumu = b2.register_module('PhysicsObjectsMiraBelle')
142 MiraBelleMumu.param('MuPListName', 'mu+:physMiraBelle')
143 MiraBelleMumu.param('MuMuPListName', 'Upsilon:physMiraBelle')
144 MiraBelleMumu_path.add_module(MiraBelleMumu)
145
146 # MiraBelle Z0 path
147 ma.fillParticleList('mu+:physMiraBelleZ0', 'abs(dr) < 2 and abs(dz) < 5', path=MiraBelleZ0_path)
148 ma.reconstructDecay('Z0:physMiraBelle -> mu+:physMiraBelleZ0 mu-:physMiraBelleZ0',
149 'nCleanedTracks(abs(dr) < 2 and abs(dz) < 5) and 9 < M and M < 12', path=MiraBelleZ0_path)
150 MiraBelleModule = b2.register_module('PhysicsObjectsMiraBelle')
151 MiraBelleModule.param('Z0PListName', 'Z0:physMiraBelle')
152 MiraBelleZ0_path.add_module(MiraBelleModule)
153
154 # MiraBelle D* (followed by D0 -> K pi) path
155 ma.fillParticleList('pi+:MiraBelleDst1', 'abs(d0)<0.5 and abs(z0)<3', path=MiraBelleDst1_path)
156 ma.fillParticleList('K+:MiraBelleDst1', 'abs(d0)<0.5 and abs(z0)<3', path=MiraBelleDst1_path)
157 ma.reconstructDecay('D0:MiraBelleDst1_kpi -> K-:MiraBelleDst1 pi+:MiraBelleDst1', '1.7 < M < 2.1', path=MiraBelleDst1_path)
158 ma.reconstructDecay('D*+:MiraBelleDst1_kpi -> D0:MiraBelleDst1_kpi pi+:MiraBelleDst1',
159 'useCMSFrame(p) > 2.5 and massDifference(0) < 0.16', path=MiraBelleDst1_path)
160 MiraBelleDst1 = b2.register_module('PhysicsObjectsMiraBelleDst')
161 MiraBelleDst1.param('DstListName', 'D*+:MiraBelleDst1_kpi')
162 MiraBelleDst1_path.add_module(MiraBelleDst1)
163
164 # MiraBelle D* (followed by D0 -> K pi pi0) path
165 ma.fillParticleList('pi+:MiraBelleDst2', 'abs(d0)<0.5 and abs(z0)<3', path=MiraBelleDst2_path)
166 ma.fillParticleList('K+:MiraBelleDst2', 'abs(d0)<0.5 and abs(z0)<3', path=MiraBelleDst2_path)
167 stdPi0s(listtype='eff60_May2020', path=MiraBelleDst2_path)
168 ma.reconstructDecay(
169 'D0:MiraBelleDst2_kpipi0 -> K-:MiraBelleDst2 pi+:MiraBelleDst2 pi0:eff60_May2020',
170 '1.7 < M < 2.1',
171 path=MiraBelleDst2_path)
172 ma.reconstructDecay('D*+:MiraBelleDst2_kpipi0 -> D0:MiraBelleDst2_kpipi0 pi+:MiraBelleDst2',
173 'useCMSFrame(p) > 2.5 and massDifference(0) < 0.16', path=MiraBelleDst2_path)
174 MiraBelleDst2 = b2.register_module('PhysicsObjectsMiraBelleDst2')
175 MiraBelleDst2.param('DstListName', 'D*+:MiraBelleDst2_kpipi0')
176 MiraBelleDst2_path.add_module(MiraBelleDst2)
177 # bhabha,hadrons
178 ma.fillParticleList(
179 'e+:physMiraBelle',
180 'pt>0.2 and abs(d0) < 2 and abs(z0) < 4 and thetaInCDCAcceptance',
181 path=MiraBelleBhabha_path)
182 ma.reconstructDecay('Upsilon:ephysMiraBelle -> e+:physMiraBelle e-:physMiraBelle', '4 < M < 12', path=MiraBelleBhabha_path)
183 MiraBelleBhabha = b2.register_module('PhysicsObjectsMiraBelleBhabha')
184 MiraBelleBhabha.param('ePListName', 'e+:physMiraBelle')
185 MiraBelleBhabha.param('bhabhaPListName', 'Upsilon:ephysMiraBelle')
186 MiraBelleBhabha_path.add_module(MiraBelleBhabha)
187 ma.fillParticleList(
188 'pi+:hadb2physMiraBelle',
189 'p>0.1 and abs(d0) < 2 and abs(z0) < 4 and thetaInCDCAcceptance',
190 path=MiraBellehadronb2_path)
191 MiraBellehadronb = b2.register_module('PhysicsObjectsMiraBelleHadron')
192 MiraBellehadronb.param('hadronb2piPListName', 'pi+:hadb2physMiraBelle')
193 MiraBellehadronb2_path.add_module(MiraBellehadronb)
194
195
196# Selection for the EcmsBB analysis
197def get_hadB_path(path):
198 """ Selects the hadronic B decays, function returns corresponding path """
199
200 # module to be run prior the collector
201 path_hadB = b2.create_path()
202 trigger_skim_BB = path.add_module(
203 "TriggerSkim",
204 triggerLines=["software_trigger_cut&skim&accept_btocharm"],
205 resultOnMissing=0,
206 )
207 trigger_skim_BB.if_value("==1", path_hadB, b2.AfterConditionPath.CONTINUE)
208
209 stdPi(listtype='loose', path=path_hadB)
210 stdK(listtype='good', path=path_hadB)
211 stdPi0s(listtype='eff40_May2020', path=path_hadB)
212
213 ma.cutAndCopyList("pi+:hadB", "pi+:loose", "[abs(dz)<2.0] and [abs(dr)<0.5]", path=path_hadB)
214 ma.cutAndCopyList("K+:hadB", "K+:good", "[abs(dz)<2.0] and [abs(dr)<0.5]", path=path_hadB)
215
216 ma.cutAndCopyList("pi0:hadB", "pi0:eff40_May2020", "", path=path_hadB)
217
218
221
222 DcutLoose = '1.7 < M < 2.1'
223 Dcut = '1.830 < M < 1.894'
224 # Reconstructs D0s and sets decay mode identifiers
225 ma.reconstructDecay(decayString='D0:hadB_Kpi -> K-:hadB pi+:hadB', cut=DcutLoose, dmID=1, path=path_hadB)
226 ma.reconstructDecay(decayString='D0:hadB_Kpipi0 -> K-:hadB pi+:hadB pi0:hadB',
227 cut=DcutLoose, dmID=2, path=path_hadB)
228 ma.reconstructDecay(decayString='D0:hadB_Kpipipi -> K-:hadB pi+:hadB pi-:hadB pi+:hadB',
229 cut=DcutLoose, dmID=3, path=path_hadB)
230
231 # Performs mass constrained fit for all D0 candidates
232 vertex.kFit(list_name='D0:hadB_Kpi', conf_level=0.0, fit_type='mass', path=path_hadB)
233 # vertex.kFit(list_name='D0:hadB_Kpipi0', conf_level=0.0, fit_type='mass', path=path_hadB)
234 vertex.kFit(list_name='D0:hadB_Kpipipi', conf_level=0.0, fit_type='mass', path=path_hadB)
235
236 ma.applyCuts("D0:hadB_Kpi", Dcut, path=path_hadB)
237 ma.applyCuts("D0:hadB_Kpipi0", Dcut, path=path_hadB)
238 ma.applyCuts("D0:hadB_Kpipipi", Dcut, path=path_hadB)
239
240 DStarcutLoose = 'massDifference(0) < 0.16'
241
242 # Reconstructs D*-s and sets decay mode identifiers
243 ma.reconstructDecay(decayString='D*+:hadB_D0pi_Kpi -> D0:hadB_Kpi pi+:hadB', cut=DStarcutLoose, dmID=1, path=path_hadB)
244 ma.reconstructDecay(decayString='D*+:hadB_D0pi_Kpipi0 -> D0:hadB_Kpipi0 pi+:hadB',
245 cut=DStarcutLoose, dmID=2, path=path_hadB)
246 ma.reconstructDecay(decayString='D*+:hadB_D0pi_Kpipipi -> D0:hadB_Kpipipi pi+:hadB',
247 cut=DStarcutLoose, dmID=3, path=path_hadB)
248
249 BcutLoose = '[ useCMSFrame(p) < 1.6 ] and [abs(dM) < 0.25]'
250 Bcut = '[ useCMSFrame(p) < 1.2 ] and [abs(dM) < 0.05]'
251
252 # Reconstructs the signal B0 candidates from Dstar
253 ma.reconstructDecay(decayString='B0:hadB_Dstpi_D0pi_Kpi -> D*-:hadB_D0pi_Kpi pi+:hadB',
254 cut=BcutLoose,
255 dmID=1, path=path_hadB)
256 ma.reconstructDecay(decayString='B0:hadB_Dstpi_D0pi_Kpipi0 -> D*-:hadB_D0pi_Kpipi0 pi+:hadB',
257 cut=BcutLoose,
258 dmID=2, path=path_hadB)
259 ma.reconstructDecay(decayString='B0:hadB_Dstpi_D0pi_Kpipipi -> D*-:hadB_D0pi_Kpipipi pi+:hadB',
260 cut=BcutLoose,
261 dmID=3, path=path_hadB)
262
263 vertex.treeFit('B0:hadB_Dstpi_D0pi_Kpi', updateAllDaughters=True, ipConstraint=True, path=path_hadB)
264 vertex.treeFit('B0:hadB_Dstpi_D0pi_Kpipi0', updateAllDaughters=True, ipConstraint=True, path=path_hadB)
265 vertex.treeFit('B0:hadB_Dstpi_D0pi_Kpipipi', updateAllDaughters=True, ipConstraint=True, path=path_hadB)
266
267
270
271 # Reconstructs charged D mesons and sets decay mode identifiers
272 ma.reconstructDecay(decayString='D-:hadB_Kpipi -> K+:hadB pi-:hadB pi-:hadB',
273 cut=DcutLoose, dmID=4, path=path_hadB)
274
275 vertex.kFit(list_name='D-:hadB_Kpipi', conf_level=0.0, fit_type='mass', path=path_hadB)
276 ma.applyCuts("D-:hadB_Kpipi", '1.844 < M < 1.894', path=path_hadB)
277
278 # Reconstructs the signal B candidates
279 ma.reconstructDecay(decayString='B0:hadB_Dpi_Kpipi -> D-:hadB_Kpipi pi+:hadB',
280 cut=BcutLoose, dmID=4, path=path_hadB)
281
282
285
286 # Reconstructs the signal B- candidates
287 ma.reconstructDecay(decayString='B-:hadB_D0pi_Kpi -> D0:hadB_Kpi pi-:hadB',
288 cut=BcutLoose,
289 dmID=5, path=path_hadB)
290 ma.reconstructDecay(decayString='B-:hadB_D0pi_Kpipi0 -> D0:hadB_Kpipi0 pi-:hadB',
291 cut=BcutLoose,
292 dmID=6, path=path_hadB)
293 ma.reconstructDecay(decayString='B-:hadB_D0pi_Kpipipi -> D0:hadB_Kpipipi pi-:hadB',
294 cut=BcutLoose,
295 dmID=7, path=path_hadB)
296
297 vertex.treeFit('B-:hadB_D0pi_Kpi', updateAllDaughters=True, ipConstraint=True, path=path_hadB)
298 vertex.treeFit('B-:hadB_D0pi_Kpipi0', updateAllDaughters=True, ipConstraint=True, path=path_hadB)
299 vertex.treeFit('B-:hadB_D0pi_Kpipipi', updateAllDaughters=True, ipConstraint=True, path=path_hadB)
300
301 ma.copyLists(
302 outputListName='B0:hadB_combined',
303 inputListNames=[
304 'B0:hadB_Dstpi_D0pi_Kpi',
305 'B0:hadB_Dstpi_D0pi_Kpipi0',
306 'B0:hadB_Dstpi_D0pi_Kpipipi',
307 'B0:hadB_Dpi_Kpipi'
308 ],
309 path=path_hadB)
310
311 ma.copyLists(
312 outputListName='B-:hadB_combined',
313 inputListNames=[
314 'B-:hadB_D0pi_Kpi',
315 'B-:hadB_D0pi_Kpipi0',
316 'B-:hadB_D0pi_Kpipipi',
317 ],
318 path=path_hadB)
319
320 # Builds the rest of event object, which contains all particles not used in the reconstruction of B0 candidates.
321 ma.buildRestOfEvent(target_list_name='B0:hadB_combined', path=path_hadB)
322
323 # CleanMask is identical for B0 and B+
324 cleanMask = ('cleanMask', 'nCDCHits > 0 and useCMSFrame(p)<=3.2', 'p >= 0.05 and useCMSFrame(p)<=3.2')
325
326 # Calculates the continuum suppression variables
327 ma.appendROEMasks(list_name='B0:hadB_combined', mask_tuples=[cleanMask], path=path_hadB)
328 ma.buildContinuumSuppression(list_name='B0:hadB_combined', roe_mask='cleanMask', path=path_hadB)
329
330 # Builds the rest of event object, which contains all particles not used in the reconstruction of B- candidates.
331 ma.buildRestOfEvent(target_list_name='B-:hadB_combined', path=path_hadB)
332
333 # Calculates the continuum suppression variables
334 ma.appendROEMasks(list_name='B-:hadB_combined', mask_tuples=[cleanMask], path=path_hadB)
335 ma.buildContinuumSuppression(list_name='B-:hadB_combined', roe_mask='cleanMask', path=path_hadB)
336
337 ma.applyCuts("B0:hadB_combined", "[R2 < 0.3] and " + Bcut, path=path_hadB)
338 ma.applyCuts("B-:hadB_combined", "[R2 < 0.3] and " + Bcut, path=path_hadB)
339
340 MiraBelleEcmsBB = b2.register_module('PhysicsObjectsMiraBelleEcmsBB')
341 MiraBelleEcmsBB.param('B0ListName', 'B0:hadB_combined')
342 MiraBelleEcmsBB.param('BmListName', 'B-:hadB_combined')
343 path_hadB.add_module(MiraBelleEcmsBB)
344
345 return path_hadB
346
def stdKshorts(prioritiseV0=True, fitter="TreeFit", path=None, updateAllDaughters=False, writeOut=False, addSuffix=False)
Definition: stdV0s.py:24
def treeFit(list_name, conf_level=0.001, massConstraint=[], ipConstraint=False, updateAllDaughters=False, customOriginConstraint=False, customOriginVertex=[0.001, 0, 0.0116], customOriginCovariance=[0.0048, 0, 0, 0, 0.003567, 0, 0, 0, 0.0400], originDimension=3, treatAsInvisible='', ignoreFromVertexFit='', path=None)
Definition: vertex.py:239
def kFit(list_name, conf_level, fit_type='vertex', constraint='', daughtersUpdate=False, decay_string='', massConstraint=[], recoilMass=0, smearing=0, path=None)
Definition: vertex.py:129