Belle II Software  release-08-01-10
B2A713-DeepContinuumSuppression_MVAExpert.py
1 #!/usr/bin/env python3
2 
3 
10 
11 
31 
32 import basf2
33 import modularAnalysis as ma
34 from stdV0s import stdKshorts
35 from stdPi0s import stdPi0s
36 from vertex import TagV
37 import variables as v
38 import sys
39 
40 basf2.set_log_level(basf2.LogLevel.ERROR)
41 
42 # --I/O----------------------------------------------------------------------------------------
43 step = 'signal'
44 
45 if 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 
51 if step == 'signal':
52  input_file_list = [basf2.find_file('Bd2K0spi0_to_test.root', 'examples', False)]
53 elif step == 'qqbar':
54  input_file_list = [basf2.find_file('ccbar_sample_to_test.root', 'examples', False)]
55 else:
56  sys.exit('Step does not match any of the available samples: `signal` or `qqbar`')
57 
58 outfile = 'MVAExpert_fullNTuple_' + step + '.root'
59 # ---------------------------------------------------------------------------------------------
60 
61 main = basf2.create_path()
62 
63 # Perform analysis.
64 ma.inputMdstList(input_file_list, path=main)
65 
66 main.add_module('ProgressBar')
67 
68 # Build B candidate like in B2A701-ContinuumSuppression_Input.py
69 stdKshorts(path=main)
70 stdPi0s('eff40_May2020', path=main)
71 ma.reconstructDecay('B0 -> K_S0:merged pi0:eff40_May2020', '5.2 < Mbc < 5.3 and -0.3 < deltaE < 0.2', path=main)
72 
73 ma.matchMCTruth('B0', path=main)
74 ma.buildRestOfEvent('B0', path=main)
75 
76 cleanMask = ('cleanMask', 'nCDCHits > 0 and useCMSFrame(p)<=3.2', 'p >= 0.05 and useCMSFrame(p)<=3.2')
77 ma.appendROEMasks('B0', [cleanMask], path=main)
78 
79 ma.buildContinuumSuppression('B0', 'cleanMask', path=main)
80 
81 # Accept only correctly reconstructed B candidates as signal
82 ma.applyCuts('B0', 'isSignal or isContinuumEvent', path=main)
83 
84 # Tag B candidate for Vertex information
85 TagV('B0', path=main)
86 
87 # Loop over each possible ROE (1 for every B candidate) in every event
88 roe_path = basf2.create_path()
89 
90 deadEndPath = basf2.create_path()
91 
92 ma.signalSideParticleFilter('B0', '', roe_path, deadEndPath)
93 
94 # Build particle lists for low level variables
95 ma.fillParticleList('gamma:roe', 'isInRestOfEvent == 1 and goodBelleGamma == 1', path=roe_path)
96 ma.fillParticleList('gamma:signal', 'isInRestOfEvent == 0 and goodBelleGamma == 1', path=roe_path)
97 ma.fillParticleList('pi+:chargedProe', 'isInRestOfEvent == 1', path=roe_path)
98 ma.fillParticleList('pi+:chargedPsignal', 'isInRestOfEvent == 0', path=roe_path)
99 ma.fillParticleList('pi-:chargedMroe', 'isInRestOfEvent == 1', path=roe_path)
100 ma.fillParticleList('pi-:chargedMsignal', 'isInRestOfEvent == 0', path=roe_path)
101 
102 v.variables.addAlias('cmsp', 'useCMSFrame(p)')
103 
104 ma.rankByHighest('gamma:roe', 'cmsp', path=roe_path)
105 ma.rankByHighest('gamma:signal', 'cmsp', path=roe_path)
106 ma.rankByHighest('pi+:chargedProe', 'cmsp', path=roe_path)
107 ma.rankByHighest('pi+:chargedPsignal', 'cmsp', path=roe_path)
108 ma.rankByHighest('pi-:chargedMroe', 'cmsp', path=roe_path)
109 ma.rankByHighest('pi-:chargedMsignal', 'cmsp', path=roe_path)
110 
111 # Define traditional Continuum Suppression Variables
112 contVars = [
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
146 basic_variables = ['p', 'phi', 'cosTheta', 'pErr', 'phiErr', 'cosThetaErr']
147 vertex_variables = ['distance', 'dphi', 'dcosTheta']
148 cluster_specific_variables = ['clusterNHits', 'clusterTiming', 'clusterE9E25', 'clusterReg', 'isInRestOfEvent']
149 track_specific_variables = ['kaonID', 'electronID', 'muonID', 'protonID', 'pValue', 'nCDCHits', 'isInRestOfEvent', 'charge']
150 
151 for variablename in basic_variables + vertex_variables:
152  v.variables.addAlias('thrustsig' + variablename, 'useBThrustFrame(' + variablename + ',Signal)')
153 
154 cluster_variables = cluster_specific_variables[:]
155 for variablename in basic_variables:
156  cluster_variables.append('thrustsig' + variablename)
157 
158 track_variables = track_specific_variables
159 for variablename in basic_variables + vertex_variables:
160  track_variables.append('thrustsig' + variablename)
161 
162 variables = ['isContinuumEvent', 'isNotContinuumEvent', 'isSignal', 'M', 'p', 'Mbc', 'DeltaZ',
163  'deltaE', 'daughter(0, M)', 'daughter(0, p)', 'daughter(1, M)', 'daughter(1, p)']
164 for 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 
171 for 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
180 roe_path.add_module('MVAExpert', listNames=['B0'], extraInfoName='Deep_CS', identifier='Deep_Feed_Forward.xml')
181 
182 # Variables from MVAExpert.
183 expertVars = ['extraInfo(Deep_CS)', 'transformedNetworkOutput(Deep_CS,0.1,1.0)']
184 
185 # Create output file with all sets of variables.
186 ma.variablesToNtuple('B0', variables + expertVars, treename='tree', filename=outfile, path=roe_path)
187 
188 main.for_each('RestOfEvent', 'RestOfEvents', roe_path)
189 
190 basf2.process(main)
191 print(basf2.statistics)