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