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