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, updateAllDaughters=True, writeOut=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')
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 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_dstar_1 = path.add_module(
98 "TriggerSkim",
99 triggerLines=["software_trigger_cut&skim&accept_dstar_1"],
100 resultOnMissing=0,
101 )
102 trigger_skim_dstar_1.if_value("==1", MiraBelleDst1_path, b2.AfterConditionPath.CONTINUE)
103
104 trigger_skim_not_dstar_1 = path.add_module(
105 "TriggerSkim",
106 triggerLines=["software_trigger_cut&skim&accept_dstar_1"],
107 expectedResult=0,
108 resultOnMissing=0,
109 )
110 trigger_skim_not_dstar_1.if_value("==1", MiraBelleNotDst1_path, b2.AfterConditionPath.CONTINUE)
111 trigger_skim_dstar_2 = MiraBelleNotDst1_path.add_module(
112 "TriggerSkim",
113 triggerLines=["software_trigger_cut&skim&accept_dstar_2"],
114 resultOnMissing=0,
115 )
116 trigger_skim_dstar_2.if_value("==1", MiraBelleDst2_path, b2.AfterConditionPath.CONTINUE)
117 # bhabha,hadrons
118 trigger_skim_bhabhaall = path.add_module(
119 "TriggerSkim",
120 triggerLines=["software_trigger_cut&skim&accept_bhabha_all"],
121 resultOnMissing=0,
122 )
123 trigger_skim_bhabhaall.if_value("==1", MiraBelleBhabha_path, b2.AfterConditionPath.CONTINUE)
124 trigger_skim_hadronb2 = path.add_module(
125 "TriggerSkim",
126 triggerLines=["software_trigger_cut&skim&accept_hadronb2"],
127 resultOnMissing=0,
128 )
129 trigger_skim_hadronb2.if_value("==1", MiraBellehadronb2_path, b2.AfterConditionPath.CONTINUE)
130
131 # MiraBelle di-muon path
132 ma.fillParticleList('mu+:physMiraBelle', '', path=MiraBelleMumu_path)
133 ma.reconstructDecay('Upsilon:physMiraBelle -> mu+:physMiraBelle mu-:physMiraBelle', '9 < M < 12', path=MiraBelleMumu_path)
134 MiraBelleMumu = b2.register_module('PhysicsObjectsMiraBelle')
135 MiraBelleMumu.param('MuPListName', 'mu+:physMiraBelle')
136 MiraBelleMumu.param('MuMuPListName', 'Upsilon:physMiraBelle')
137 MiraBelleMumu_path.add_module(MiraBelleMumu)
138
139 # MiraBelle D* (followed by D0 -> K pi) path
140 ma.fillParticleList('pi+:MiraBelleDst1', 'abs(d0)<0.5 and abs(z0)<3', path=MiraBelleDst1_path)
141 ma.fillParticleList('K+:MiraBelleDst1', 'abs(d0)<0.5 and abs(z0)<3', path=MiraBelleDst1_path)
142 ma.reconstructDecay('D0:MiraBelleDst1_kpi -> K-:MiraBelleDst1 pi+:MiraBelleDst1', '1.7 < M < 2.1', path=MiraBelleDst1_path)
143 ma.reconstructDecay('D*+:MiraBelleDst1_kpi -> D0:MiraBelleDst1_kpi pi+:MiraBelleDst1',
144 'useCMSFrame(p) > 2.5 and massDifference(0) < 0.16', path=MiraBelleDst1_path)
145 MiraBelleDst1 = b2.register_module('PhysicsObjectsMiraBelleDst')
146 MiraBelleDst1.param('DstListName', 'D*+:MiraBelleDst1_kpi')
147 MiraBelleDst1_path.add_module(MiraBelleDst1)
148
149 # MiraBelle D* (followed by D0 -> K pi pi0) path
150 ma.fillParticleList('pi+:MiraBelleDst2', 'abs(d0)<0.5 and abs(z0)<3', path=MiraBelleDst2_path)
151 ma.fillParticleList('K+:MiraBelleDst2', 'abs(d0)<0.5 and abs(z0)<3', path=MiraBelleDst2_path)
152 stdPi0s(listtype='eff60_May2020', path=MiraBelleDst2_path)
153 ma.reconstructDecay(
154 'D0:MiraBelleDst2_kpipi0 -> K-:MiraBelleDst2 pi+:MiraBelleDst2 pi0:eff60_May2020',
155 '1.7 < M < 2.1',
156 path=MiraBelleDst2_path)
157 ma.reconstructDecay('D*+:MiraBelleDst2_kpipi0 -> D0:MiraBelleDst2_kpipi0 pi+:MiraBelleDst2',
158 'useCMSFrame(p) > 2.5 and massDifference(0) < 0.16', path=MiraBelleDst2_path)
159 MiraBelleDst2 = b2.register_module('PhysicsObjectsMiraBelleDst2')
160 MiraBelleDst2.param('DstListName', 'D*+:MiraBelleDst2_kpipi0')
161 MiraBelleDst2_path.add_module(MiraBelleDst2)
162 # bhabha,hadrons
163 ma.fillParticleList(
164 'e+:physMiraBelle',
165 'pt>0.2 and abs(d0) < 2 and abs(z0) < 4 and thetaInCDCAcceptance',
166 path=MiraBelleBhabha_path)
167 ma.reconstructDecay('Upsilon:ephysMiraBelle -> e+:physMiraBelle e-:physMiraBelle', '4 < M < 12', path=MiraBelleBhabha_path)
168 MiraBelleBhabha = b2.register_module('PhysicsObjectsMiraBelleBhabha')
169 MiraBelleBhabha.param('ePListName', 'e+:physMiraBelle')
170 MiraBelleBhabha.param('bhabhaPListName', 'Upsilon:ephysMiraBelle')
171 MiraBelleBhabha_path.add_module(MiraBelleBhabha)
172 ma.fillParticleList(
173 'pi+:hadb2physMiraBelle',
174 'p>0.1 and abs(d0) < 2 and abs(z0) < 4 and thetaInCDCAcceptance',
175 path=MiraBellehadronb2_path)
176 MiraBellehadronb = b2.register_module('PhysicsObjectsMiraBelleHadron')
177 MiraBellehadronb.param('hadronb2piPListName', 'pi+:hadb2physMiraBelle')
178 MiraBellehadronb2_path.add_module(MiraBellehadronb)
179
180
181# Selection for the EcmsBB analysis
182def get_hadB_path(path):
183 """ Selects the hadronic B decays, function returns corresponding path """
184
185 # module to be run prior the collector
186 path_hadB = b2.create_path()
187 trigger_skim_BB = path.add_module(
188 "TriggerSkim",
189 triggerLines=["software_trigger_cut&skim&accept_btocharm"],
190 resultOnMissing=0,
191 )
192 trigger_skim_BB.if_value("==1", path_hadB, b2.AfterConditionPath.CONTINUE)
193
194 stdPi(listtype='loose', path=path_hadB)
195 stdK(listtype='good', path=path_hadB)
196 stdPi0s(listtype='eff40_May2020', path=path_hadB)
197
198 ma.cutAndCopyList("pi+:hadB", "pi+:loose", "[abs(dz)<2.0] and [abs(dr)<0.5]", path=path_hadB)
199 ma.cutAndCopyList("K+:hadB", "K+:good", "[abs(dz)<2.0] and [abs(dr)<0.5]", path=path_hadB)
200
201 ma.cutAndCopyList("pi0:hadB", "pi0:eff40_May2020", "", path=path_hadB)
202
203
206
207 DcutLoose = '1.7 < M < 2.1'
208 Dcut = '1.830 < M < 1.894'
209 # Reconstructs D0s and sets decay mode identifiers
210 ma.reconstructDecay(decayString='D0:hadB_Kpi -> K-:hadB pi+:hadB', cut=DcutLoose, dmID=1, path=path_hadB)
211 ma.reconstructDecay(decayString='D0:hadB_Kpipi0 -> K-:hadB pi+:hadB pi0:hadB',
212 cut=DcutLoose, dmID=2, path=path_hadB)
213 ma.reconstructDecay(decayString='D0:hadB_Kpipipi -> K-:hadB pi+:hadB pi-:hadB pi+:hadB',
214 cut=DcutLoose, dmID=3, path=path_hadB)
215
216 # Performs mass constrained fit for all D0 candidates
217 vertex.kFit(list_name='D0:hadB_Kpi', conf_level=0.0, fit_type='mass', path=path_hadB)
218 # vertex.kFit(list_name='D0:hadB_Kpipi0', conf_level=0.0, fit_type='mass', path=path_hadB)
219 vertex.kFit(list_name='D0:hadB_Kpipipi', conf_level=0.0, fit_type='mass', path=path_hadB)
220
221 ma.applyCuts("D0:hadB_Kpi", Dcut, path=path_hadB)
222 ma.applyCuts("D0:hadB_Kpipi0", Dcut, path=path_hadB)
223 ma.applyCuts("D0:hadB_Kpipipi", Dcut, path=path_hadB)
224
225 DStarcutLoose = 'massDifference(0) < 0.16'
226
227 # Reconstructs D*-s and sets decay mode identifiers
228 ma.reconstructDecay(decayString='D*+:hadB_D0pi_Kpi -> D0:hadB_Kpi pi+:hadB', cut=DStarcutLoose, dmID=1, path=path_hadB)
229 ma.reconstructDecay(decayString='D*+:hadB_D0pi_Kpipi0 -> D0:hadB_Kpipi0 pi+:hadB',
230 cut=DStarcutLoose, dmID=2, path=path_hadB)
231 ma.reconstructDecay(decayString='D*+:hadB_D0pi_Kpipipi -> D0:hadB_Kpipipi pi+:hadB',
232 cut=DStarcutLoose, dmID=3, path=path_hadB)
233
234 BcutLoose = '[ useCMSFrame(p) < 1.6 ] and [abs(dM) < 0.25]'
235 Bcut = '[ useCMSFrame(p) < 1.2 ] and [abs(dM) < 0.05]'
236
237 # Reconstructs the signal B0 candidates from Dstar
238 ma.reconstructDecay(decayString='B0:hadB_Dstpi_D0pi_Kpi -> D*-:hadB_D0pi_Kpi pi+:hadB',
239 cut=BcutLoose,
240 dmID=1, path=path_hadB)
241 ma.reconstructDecay(decayString='B0:hadB_Dstpi_D0pi_Kpipi0 -> D*-:hadB_D0pi_Kpipi0 pi+:hadB',
242 cut=BcutLoose,
243 dmID=2, path=path_hadB)
244 ma.reconstructDecay(decayString='B0:hadB_Dstpi_D0pi_Kpipipi -> D*-:hadB_D0pi_Kpipipi pi+:hadB',
245 cut=BcutLoose,
246 dmID=3, path=path_hadB)
247
248 vertex.treeFit('B0:hadB_Dstpi_D0pi_Kpi', updateAllDaughters=True, ipConstraint=True, path=path_hadB)
249 vertex.treeFit('B0:hadB_Dstpi_D0pi_Kpipi0', updateAllDaughters=True, ipConstraint=True, path=path_hadB)
250 vertex.treeFit('B0:hadB_Dstpi_D0pi_Kpipipi', updateAllDaughters=True, ipConstraint=True, path=path_hadB)
251
252
255
256 # Reconstructs charged D mesons and sets decay mode identifiers
257 ma.reconstructDecay(decayString='D-:hadB_Kpipi -> K+:hadB pi-:hadB pi-:hadB',
258 cut=DcutLoose, dmID=4, path=path_hadB)
259
260 vertex.kFit(list_name='D-:hadB_Kpipi', conf_level=0.0, fit_type='mass', path=path_hadB)
261 ma.applyCuts("D-:hadB_Kpipi", '1.844 < M < 1.894', path=path_hadB)
262
263 # Reconstructs the signal B candidates
264 ma.reconstructDecay(decayString='B0:hadB_Dpi_Kpipi -> D-:hadB_Kpipi pi+:hadB',
265 cut=BcutLoose, dmID=4, path=path_hadB)
266
267
270
271 # Reconstructs the signal B- candidates
272 ma.reconstructDecay(decayString='B-:hadB_D0pi_Kpi -> D0:hadB_Kpi pi-:hadB',
273 cut=BcutLoose,
274 dmID=5, path=path_hadB)
275 ma.reconstructDecay(decayString='B-:hadB_D0pi_Kpipi0 -> D0:hadB_Kpipi0 pi-:hadB',
276 cut=BcutLoose,
277 dmID=6, path=path_hadB)
278 ma.reconstructDecay(decayString='B-:hadB_D0pi_Kpipipi -> D0:hadB_Kpipipi pi-:hadB',
279 cut=BcutLoose,
280 dmID=7, path=path_hadB)
281
282 vertex.treeFit('B-:hadB_D0pi_Kpi', updateAllDaughters=True, ipConstraint=True, path=path_hadB)
283 vertex.treeFit('B-:hadB_D0pi_Kpipi0', updateAllDaughters=True, ipConstraint=True, path=path_hadB)
284 vertex.treeFit('B-:hadB_D0pi_Kpipipi', updateAllDaughters=True, ipConstraint=True, path=path_hadB)
285
286 ma.copyLists(
287 outputListName='B0:hadB_combined',
288 inputListNames=[
289 'B0:hadB_Dstpi_D0pi_Kpi',
290 'B0:hadB_Dstpi_D0pi_Kpipi0',
291 'B0:hadB_Dstpi_D0pi_Kpipipi',
292 'B0:hadB_Dpi_Kpipi'
293 ],
294 path=path_hadB)
295
296 ma.copyLists(
297 outputListName='B-:hadB_combined',
298 inputListNames=[
299 'B-:hadB_D0pi_Kpi',
300 'B-:hadB_D0pi_Kpipi0',
301 'B-:hadB_D0pi_Kpipipi',
302 ],
303 path=path_hadB)
304
305 # Builds the rest of event object, which contains all particles not used in the reconstruction of B0 candidates.
306 ma.buildRestOfEvent(target_list_name='B0:hadB_combined', path=path_hadB)
307
308 # CleanMask is identical for B0 and B+
309 cleanMask = ('cleanMask', 'nCDCHits > 0 and useCMSFrame(p)<=3.2', 'p >= 0.05 and useCMSFrame(p)<=3.2')
310
311 # Calculates the continuum suppression variables
312 ma.appendROEMasks(list_name='B0:hadB_combined', mask_tuples=[cleanMask], path=path_hadB)
313 ma.buildContinuumSuppression(list_name='B0:hadB_combined', roe_mask='cleanMask', path=path_hadB)
314
315 # Builds the rest of event object, which contains all particles not used in the reconstruction of B- candidates.
316 ma.buildRestOfEvent(target_list_name='B-:hadB_combined', path=path_hadB)
317
318 # Calculates the continuum suppression variables
319 ma.appendROEMasks(list_name='B-:hadB_combined', mask_tuples=[cleanMask], path=path_hadB)
320 ma.buildContinuumSuppression(list_name='B-:hadB_combined', roe_mask='cleanMask', path=path_hadB)
321
322 ma.applyCuts("B0:hadB_combined", "[R2 < 0.3] and " + Bcut, path=path_hadB)
323 ma.applyCuts("B-:hadB_combined", "[R2 < 0.3] and " + Bcut, path=path_hadB)
324
325 MiraBelleEcmsBB = b2.register_module('PhysicsObjectsMiraBelleEcmsBB')
326 MiraBelleEcmsBB.param('B0ListName', 'B0:hadB_combined')
327 MiraBelleEcmsBB.param('BmListName', 'B-:hadB_combined')
328 path_hadB.add_module(MiraBelleEcmsBB)
329
330 return path_hadB
stdKshorts(prioritiseV0=True, fitter='TreeFit', path=None, updateAllDaughters=False, writeOut=False)
Definition stdV0s.py:18
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