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