Belle II Software development
B2A713-DeepContinuumSuppression_MVAExpert.py
1#!/usr/bin/env python3
2
3
10
11
31
32import basf2
33import modularAnalysis as ma
34from stdV0s import stdKshorts
35from stdPi0s import stdPi0s
36from vertex import TagV
37import variables as v
38import sys
39
40basf2.set_log_level(basf2.LogLevel.ERROR)
41
42# --I/O----------------------------------------------------------------------------------------
43step = 'signal'
44
45if len(sys.argv) >= 2:
46 if sys.argv[1] not in ['signal', 'qqbar']:
47 sys.exit("usage:\n\tbasf2 B2A713-DeepContinuumSuppression_MVAExpert.py <signal,qqbar>")
48 else:
49 step = str(sys.argv[1])
50
51if step == 'signal':
52 input_file_list = [basf2.find_file('Bd2K0spi0_to_test.root', 'examples', False)]
53elif step == 'qqbar':
54 input_file_list = [basf2.find_file('ccbar_sample_to_test.root', 'examples', False)]
55else:
56 sys.exit('Step does not match any of the available samples: `signal` or `qqbar`')
57
58outfile = 'MVAExpert_fullNTuple_' + step + '.root'
59# ---------------------------------------------------------------------------------------------
60
61main = basf2.create_path()
62
63# Perform analysis.
64ma.inputMdstList(input_file_list, path=main)
65
66main.add_module('ProgressBar')
67
68# Build B candidate like in B2A701-ContinuumSuppression_Input.py
69stdKshorts(path=main)
70stdPi0s('eff40_May2020', path=main)
71ma.reconstructDecay('B0 -> K_S0:merged pi0:eff40_May2020', '5.2 < Mbc < 5.3 and -0.3 < deltaE < 0.2', path=main)
72
73ma.matchMCTruth('B0', path=main)
74ma.buildRestOfEvent('B0', path=main)
75
76cleanMask = ('cleanMask', 'nCDCHits > 0 and useCMSFrame(p)<=3.2', 'p >= 0.05 and useCMSFrame(p)<=3.2')
77ma.appendROEMasks('B0', [cleanMask], path=main)
78
79ma.buildContinuumSuppression('B0', 'cleanMask', path=main)
80
81# Accept only correctly reconstructed B candidates as signal
82ma.applyCuts('B0', 'isSignal or isContinuumEvent', path=main)
83
84# Tag B candidate for Vertex information
85TagV('B0', path=main)
86
87# Loop over each possible ROE (1 for every B candidate) in every event
88roe_path = basf2.create_path()
89
90deadEndPath = basf2.create_path()
91
92ma.signalSideParticleFilter('B0', '', roe_path, deadEndPath)
93
94# Build particle lists for low level variables
95ma.fillParticleList('gamma:roe', 'isInRestOfEvent == 1 and goodBelleGamma == 1', path=roe_path)
96ma.fillParticleList('gamma:signal', 'isInRestOfEvent == 0 and goodBelleGamma == 1', path=roe_path)
97ma.fillParticleList('pi+:chargedProe', 'isInRestOfEvent == 1', path=roe_path)
98ma.fillParticleList('pi+:chargedPsignal', 'isInRestOfEvent == 0', path=roe_path)
99ma.fillParticleList('pi-:chargedMroe', 'isInRestOfEvent == 1', path=roe_path)
100ma.fillParticleList('pi-:chargedMsignal', 'isInRestOfEvent == 0', path=roe_path)
101
102v.variables.addAlias('cmsp', 'useCMSFrame(p)')
103
104ma.rankByHighest('gamma:roe', 'cmsp', path=roe_path)
105ma.rankByHighest('gamma:signal', 'cmsp', path=roe_path)
106ma.rankByHighest('pi+:chargedProe', 'cmsp', path=roe_path)
107ma.rankByHighest('pi+:chargedPsignal', 'cmsp', path=roe_path)
108ma.rankByHighest('pi-:chargedMroe', 'cmsp', path=roe_path)
109ma.rankByHighest('pi-:chargedMsignal', 'cmsp', path=roe_path)
110
111# Define traditional Continuum Suppression Variables
112contVars = [
113 'R2',
114 'thrustBm',
115 'thrustOm',
116 'cosTBTO',
117 'cosTBz',
118 'KSFWVariables(et)',
119 'KSFWVariables(mm2)',
120 'KSFWVariables(hso00)',
121 'KSFWVariables(hso02)',
122 'KSFWVariables(hso04)',
123 'KSFWVariables(hso10)',
124 'KSFWVariables(hso12)',
125 'KSFWVariables(hso14)',
126 'KSFWVariables(hso20)',
127 'KSFWVariables(hso22)',
128 'KSFWVariables(hso24)',
129 'KSFWVariables(hoo0)',
130 'KSFWVariables(hoo1)',
131 'KSFWVariables(hoo2)',
132 'KSFWVariables(hoo3)',
133 'KSFWVariables(hoo4)',
134 'CleoConeCS(1)',
135 'CleoConeCS(2)',
136 'CleoConeCS(3)',
137 'CleoConeCS(4)',
138 'CleoConeCS(5)',
139 'CleoConeCS(6)',
140 'CleoConeCS(7)',
141 'CleoConeCS(8)',
142 'CleoConeCS(9)'
143]
144
145# Define additional low level variables
146basic_variables = ['p', 'phi', 'cosTheta', 'pErr', 'phiErr', 'cosThetaErr']
147vertex_variables = ['distance', 'dphi', 'dcosTheta']
148cluster_specific_variables = ['clusterNHits', 'clusterTiming', 'clusterE9E25', 'clusterReg', 'isInRestOfEvent']
149track_specific_variables = ['kaonID', 'electronID', 'muonID', 'protonID', 'pValue', 'nCDCHits', 'isInRestOfEvent', 'charge']
150
151for variablename in basic_variables + vertex_variables:
152 v.variables.addAlias('thrustsig' + variablename, 'useBThrustFrame(' + variablename + ',Signal)')
153
154cluster_variables = cluster_specific_variables[:]
155for variablename in basic_variables:
156 cluster_variables.append('thrustsig' + variablename)
157
158track_variables = track_specific_variables
159for variablename in basic_variables + vertex_variables:
160 track_variables.append('thrustsig' + variablename)
161
162variables = ['isContinuumEvent', 'isNotContinuumEvent', 'isSignal', 'M', 'p', 'Mbc', 'DeltaZ',
163 'deltaE', 'daughter(0, M)', 'daughter(0, p)', 'daughter(1, M)', 'daughter(1, p)']
164for rank in range(10):
165 for shortcut, particlelist in [('Croe', 'gamma:roe'), ('Csig', 'gamma:signal')]:
166 for variable in cluster_variables:
167 v.variables.addAlias(
168 f'{variable}_{shortcut}{rank}', f'getVariableByRank({particlelist}, cmsp, {variable}, {rank + 1})')
169 variables.append(f'{variable}_{shortcut}{rank}')
170
171for rank in range(5):
172 for shortcut, particlelist in [('TProe', 'pi+:chargedProe'), ('TPsig', 'pi+:chargedPsignal'),
173 ('TMroe', 'pi+:chargedMroe'), ('TMsig', 'pi+:chargedMsignal')]:
174 for variable in track_variables:
175 v.variables.addAlias(
176 f'{variable}_{shortcut}{rank}', f'getVariableByRank({particlelist}, cmsp, {variable}, {rank + 1})')
177 variables.append(f'{variable}_{shortcut}{rank}')
178
179# MVAExpert
180roe_path.add_module('MVAExpert', listNames=['B0'], extraInfoName='Deep_CS', identifier='Deep_Feed_Forward.xml')
181
182# Variables from MVAExpert.
183expertVars = ['extraInfo(Deep_CS)', 'transformedNetworkOutput(Deep_CS,0.1,1.0)']
184
185# Create output file with all sets of variables.
186ma.variablesToNtuple('B0', variables + expertVars, treename='tree', filename=outfile, path=roe_path)
187
188main.for_each('RestOfEvent', 'RestOfEvents', roe_path)
189
190basf2.process(main)
191print(basf2.statistics)