32 pybasf2.Module.__eq__ =
lambda a, b: a.type() == b.type()
and\
33 all(x == y
for x, y
in zip(a.available_params(), b.available_params()))
34 pybasf2.ModuleParamInfo.__eq__ =
lambda a, b: a.name == b.name
and a.values == b.values
35 pybasf2.Path.__eq__ =
lambda a, b: all(x == y
for x, y
in zip(a.modules(), b.modules()))
40 Print the parts of the paths which are different
42 for x, y
in zip(a.modules(), b.modules()):
43 if x.type() != y.type():
44 print(x.type(), y.type())
45 for n, m
in zip(x.available_params(), y.available_params()):
48 if n.values != m.values:
49 print(n.name, n.values, m.values)
52 def get_small_unittest_channels():
53 pion = Particle(
'pi+',
54 fei.config.MVAConfiguration(variables=[
'p',
'dr'],
55 target=
'isPrimarySignal'),
56 fei.config.PreCutConfiguration(userCut=
'[dr < 2] and [abs(dz) < 4]',
57 bestCandidateMode=
'highest',
58 bestCandidateVariable=
'piid',
60 fei.config.PostCutConfiguration(bestCandidateCut=10, value=0.01))
61 pion.addChannel([
'pi+:FSP'])
64 fei.config.MVAConfiguration(variables=[
'p',
'dr'],
65 target=
'isPrimarySignal'),
66 fei.config.PreCutConfiguration(userCut=
'[dr < 2] and [abs(dz) < 4]',
67 bestCandidateMode=
'highest',
68 bestCandidateVariable=
'Kid',
70 fei.config.PostCutConfiguration(bestCandidateCut=10, value=0.01))
71 kaon.addChannel([
'K+:FSP'])
74 fei.config.MVAConfiguration(variables=[
'M',
'p'],
76 fei.config.PreCutConfiguration(userCut=
'1.7 < M < 1.95',
77 bestCandidateMode=
'lowest',
78 bestCandidateVariable=
'abs(dM)',
80 fei.config.PostCutConfiguration(bestCandidateCut=10, value=0.001))
81 D0.addChannel([
'K-',
'pi+'])
82 D0.addChannel([
'pi-',
'pi+'])
84 particles = [pion, kaon, D0]
88 class TestGetStagesFromParticles(unittest.TestCase):
89 def test_get_stages_from_particles(self):
90 particles = fei.get_unittest_channels()
91 stages = fei.core.get_stages_from_particles(particles)
92 self.assertEqual(len(stages), 7)
93 self.assertEqual(len(stages[0]), 4)
94 self.assertEqual(stages[0][0].identifier,
'gamma:generic')
95 self.assertEqual(stages[0][1].identifier,
'mu+:generic')
96 self.assertEqual(stages[0][2].identifier,
'pi+:generic')
97 self.assertEqual(stages[0][3].identifier,
'K+:generic')
98 self.assertEqual(len(stages[1]), 1)
99 self.assertEqual(stages[1][0].identifier,
'pi0:generic')
100 self.assertEqual(len(stages[2]), 0)
101 self.assertEqual(len(stages[3]), 2)
102 self.assertEqual(stages[3][0].identifier,
'D0:generic')
103 self.assertEqual(stages[3][1].identifier,
'D0:semileptonic')
104 self.assertEqual(len(stages[4]), 0)
105 self.assertEqual(len(stages[5]), 0)
106 self.assertEqual(len(stages[6]), 0)
109 class TestTrainingDataInformation(unittest.TestCase):
112 if os.path.isfile(
'mcParticlesCount.root'):
113 os.remove(
'mcParticlesCount.root')
115 def test_reconstruct(self):
116 particles = fei.get_unittest_channels()
117 x = fei.core.TrainingDataInformation(particles)
119 path = basf2.create_path()
120 path.add_module(
'VariablesToHistogram', fileName=
'mcParticlesCount.root',
122 (
'NumberOfMCParticlesInEvent(321)', 100, -0.5, 99.5),
123 (
'NumberOfMCParticlesInEvent(421)', 100, -0.5, 99.5),
124 (
'NumberOfMCParticlesInEvent(13)', 100, -0.5, 99.5),
125 (
'NumberOfMCParticlesInEvent(111)', 100, -0.5, 99.5),
126 (
'NumberOfMCParticlesInEvent(211)', 100, -0.5, 99.5),
127 (
'NumberOfMCParticlesInEvent(22)', 100, -0.5, 99.5)]
129 print_path(path, x.reconstruct())
130 self.assertEqual(x.reconstruct(), path)
132 def test_available(self):
133 particles = fei.get_unittest_channels()
134 x = fei.core.TrainingDataInformation(particles)
135 self.assertEqual(x.available(),
False)
136 f = ROOT.TFile(
'mcParticlesCount.root',
'RECREATE')
137 self.assertEqual(x.available(),
True)
139 def test_get_mc_counts(self):
140 f = ROOT.TFile(
'mcParticlesCount.root',
'RECREATE')
142 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo211__bc",
"NumberOfMCParticlesInEvent__bo211__bc", 11, -0.5, 10.5)
149 f.Write(
"NumberOfMCParticlesInEvent__bo211__bc")
151 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo321__bc",
"NumberOfMCParticlesInEvent__bo321__bc", 11, -0.5, 10.5)
158 f.Write(
"NumberOfMCParticlesInEvent__bo321__bc")
160 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo13__bc",
"NumberOfMCParticlesInEvent__bo13__bc", 11, -0.5, 10.5)
163 f.Write(
"NumberOfMCParticlesInEvent__bo13__bc")
165 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo22__bc",
"NumberOfMCParticlesInEvent__bo222__bc", 11, -0.5, 10.5)
168 f.Write(
"NumberOfMCParticlesInEvent__bo22__bc")
170 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo111__bc",
"NumberOfMCParticlesInEvent__bo111__bc", 11, -0.5, 10.5)
177 f.Write(
"NumberOfMCParticlesInEvent__bo111__bc")
179 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo421__bc",
"NumberOfMCParticlesInEvent__bo421__bc", 11, -0.5, 10.5)
186 f.Write(
"NumberOfMCParticlesInEvent__bo421__bc")
188 particles = fei.get_unittest_channels()
189 x = fei.core.TrainingDataInformation(particles)
192 211: {
'max': 5.0,
'min': 3.0,
'sum': 79.0,
'avg': 4.3888888888888893,
'std': 0.7556372504852998},
193 321: {
'max': 7.0,
'min': 2.0,
'sum': 77.0,
'avg': 4.2777777777777777,
'std': 1.8798804795209585},
194 13: {
'max': 5.0,
'min': 5.0,
'sum': 90.0,
'avg': 5.0,
'std': 0.0},
195 22: {
'max': 0.0,
'min': 0.0,
'sum': 0.0,
'avg': 0.0,
'std': 0.0},
196 111: {
'max': 5.0,
'min': 3.0,
'sum': 74.0,
'avg': 4.1111111111111107,
'std': 0.6573421981221816},
197 421: {
'max': 9.0,
'min': 0.0,
'sum': 93.0,
'avg': 5.166666666666667,
'std': 4.2979323194092087},
199 self.assertDictEqual(x.get_mc_counts(), mcCounts)
202 class TestFSPLoader(unittest.TestCase):
204 def test_belle2_without_monitoring(self):
205 particles = get_small_unittest_channels()
206 config = fei.config.FeiConfiguration(monitor=
False)
207 x = fei.core.FSPLoader(particles, config)
209 path = basf2.create_path()
210 fsps = [
'K+:FSP',
'pi+:FSP',
'e+:FSP',
'mu+:FSP',
'gamma:FSP',
'p+:FSP',
'K_L0:FSP']
211 path.add_module(
'ParticleLoader', decayStrings=fsps, writeOut=
True)
213 path.add_module(
'ParticleListManipulator', outputListName=fsp,
214 inputListNames=[fsp.split(
':')[0] +
':all'], writeOut=
True)
216 path.add_module(
'ParticleSelector', decayString=
'gamma:FSP', cut=
'isFromECL')
217 path.add_module(
'ParticleLoader', decayStrings=[
'K_S0:V0 -> pi+ pi-'], writeOut=
True)
218 path.add_module(
'ParticleLoader', decayStrings=[
'Lambda0:V0 -> p+ pi-'], writeOut=
True)
219 path.add_module(
'ParticleLoader', decayStrings=[
'gamma:V0 -> e+ e-'], addDaughters=
True, writeOut=
True)
220 print_path(path, x.reconstruct())
221 self.assertEqual(x.reconstruct(), path)
223 def test_belle2_with_monitoring(self):
224 particles = get_small_unittest_channels()
225 config = fei.config.FeiConfiguration(monitor=
True)
226 x = fei.core.FSPLoader(particles, config)
228 path = basf2.create_path()
229 fsps = [
'K+:FSP',
'pi+:FSP',
'e+:FSP',
'mu+:FSP',
'gamma:FSP',
'p+:FSP',
'K_L0:FSP']
230 path.add_module(
'ParticleLoader', decayStrings=fsps, writeOut=
True)
232 path.add_module(
'ParticleListManipulator', outputListName=fsp,
233 inputListNames=[fsp.split(
':')[0] +
':all'], writeOut=
True)
235 path.add_module(
'ParticleSelector', decayString=
'gamma:FSP', cut=
'isFromECL')
236 path.add_module(
'ParticleLoader', decayStrings=[
'K_S0:V0 -> pi+ pi-'], writeOut=
True)
237 path.add_module(
'ParticleLoader', decayStrings=[
'Lambda0:V0 -> p+ pi-'], writeOut=
True)
238 path.add_module(
'ParticleLoader', decayStrings=[
'gamma:V0 -> e+ e-'], addDaughters=
True, writeOut=
True)
239 hist_variables = [(f
'NumberOfMCParticlesInEvent({pdgcode})', 100, -0.5, 99.5)
240 for pdgcode
in {11, 321, 211, 13, 22, 310, 2212, 130, 3122, 111}]
241 path.add_module(
'VariablesToHistogram', particleList=
'',
242 variables=hist_variables,
243 fileName=
'Monitor_FSPLoader.root')
244 print_path(path, x.reconstruct())
245 self.assertEqual(x.reconstruct(), path)
247 def test_belle1_without_monitoring(self):
248 particles = get_small_unittest_channels()
250 config = fei.config.FeiConfiguration(monitor=
False)
251 x = fei.core.FSPLoader(particles, config)
253 path = basf2.create_path()
254 fsps = [
'K+:FSP',
'pi+:FSP',
'e+:FSP',
'mu+:FSP',
'p+:FSP']
255 path.add_module(
'ParticleLoader', decayStrings=fsps, writeOut=
True)
257 path.add_module(
'ParticleListManipulator', outputListName=fsp,
258 inputListNames=[fsp.split(
':')[0] +
':all'], writeOut=
True)
259 path.add_module(
'ParticleListManipulator', outputListName=
'gamma:FSP', inputListNames=[
'gamma:mdst'], writeOut=
True)
260 path.add_module(
'ParticleCopier', inputListNames=[
'gamma:FSP'])
261 path.add_module(
'ParticleListManipulator', outputListName=
'K_S0:V0', inputListNames=[
'K_S0:mdst'], writeOut=
True)
262 path.add_module(
'ParticleCopier', inputListNames=[
'K_S0:V0'])
263 path.add_module(
'ParticleListManipulator', outputListName=
'Lambda0:V0', inputListNames=[
'Lambda0:mdst'], writeOut=
True)
264 path.add_module(
'ParticleCopier', inputListNames=[
'Lambda0:V0'])
265 path.add_module(
'ParticleListManipulator', outputListName=
'K_L0:FSP', inputListNames=[
'K_L0:mdst'], writeOut=
True)
266 path.add_module(
'ParticleCopier', inputListNames=[
'K_L0:FSP'])
267 path.add_module(
'ParticleListManipulator', outputListName=
'pi0:FSP', inputListNames=[
'pi0:mdst'], writeOut=
True)
268 path.add_module(
'ParticleCopier', inputListNames=[
'pi0:FSP'])
269 path.add_module(
'ParticleListManipulator', outputListName=
'gamma:V0', inputListNames=[
'gamma:v0mdst'], writeOut=
True)
270 path.add_module(
'ParticleCopier', inputListNames=[
'gamma:V0'])
271 print_path(path, x.reconstruct())
272 self.assertEqual(x.reconstruct(), path)
275 def test_belle1_with_monitoring(self):
276 particles = get_small_unittest_channels()
278 config = fei.config.FeiConfiguration(monitor=
True)
279 x = fei.core.FSPLoader(particles, config)
281 path = basf2.create_path()
282 fsps = [
'K+:FSP',
'pi+:FSP',
'e+:FSP',
'mu+:FSP',
'p+:FSP']
283 path.add_module(
'ParticleLoader', decayStrings=fsps, writeOut=
True)
285 path.add_module(
'ParticleListManipulator', outputListName=fsp,
286 inputListNames=[fsp.split(
':')[0] +
':all'], writeOut=
True)
287 path.add_module(
'ParticleListManipulator', outputListName=
'gamma:FSP', inputListNames=[
'gamma:mdst'], writeOut=
True)
288 path.add_module(
'ParticleCopier', inputListNames=[
'gamma:FSP'])
289 path.add_module(
'ParticleListManipulator', outputListName=
'K_S0:V0', inputListNames=[
'K_S0:mdst'], writeOut=
True)
290 path.add_module(
'ParticleCopier', inputListNames=[
'K_S0:V0'])
291 path.add_module(
'ParticleListManipulator', outputListName=
'Lambda0:V0', inputListNames=[
'Lambda0:mdst'], writeOut=
True)
292 path.add_module(
'ParticleCopier', inputListNames=[
'Lambda0:V0'])
293 path.add_module(
'ParticleListManipulator', outputListName=
'K_L0:FSP', inputListNames=[
'K_L0:mdst'], writeOut=
True)
294 path.add_module(
'ParticleCopier', inputListNames=[
'K_L0:FSP'])
295 path.add_module(
'ParticleListManipulator', outputListName=
'pi0:FSP', inputListNames=[
'pi0:mdst'], writeOut=
True)
296 path.add_module(
'ParticleCopier', inputListNames=[
'pi0:FSP'])
297 path.add_module(
'ParticleListManipulator', outputListName=
'gamma:V0', inputListNames=[
'gamma:v0mdst'], writeOut=
True)
298 path.add_module(
'ParticleCopier', inputListNames=[
'gamma:V0'])
299 hist_variables = [(f
'NumberOfMCParticlesInEvent({pdgcode})', 100, -0.5, 99.5)
300 for pdgcode
in {11, 321, 211, 13, 22, 310, 2212, 130, 3122, 111}]
301 path.add_module(
'VariablesToHistogram', particleList=
'',
302 variables=hist_variables,
303 fileName=
'Monitor_FSPLoader.root')
304 print_path(path, x.reconstruct())
305 self.assertEqual(x.reconstruct(), path)
309 class TestTrainingData(unittest.TestCase):
313 211: {
'sum': 79,
'avg': 4.3888888888888893,
'max': 5,
'min': 3,
'std': 0.75563725048530228},
314 321: {
'sum': 77,
'avg': 4.2777777777777777,
'max': 7,
'min': 2,
'std': 1.8798804795209592},
315 421: {
'sum': 93,
'avg': 5.166666666666667,
'max': 9,
'min': 0,
'std': 4.2979323194092087},
318 def test_without_monitoring(self):
319 particles = get_small_unittest_channels()
320 config = fei.config.FeiConfiguration(monitor=
False)
321 x = fei.core.TrainingData(particles, config, self.mc_counts)
323 path = basf2.create_path()
324 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root', treeName=
'pi+:generic ==> pi+:FSP variables',
325 variables=[
'p',
'dr',
'isPrimarySignal'],
326 particleList=
'pi+:generic_0', sampling=(
'isPrimarySignal', {}))
327 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root', treeName=
'K+:generic ==> K+:FSP variables',
328 variables=[
'p',
'dr',
'isPrimarySignal'],
329 particleList=
'K+:generic_0', sampling=(
'isPrimarySignal', {}))
330 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root',
331 treeName=
'D0:generic ==> K-:generic pi+:generic variables',
332 variables=[
'M',
'p',
'isSignal'],
333 particleList=
'D0:generic_0', sampling=(
'isSignal', {}))
334 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root',
335 treeName=
'D0:generic ==> pi-:generic pi+:generic variables',
336 variables=[
'M',
'p',
'isSignal'],
337 particleList=
'D0:generic_1', sampling=(
'isSignal', {}))
338 print_path(path, x.reconstruct())
339 self.assertEqual(x.reconstruct(), path)
341 def test_with_monitoring(self):
342 particles = get_small_unittest_channels()
343 config = fei.config.FeiConfiguration(monitor=
True)
344 x = fei.core.TrainingData(particles, config, self.mc_counts)
346 path = basf2.create_path()
347 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic_0',
348 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'p',
'dr',
'isPrimarySignal']),
349 variables_2d=fei.config.variables2binnings_2d([(
'p',
'isPrimarySignal'), (
'dr',
'isPrimarySignal')]),
350 fileName=
'Monitor_TrainingData.root', directory=
'pi+:generic ==> pi+:FSP')
351 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root', treeName=
'pi+:generic ==> pi+:FSP variables',
352 variables=[
'p',
'dr',
'isPrimarySignal'],
353 particleList=
'pi+:generic_0', sampling=(
'isPrimarySignal', {}))
354 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic_0',
355 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'p',
'dr',
'isPrimarySignal']),
356 variables_2d=fei.config.variables2binnings_2d([(
'p',
'isPrimarySignal'), (
'dr',
'isPrimarySignal')]),
357 fileName=
'Monitor_TrainingData.root', directory=
'K+:generic ==> K+:FSP')
358 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root', treeName=
'K+:generic ==> K+:FSP variables',
359 variables=[
'p',
'dr',
'isPrimarySignal'],
360 particleList=
'K+:generic_0', sampling=(
'isPrimarySignal', {}))
361 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_0',
362 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'M',
'p',
'isSignal']),
363 variables_2d=fei.config.variables2binnings_2d([(
'M',
'isSignal'), (
'p',
'isSignal')]),
364 fileName=
'Monitor_TrainingData.root', directory=
'D0:generic ==> K-:generic pi+:generic')
365 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root',
366 treeName=
'D0:generic ==> K-:generic pi+:generic variables',
367 variables=[
'M',
'p',
'isSignal'],
368 particleList=
'D0:generic_0', sampling=(
'isSignal', {}))
369 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_1',
370 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'M',
'p',
'isSignal']),
371 variables_2d=fei.config.variables2binnings_2d([(
'M',
'isSignal'), (
'p',
'isSignal')]),
372 fileName=
'Monitor_TrainingData.root', directory=
'D0:generic ==> pi-:generic pi+:generic')
373 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root',
374 treeName=
'D0:generic ==> pi-:generic pi+:generic variables',
375 variables=[
'M',
'p',
'isSignal'],
376 particleList=
'D0:generic_1', sampling=(
'isSignal', {}))
377 print_path(path, x.reconstruct())
378 self.assertEqual(x.reconstruct(), path)
381 class TestPreReconstruction(unittest.TestCase):
383 def test_without_monitoring(self):
384 particles = get_small_unittest_channels()
385 config = fei.config.FeiConfiguration(monitor=
False)
386 x = fei.core.PreReconstruction(particles, config)
388 path = basf2.create_path()
389 path.add_module(
'ParticleListManipulator', inputListNames=[
'pi+:FSP'], outputListName=
'pi+:generic_0',
390 cut=
'[dr < 2] and [abs(dz) < 4]', writeOut=
True)
391 path.add_module(
'VariablesToExtraInfo', particleList=
'pi+:generic_0', variables={
'constant(0)':
'decayModeID'})
392 path.add_module(
'BestCandidateSelection', particleList=
'pi+:generic_0', variable=
'piid', selectLowest=
False,
393 numBest=20, outputVariable=
'preCut_rank')
395 path.add_module(
'ParticleListManipulator', inputListNames=[
'K+:FSP'], outputListName=
'K+:generic_0',
396 cut=
'[dr < 2] and [abs(dz) < 4]', writeOut=
True)
397 path.add_module(
'VariablesToExtraInfo', particleList=
'K+:generic_0', variables={
'constant(0)':
'decayModeID'})
398 path.add_module(
'BestCandidateSelection', particleList=
'K+:generic_0', variable=
'Kid', selectLowest=
False,
399 numBest=20, outputVariable=
'preCut_rank')
401 path.add_module(
'ParticleCombiner', decayString=
'D0:generic_0 -> K-:generic pi+:generic', writeOut=
True,
402 decayMode=0, cut=
'1.7 < M < 1.95')
403 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic_0',
404 variable=
'abs(dM)', selectLowest=
True, numBest=20, outputVariable=
'preCut_rank')
405 path.add_module(
'ParticleVertexFitter', listName=
'D0:generic_0', confidenceLevel=-2.0,
406 vertexFitter=
'KFit', fitType=
'vertex')
408 path.add_module(
'ParticleCombiner', decayString=
'D0:generic_1 -> pi-:generic pi+:generic', writeOut=
True,
409 decayMode=1, cut=
'1.7 < M < 1.95')
410 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic_1',
411 variable=
'abs(dM)', selectLowest=
True, numBest=20, outputVariable=
'preCut_rank')
412 path.add_module(
'ParticleVertexFitter', listName=
'D0:generic_1', confidenceLevel=-2.0,
413 vertexFitter=
'KFit', fitType=
'vertex')
415 print_path(path, x.reconstruct())
416 self.assertEqual(x.reconstruct(), path)
418 def test_with_monitoring(self):
419 particles = get_small_unittest_channels()
420 config = fei.config.FeiConfiguration(monitor=
True)
421 x = fei.core.PreReconstruction(particles, config)
423 path = basf2.create_path()
424 path.add_module(
'ParticleListManipulator', inputListNames=[
'pi+:FSP'], outputListName=
'pi+:generic_0',
425 cut=
'[dr < 2] and [abs(dz) < 4]', writeOut=
True)
426 path.add_module(
'VariablesToExtraInfo', particleList=
'pi+:generic_0', variables={
'constant(0)':
'decayModeID'})
427 path.add_module(
'MCMatcherParticles', listName=
'pi+:generic_0')
428 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic_0',
429 variables=fei.config.variables2binnings([
'piid',
'mcErrors',
'mcParticleStatus',
'isPrimarySignal']),
430 variables_2d=fei.config.variables2binnings_2d([(
'piid',
'isPrimarySignal'),
431 (
'piid',
'mcErrors'),
432 (
'piid',
'mcParticleStatus')]),
433 fileName=
'Monitor_PreReconstruction_BeforeRanking.root', directory=
'pi+:generic ==> pi+:FSP')
434 path.add_module(
'BestCandidateSelection', particleList=
'pi+:generic_0', variable=
'piid', selectLowest=
False,
435 numBest=20, outputVariable=
'preCut_rank')
436 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic_0',
437 variables=fei.config.variables2binnings([
'piid',
'mcErrors',
'mcParticleStatus',
438 'isPrimarySignal',
'extraInfo(preCut_rank)']),
439 variables_2d=fei.config.variables2binnings_2d([(
'piid',
'isPrimarySignal'),
440 (
'piid',
'mcErrors'),
441 (
'piid',
'mcParticleStatus'),
442 (
'extraInfo(preCut_rank)',
'isPrimarySignal'),
443 (
'extraInfo(preCut_rank)',
'mcErrors'),
444 (
'extraInfo(preCut_rank)',
'mcParticleStatus')]),
445 fileName=
'Monitor_PreReconstruction_AfterRanking.root', directory=
'pi+:generic ==> pi+:FSP')
446 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic_0',
447 variables=fei.config.variables2binnings([
'chiProb',
'mcErrors',
'mcParticleStatus',
449 variables_2d=fei.config.variables2binnings_2d([(
'chiProb',
'isPrimarySignal'),
450 (
'chiProb',
'mcErrors'),
451 (
'chiProb',
'mcParticleStatus')]),
452 fileName=
'Monitor_PreReconstruction_AfterVertex.root', directory=
'pi+:generic ==> pi+:FSP')
454 path.add_module(
'ParticleListManipulator', inputListNames=[
'K+:FSP'], outputListName=
'K+:generic_0',
455 cut=
'[dr < 2] and [abs(dz) < 4]', writeOut=
True)
456 path.add_module(
'VariablesToExtraInfo', particleList=
'K+:generic_0', variables={
'constant(0)':
'decayModeID'})
458 path.add_module(
'MCMatcherParticles', listName=
'K+:generic_0')
459 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic_0',
460 variables=fei.config.variables2binnings([
'Kid',
'mcErrors',
'mcParticleStatus',
'isPrimarySignal']),
461 variables_2d=fei.config.variables2binnings_2d([(
'Kid',
'isPrimarySignal'),
463 (
'Kid',
'mcParticleStatus')]),
464 fileName=
'Monitor_PreReconstruction_BeforeRanking.root', directory=
'K+:generic ==> K+:FSP')
465 path.add_module(
'BestCandidateSelection', particleList=
'K+:generic_0', variable=
'Kid', selectLowest=
False,
466 numBest=20, outputVariable=
'preCut_rank')
467 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic_0',
468 variables=fei.config.variables2binnings([
'Kid',
'mcErrors',
'mcParticleStatus',
469 'isPrimarySignal',
'extraInfo(preCut_rank)']),
470 variables_2d=fei.config.variables2binnings_2d([(
'Kid',
'isPrimarySignal'),
472 (
'Kid',
'mcParticleStatus'),
473 (
'extraInfo(preCut_rank)',
'isPrimarySignal'),
474 (
'extraInfo(preCut_rank)',
'mcErrors'),
475 (
'extraInfo(preCut_rank)',
'mcParticleStatus')]),
476 fileName=
'Monitor_PreReconstruction_AfterRanking.root', directory=
'K+:generic ==> K+:FSP')
477 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic_0',
478 variables=fei.config.variables2binnings([
'chiProb',
'mcErrors',
'mcParticleStatus',
480 variables_2d=fei.config.variables2binnings_2d([(
'chiProb',
'isPrimarySignal'),
481 (
'chiProb',
'mcErrors'),
482 (
'chiProb',
'mcParticleStatus')]),
483 fileName=
'Monitor_PreReconstruction_AfterVertex.root', directory=
'K+:generic ==> K+:FSP')
485 path.add_module(
'ParticleCombiner', decayString=
'D0:generic_0 -> K-:generic pi+:generic', writeOut=
True,
486 decayMode=0, cut=
'1.7 < M < 1.95')
487 path.add_module(
'MCMatcherParticles', listName=
'D0:generic_0')
488 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_0',
489 variables=fei.config.variables2binnings([
'abs(dM)',
'mcErrors',
'mcParticleStatus',
'isSignal']),
490 variables_2d=fei.config.variables2binnings_2d([(
'abs(dM)',
'isSignal'),
491 (
'abs(dM)',
'mcErrors'),
492 (
'abs(dM)',
'mcParticleStatus')]),
493 fileName=
'Monitor_PreReconstruction_BeforeRanking.root', directory=
'D0:generic ==> K-:generic pi+:generic')
494 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic_0',
495 variable=
'abs(dM)', selectLowest=
True, numBest=20, outputVariable=
'preCut_rank')
496 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_0',
497 variables=fei.config.variables2binnings([
'abs(dM)',
'mcErrors',
'mcParticleStatus',
498 'isSignal',
'extraInfo(preCut_rank)']),
499 variables_2d=fei.config.variables2binnings_2d([(
'abs(dM)',
'isSignal'),
500 (
'abs(dM)',
'mcErrors'),
501 (
'abs(dM)',
'mcParticleStatus'),
502 (
'extraInfo(preCut_rank)',
'isSignal'),
503 (
'extraInfo(preCut_rank)',
'mcErrors'),
504 (
'extraInfo(preCut_rank)',
'mcParticleStatus')]),
505 fileName=
'Monitor_PreReconstruction_AfterRanking.root', directory=
'D0:generic ==> K-:generic pi+:generic')
506 path.add_module(
'ParticleVertexFitter', listName=
'D0:generic_0', confidenceLevel=-2.0,
507 vertexFitter=
'KFit', fitType=
'vertex')
508 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_0',
509 variables=fei.config.variables2binnings([
'chiProb',
'mcErrors',
'mcParticleStatus',
511 variables_2d=fei.config.variables2binnings_2d([(
'chiProb',
'isSignal'),
512 (
'chiProb',
'mcErrors'),
513 (
'chiProb',
'mcParticleStatus')]),
514 fileName=
'Monitor_PreReconstruction_AfterVertex.root', directory=
'D0:generic ==> K-:generic pi+:generic')
516 path.add_module(
'ParticleCombiner', decayString=
'D0:generic_1 -> pi-:generic pi+:generic', writeOut=
True,
517 decayMode=1, cut=
'1.7 < M < 1.95')
518 path.add_module(
'MCMatcherParticles', listName=
'D0:generic_1')
519 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_1',
520 variables=fei.config.variables2binnings([
'abs(dM)',
'mcErrors',
'mcParticleStatus',
'isSignal']),
521 variables_2d=fei.config.variables2binnings_2d([(
'abs(dM)',
'isSignal'),
522 (
'abs(dM)',
'mcErrors'),
523 (
'abs(dM)',
'mcParticleStatus')]),
524 fileName=
'Monitor_PreReconstruction_BeforeRanking.root', directory=
'D0:generic ==> pi-:generic pi+:generic')
525 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic_1',
526 variable=
'abs(dM)', selectLowest=
True, numBest=20, outputVariable=
'preCut_rank')
527 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_1',
528 variables=fei.config.variables2binnings([
'abs(dM)',
'mcErrors',
'mcParticleStatus',
529 'isSignal',
'extraInfo(preCut_rank)']),
530 variables_2d=fei.config.variables2binnings_2d([(
'abs(dM)',
'isSignal'),
531 (
'abs(dM)',
'mcErrors'),
532 (
'abs(dM)',
'mcParticleStatus'),
533 (
'extraInfo(preCut_rank)',
'isSignal'),
534 (
'extraInfo(preCut_rank)',
'mcErrors'),
535 (
'extraInfo(preCut_rank)',
'mcParticleStatus')]),
536 fileName=
'Monitor_PreReconstruction_AfterRanking.root', directory=
'D0:generic ==> pi-:generic pi+:generic')
537 path.add_module(
'ParticleVertexFitter', listName=
'D0:generic_1', confidenceLevel=-2.0,
538 vertexFitter=
'KFit', fitType=
'vertex')
539 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_1',
540 variables=fei.config.variables2binnings([
'chiProb',
'mcErrors',
'mcParticleStatus',
542 variables_2d=fei.config.variables2binnings_2d([(
'chiProb',
'isSignal'),
543 (
'chiProb',
'mcErrors'),
544 (
'chiProb',
'mcParticleStatus')]),
545 fileName=
'Monitor_PreReconstruction_AfterVertex.root', directory=
'D0:generic ==> pi-:generic pi+:generic')
547 print_path(path, x.reconstruct())
548 self.assertEqual(x.reconstruct(), path)
551 class TestPostReconstruction(unittest.TestCase):
553 def test_get_missing_channels(self):
554 pion = Particle(
'pi+:unittest', fei.config.MVAConfiguration(variables=[
'p',
'dr'], target=
'isPrimarySignal'))
555 pion.addChannel([
'pi+:FSP'])
556 D0 = Particle(
'D0:unittest', fei.config.MVAConfiguration(variables=[
'M',
'p'], target=
'isSignal'))
557 D0.addChannel([
'K-:unittest',
'pi+:unittest'])
558 D0.addChannel([
'pi-:unittest',
'pi+:unittest'])
559 config = fei.config.FeiConfiguration(monitor=
False, prefix=
"UNITTEST")
560 x = fei.core.PostReconstruction([pion, D0], config)
562 self.assertEqual(x.get_missing_channels(), [
'pi+:unittest ==> pi+:FSP',
'D0:unittest ==> K-:unittest pi+:unittest',
563 'D0:unittest ==> pi-:unittest pi+:unittest'])
564 self.assertEqual(x.available(),
False)
567 <?xml version="1.0" encoding="utf-8"?>
568 <method>Trivial</method>
569 <weightfile>{channel}.xml</weightfile>
570 <treename>tree</treename>
571 <target_variable>isSignal</target_variable>
572 <weight_variable>__weight__</weight_variable>
573 <signal_class>1</signal_class>
574 <max_events>0</max_events>
575 <number_feature_variables>1</number_feature_variables>
576 <variable0>M</variable0>
577 <number_spectator_variables>0</number_spectator_variables>
578 <number_data_files>1</number_data_files>
579 <datafile0>train.root</datafile0>
580 <Trivial_version>1</Trivial_version>
581 <Trivial_output>0</Trivial_output>
582 <signal_fraction>0.066082567</signal_fraction>
585 channel =
'D0:unittest ==> K-:unittest pi+:unittest'
586 with open(channel +
".xml",
"w")
as f:
587 f.write(content.format(channel=channel))
588 basf2_mva.upload(channel +
".xml",
'UNITTEST_' + channel)
590 self.assertEqual(x.get_missing_channels(), [
'pi+:unittest ==> pi+:FSP',
591 'D0:unittest ==> pi-:unittest pi+:unittest'])
592 self.assertEqual(x.available(),
False)
594 channel =
'D0:unittest ==> pi-:unittest pi+:unittest'
595 with open(channel +
".xml",
"w")
as f:
596 f.write(content.format(channel=channel))
597 basf2_mva.upload(channel +
".xml",
'UNITTEST_' + channel)
599 self.assertEqual(x.get_missing_channels(), [
'pi+:unittest ==> pi+:FSP'])
600 self.assertEqual(x.available(),
False)
602 channel =
'pi+:unittest ==> pi+:FSP'
603 with open(channel +
".xml",
"w")
as f:
604 f.write(content.format(channel=channel))
605 basf2_mva.upload(channel +
".xml",
'UNITTEST_' + channel)
607 self.assertEqual(x.get_missing_channels(), [])
608 self.assertEqual(x.available(),
True)
611 if os.path.isfile(
'pi+:unittest ==> pi+:FSP.xml'):
612 os.remove(
'pi+:unittest ==> pi+:FSP.xml')
613 if os.path.isfile(
'D0:unittest ==> pi-:unittest pi+:unittest.xml'):
614 os.remove(
'D0:unittest ==> pi-:unittest pi+:unittest.xml')
615 if os.path.isfile(
'D0:unittest ==> K-:unittest pi+:unittest.xml'):
616 os.remove(
'D0:unittest ==> K-:unittest pi+:unittest.xml')
618 def test_without_monitoring(self):
619 particles = get_small_unittest_channels()
620 config = fei.config.FeiConfiguration(monitor=
False, prefix=
'UNITTEST')
621 x = fei.core.PostReconstruction(particles, config)
623 path = basf2.create_path()
625 path.add_module(
'MVAExpert', identifier=
'UNITTEST_pi+:generic ==> pi+:FSP', extraInfoName=
'SignalProbability',
626 listNames=[
'pi+:generic_0'])
627 path.add_module(
'TagUniqueSignal', particleList=
'pi+:generic_0', target=
'isPrimarySignal',
628 extraInfoName=
'uniqueSignal')
629 path.add_module(
'ParticleListManipulator', outputListName=
'pi+:generic', inputListNames=[
'pi+:generic_0'],
630 variable=
'particleSource', writeOut=
True)
631 path.add_module(
'ParticleSelector', decayString=
'pi+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
632 path.add_module(
'BestCandidateSelection', particleList=
'pi+:generic', variable=
'extraInfo(SignalProbability)',
633 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
635 path.add_module(
'MVAExpert', identifier=
'UNITTEST_K+:generic ==> K+:FSP', extraInfoName=
'SignalProbability',
636 listNames=[
'K+:generic_0'])
637 path.add_module(
'TagUniqueSignal', particleList=
'K+:generic_0', target=
'isPrimarySignal',
638 extraInfoName=
'uniqueSignal')
639 path.add_module(
'ParticleListManipulator', outputListName=
'K+:generic', inputListNames=[
'K+:generic_0'],
640 variable=
'particleSource', writeOut=
True)
641 path.add_module(
'ParticleSelector', decayString=
'K+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
642 path.add_module(
'BestCandidateSelection', particleList=
'K+:generic', variable=
'extraInfo(SignalProbability)',
643 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
645 path.add_module(
'MVAExpert', identifier=
'UNITTEST_D0:generic ==> K-:generic pi+:generic',
646 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_0'])
647 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_0', target=
'isSignal',
648 extraInfoName=
'uniqueSignal')
650 path.add_module(
'MVAExpert', identifier=
'UNITTEST_D0:generic ==> pi-:generic pi+:generic',
651 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_1'])
652 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_1', target=
'isSignal',
653 extraInfoName=
'uniqueSignal')
655 path.add_module(
'ParticleListManipulator', outputListName=
'D0:generic',
656 inputListNames=[
'D0:generic_0',
'D0:generic_1'], variable=
'particleSource',
658 path.add_module(
'ParticleSelector', decayString=
'D0:generic', cut=
'0.001 < extraInfo(SignalProbability)')
659 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic', variable=
'extraInfo(SignalProbability)',
660 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
662 print_path(path, x.reconstruct())
663 self.assertEqual(x.reconstruct(), path)
665 def test_without_monitoring_training_mode(self):
666 particles = get_small_unittest_channels()
667 config = fei.config.FeiConfiguration(monitor=
False, prefix=
'UNITTEST', training=
True)
668 x = fei.core.PostReconstruction(particles, config)
670 path = basf2.create_path()
672 path.add_module(
'MVAExpert', identifier=
'pi+:generic ==> pi+:FSP.xml', extraInfoName=
'SignalProbability',
673 listNames=[
'pi+:generic_0'])
674 path.add_module(
'TagUniqueSignal', particleList=
'pi+:generic_0', target=
'isPrimarySignal',
675 extraInfoName=
'uniqueSignal')
676 path.add_module(
'ParticleListManipulator', outputListName=
'pi+:generic', inputListNames=[
'pi+:generic_0'],
677 variable=
'particleSource', writeOut=
True)
678 path.add_module(
'ParticleSelector', decayString=
'pi+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
679 path.add_module(
'BestCandidateSelection', particleList=
'pi+:generic', variable=
'extraInfo(SignalProbability)',
680 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
682 path.add_module(
'MVAExpert', identifier=
'K+:generic ==> K+:FSP.xml', extraInfoName=
'SignalProbability',
683 listNames=[
'K+:generic_0'])
684 path.add_module(
'TagUniqueSignal', particleList=
'K+:generic_0', target=
'isPrimarySignal',
685 extraInfoName=
'uniqueSignal')
686 path.add_module(
'ParticleListManipulator', outputListName=
'K+:generic', inputListNames=[
'K+:generic_0'],
687 variable=
'particleSource', writeOut=
True)
688 path.add_module(
'ParticleSelector', decayString=
'K+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
689 path.add_module(
'BestCandidateSelection', particleList=
'K+:generic', variable=
'extraInfo(SignalProbability)',
690 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
692 path.add_module(
'MVAExpert', identifier=
'D0:generic ==> K-:generic pi+:generic.xml',
693 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_0'])
694 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_0', target=
'isSignal',
695 extraInfoName=
'uniqueSignal')
697 path.add_module(
'MVAExpert', identifier=
'D0:generic ==> pi-:generic pi+:generic.xml',
698 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_1'])
699 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_1', target=
'isSignal',
700 extraInfoName=
'uniqueSignal')
702 path.add_module(
'ParticleListManipulator', outputListName=
'D0:generic',
703 inputListNames=[
'D0:generic_0',
'D0:generic_1'], variable=
'particleSource',
705 path.add_module(
'ParticleSelector', decayString=
'D0:generic', cut=
'0.001 < extraInfo(SignalProbability)')
706 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic', variable=
'extraInfo(SignalProbability)',
707 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
709 print_path(path, x.reconstruct())
710 self.assertEqual(x.reconstruct(), path)
712 def test_with_monitoring(self):
713 particles = get_small_unittest_channels()
714 config = fei.config.FeiConfiguration(monitor=
True, prefix=
'UNITTEST')
715 x = fei.core.PostReconstruction(particles, config)
717 path = basf2.create_path()
719 path.add_module(
'MVAExpert', identifier=
'UNITTEST_pi+:generic ==> pi+:FSP', extraInfoName=
'SignalProbability',
720 listNames=[
'pi+:generic_0'])
721 path.add_module(
'TagUniqueSignal', particleList=
'pi+:generic_0', target=
'isPrimarySignal',
722 extraInfoName=
'uniqueSignal')
724 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic_0',
725 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
726 'extraInfo(SignalProbability)',
727 'isPrimarySignal',
'extraInfo(decayModeID)']),
728 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(SignalProbability)',
'isPrimarySignal'),
729 (
'extraInfo(SignalProbability)',
'mcErrors'),
730 (
'extraInfo(SignalProbability)',
'mcParticleStatus'),
731 (
'extraInfo(decayModeID)',
'isPrimarySignal'),
732 (
'extraInfo(decayModeID)',
'mcErrors'),
733 (
'extraInfo(decayModeID)',
'extraInfo(uniqueSignal)'),
734 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
735 fileName=
'Monitor_PostReconstruction_AfterMVA.root', directory=
'pi+:generic ==> pi+:FSP')
736 path.add_module(
'ParticleListManipulator', outputListName=
'pi+:generic', inputListNames=[
'pi+:generic_0'],
737 variable=
'particleSource', writeOut=
True)
738 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic',
739 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
740 'extraInfo(SignalProbability)',
741 'isPrimarySignal',
'extraInfo(decayModeID)']),
742 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
743 (
'extraInfo(decayModeID)',
'mcErrors'),
744 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
745 fileName=
'Monitor_PostReconstruction_BeforePostCut.root', directory=
'pi+:generic')
746 path.add_module(
'ParticleSelector', decayString=
'pi+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
747 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic',
748 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
749 'extraInfo(SignalProbability)',
750 'isPrimarySignal',
'extraInfo(decayModeID)']),
751 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
752 (
'extraInfo(decayModeID)',
'mcErrors'),
753 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
754 fileName=
'Monitor_PostReconstruction_BeforeRanking.root', directory=
'pi+:generic')
755 path.add_module(
'BestCandidateSelection', particleList=
'pi+:generic', variable=
'extraInfo(SignalProbability)',
756 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
757 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic',
758 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
759 'extraInfo(SignalProbability)',
'isPrimarySignal',
760 'extraInfo(decayModeID)',
'extraInfo(postCut_rank)']),
761 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
762 (
'extraInfo(decayModeID)',
'mcErrors'),
763 (
'extraInfo(decayModeID)',
'mcParticleStatus'),
764 (
'extraInfo(decayModeID)',
'extraInfo(postCut_rank)'),
765 (
'isPrimarySignal',
'extraInfo(postCut_rank)'),
766 (
'mcErrors',
'extraInfo(postCut_rank)'),
767 (
'mcParticleStatus',
'extraInfo(postCut_rank)')]),
768 fileName=
'Monitor_PostReconstruction_AfterRanking.root', directory=
'pi+:generic')
769 path.add_module(
'VariablesToNtuple', fileName=
'Monitor_Final.root', treeName=
'pi+:generic variables',
770 variables=[
'extraInfo(SignalProbability)',
'mcErrors',
'mcParticleStatus',
'isPrimarySignal',
771 'extraInfo(uniqueSignal)',
'extraInfo(decayModeID)'],
772 particleList=
'pi+:generic')
774 path.add_module(
'MVAExpert', identifier=
'UNITTEST_K+:generic ==> K+:FSP', extraInfoName=
'SignalProbability',
775 listNames=[
'K+:generic_0'])
776 path.add_module(
'TagUniqueSignal', particleList=
'K+:generic_0', target=
'isPrimarySignal',
777 extraInfoName=
'uniqueSignal')
778 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic_0',
779 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
780 'extraInfo(SignalProbability)',
781 'isPrimarySignal',
'extraInfo(decayModeID)']),
782 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(SignalProbability)',
'isPrimarySignal'),
783 (
'extraInfo(SignalProbability)',
'mcErrors'),
784 (
'extraInfo(SignalProbability)',
'mcParticleStatus'),
785 (
'extraInfo(decayModeID)',
'isPrimarySignal'),
786 (
'extraInfo(decayModeID)',
'mcErrors'),
787 (
'extraInfo(decayModeID)',
'extraInfo(uniqueSignal)'),
788 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
789 fileName=
'Monitor_PostReconstruction_AfterMVA.root', directory=
'K+:generic ==> K+:FSP')
790 path.add_module(
'ParticleListManipulator', outputListName=
'K+:generic', inputListNames=[
'K+:generic_0'],
791 variable=
'particleSource', writeOut=
True)
792 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic',
793 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
794 'extraInfo(SignalProbability)',
795 'isPrimarySignal',
'extraInfo(decayModeID)']),
796 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
797 (
'extraInfo(decayModeID)',
'mcErrors'),
798 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
799 fileName=
'Monitor_PostReconstruction_BeforePostCut.root', directory=
'K+:generic')
800 path.add_module(
'ParticleSelector', decayString=
'K+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
801 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic',
802 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
803 'extraInfo(SignalProbability)',
804 'isPrimarySignal',
'extraInfo(decayModeID)']),
805 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
806 (
'extraInfo(decayModeID)',
'mcErrors'),
807 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
808 fileName=
'Monitor_PostReconstruction_BeforeRanking.root', directory=
'K+:generic')
809 path.add_module(
'BestCandidateSelection', particleList=
'K+:generic', variable=
'extraInfo(SignalProbability)',
810 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
811 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic',
812 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
813 'extraInfo(SignalProbability)',
'isPrimarySignal',
814 'extraInfo(decayModeID)',
'extraInfo(postCut_rank)']),
815 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
816 (
'extraInfo(decayModeID)',
'mcErrors'),
817 (
'extraInfo(decayModeID)',
'mcParticleStatus'),
818 (
'extraInfo(decayModeID)',
'extraInfo(postCut_rank)'),
819 (
'isPrimarySignal',
'extraInfo(postCut_rank)'),
820 (
'mcErrors',
'extraInfo(postCut_rank)'),
821 (
'mcParticleStatus',
'extraInfo(postCut_rank)')]),
822 fileName=
'Monitor_PostReconstruction_AfterRanking.root', directory=
'K+:generic')
823 path.add_module(
'VariablesToNtuple', fileName=
'Monitor_Final.root', treeName=
'K+:generic variables',
824 variables=[
'extraInfo(SignalProbability)',
'mcErrors',
'mcParticleStatus',
'isPrimarySignal',
825 'extraInfo(uniqueSignal)',
'extraInfo(decayModeID)'],
826 particleList=
'K+:generic')
828 path.add_module(
'MVAExpert', identifier=
'UNITTEST_D0:generic ==> K-:generic pi+:generic',
829 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_0'])
830 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_0', target=
'isSignal',
831 extraInfoName=
'uniqueSignal')
832 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_0',
833 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
834 'extraInfo(SignalProbability)',
835 'isSignal',
'extraInfo(decayModeID)']),
836 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(SignalProbability)',
'isSignal'),
837 (
'extraInfo(SignalProbability)',
'mcErrors'),
838 (
'extraInfo(SignalProbability)',
'mcParticleStatus'),
839 (
'extraInfo(decayModeID)',
'isSignal'),
840 (
'extraInfo(decayModeID)',
'mcErrors'),
841 (
'extraInfo(decayModeID)',
'extraInfo(uniqueSignal)'),
842 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
843 fileName=
'Monitor_PostReconstruction_AfterMVA.root', directory=
'D0:generic ==> K-:generic pi+:generic')
845 path.add_module(
'MVAExpert', identifier=
'UNITTEST_D0:generic ==> pi-:generic pi+:generic',
846 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_1'])
847 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_1', target=
'isSignal',
848 extraInfoName=
'uniqueSignal')
849 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_1',
850 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
851 'extraInfo(SignalProbability)',
852 'isSignal',
'extraInfo(decayModeID)']),
853 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(SignalProbability)',
'isSignal'),
854 (
'extraInfo(SignalProbability)',
'mcErrors'),
855 (
'extraInfo(SignalProbability)',
'mcParticleStatus'),
856 (
'extraInfo(decayModeID)',
'isSignal'),
857 (
'extraInfo(decayModeID)',
'mcErrors'),
858 (
'extraInfo(decayModeID)',
'extraInfo(uniqueSignal)'),
859 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
860 fileName=
'Monitor_PostReconstruction_AfterMVA.root', directory=
'D0:generic ==> pi-:generic pi+:generic')
862 path.add_module(
'ParticleListManipulator', outputListName=
'D0:generic',
863 inputListNames=[
'D0:generic_0',
'D0:generic_1'], variable=
'particleSource',
865 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic',
866 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
867 'extraInfo(SignalProbability)',
868 'isSignal',
'extraInfo(decayModeID)']),
869 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isSignal'),
870 (
'extraInfo(decayModeID)',
'mcErrors'),
871 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
872 fileName=
'Monitor_PostReconstruction_BeforePostCut.root', directory=
'D0:generic')
873 path.add_module(
'ParticleSelector', decayString=
'D0:generic', cut=
'0.001 < extraInfo(SignalProbability)')
874 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic',
875 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
876 'extraInfo(SignalProbability)',
877 'isSignal',
'extraInfo(decayModeID)']),
878 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isSignal'),
879 (
'extraInfo(decayModeID)',
'mcErrors'),
880 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
881 fileName=
'Monitor_PostReconstruction_BeforeRanking.root', directory=
'D0:generic')
882 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic', variable=
'extraInfo(SignalProbability)',
883 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
884 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic',
885 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
886 'extraInfo(SignalProbability)',
'isSignal',
887 'extraInfo(decayModeID)',
'extraInfo(postCut_rank)']),
888 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isSignal'),
889 (
'extraInfo(decayModeID)',
'mcErrors'),
890 (
'extraInfo(decayModeID)',
'mcParticleStatus'),
891 (
'extraInfo(decayModeID)',
'extraInfo(postCut_rank)'),
892 (
'isSignal',
'extraInfo(postCut_rank)'),
893 (
'mcErrors',
'extraInfo(postCut_rank)'),
894 (
'mcParticleStatus',
'extraInfo(postCut_rank)')]),
895 fileName=
'Monitor_PostReconstruction_AfterRanking.root', directory=
'D0:generic')
896 path.add_module(
'VariablesToNtuple', fileName=
'Monitor_Final.root', treeName=
'D0:generic variables',
897 variables=[
'extraInfo(SignalProbability)',
'mcErrors',
'mcParticleStatus',
'isSignal',
898 'extraInfo(uniqueSignal)',
'extraInfo(decayModeID)'],
899 particleList=
'D0:generic')
901 print_path(path, x.reconstruct())
902 self.assertEqual(x.reconstruct(), path)
905 class TestTeacher(unittest.TestCase):
907 fei.core.Teacher.MaximumNumberOfMVASamples = int(1e7)
908 fei.core.Teacher.MinimumNumberOfMVASamples = int(10)
910 f = ROOT.TFile(
'training_input.root',
'RECREATE')
912 tree = ROOT.TTree(
'pi+:generic ==> pi+:FSP variables',
'pi+:generic ==> pi+:FSP variables')
913 isSignal = np.zeros(1, dtype=float)
914 p = np.zeros(1, dtype=float)
915 pt = np.zeros(1, dtype=float)
916 tree.Branch(
'isPrimarySignal', isSignal,
'isPrimarySignal/D')
917 tree.Branch(
'p', p,
'p/D')
918 tree.Branch(
'dr', pt,
'dr/D')
919 for i
in range(1000):
924 tree.Write(
"", ROOT.TObject.kOverwrite)
928 tree = ROOT.TTree(
'D0:generic ==> K-:generic pi+:generic variables',
'D0:generic ==> K-:generic pi+:generic variables')
929 isSignal = np.zeros(1, dtype=float)
930 p = np.zeros(1, dtype=float)
931 pt = np.zeros(1, dtype=float)
932 tree.Branch(
'isSignal', isSignal,
'isSignal/D')
933 tree.Branch(
'M', p,
'M/D')
934 tree.Branch(
'p', pt,
'p/D')
941 tree.Write(
"", ROOT.TObject.kOverwrite)
943 tree = ROOT.TTree(
'D0:generic ==> pi-:generic pi+:generic variables',
'D0:generic ==> pi-:generic pi+:generic variables')
944 isSignal = np.zeros(1, dtype=float)
945 p = np.zeros(1, dtype=float)
946 pt = np.zeros(1, dtype=float)
947 tree.Branch(
'isSignal', isSignal,
'isSignal/D')
948 tree.Branch(
'M', p,
'M/D')
949 tree.Branch(
'p', pt,
'p/D')
950 for i
in range(1000):
955 tree.Write(
"", ROOT.TObject.kOverwrite)
958 if os.path.isfile(
'UNITTEST_TEACHER.xml'):
959 os.remove(
'UNITTEST_TEACHER.xml')
960 if os.path.isfile(
'UNITTEST_pi+:generic ==> pi+:FSP.xml'):
961 os.remove(
'UNITTEST_pi+:generic ==> pi+:FSP.xml')
962 if os.path.isfile(
'UNITTEST_K+:generic ==> K+:FSP.xml'):
963 os.remove(
'UNITTEST_K+:generic ==> K+:FSP.xml')
964 if os.path.isfile(
'UNITTEST_D0:generic ==> K-:generic pi+:generic.xml'):
965 os.remove(
'UNITTEST_D0:generic ==> K-:generic pi+:generic.xml')
966 if os.path.isfile(
'UNITTEST_D0:generic ==> pi-:generic pi+:generic.xml'):
967 os.remove(
'UNITTEST_D0:generic ==> pi-:generic pi+:generic.xml')
968 if os.path.isfile(
'training_input.root'):
969 os.remove(
'training_input.root')
971 def test_create_fake_weightfile(self):
972 self.assertEqual(os.path.isfile(
'UNITTEST_pi+:generic ==> pi+:FSP.xml'),
False)
973 self.assertEqual(basf2_mva.available(
'UNITTEST_pi+:generic ==> pi+:FSP.xml'),
False)
974 fei.core.Teacher.create_fake_weightfile(
'UNITTEST_pi+:generic ==> pi+:FSP')
975 self.assertEqual(os.path.isfile(
'UNITTEST_pi+:generic ==> pi+:FSP.xml'),
True)
976 self.assertEqual(basf2_mva.available(
'UNITTEST_pi+:generic ==> pi+:FSP.xml'),
True)
978 def test_upload(self):
979 particles = get_small_unittest_channels()
980 config = fei.config.FeiConfiguration(monitor=
False, prefix=
'UNITTEST', externTeacher=
'basf2_mva_teacher')
981 x = fei.core.Teacher(particles, config)
982 fei.core.Teacher.create_fake_weightfile(
'TEACHER')
983 self.assertEqual(basf2_mva.available(
'UNITTEST_TEACHER'),
False)
984 r = x.upload(
'TEACHER')
985 self.assertEqual(basf2_mva.available(
'UNITTEST_TEACHER'),
True)
986 self.assertEqual(r, (
'TEACHER.xml',
'UNITTEST_TEACHER'))
988 def test_without_monitoring(self):
989 particles = get_small_unittest_channels()
990 config = fei.config.FeiConfiguration(monitor=
False, prefix=
'UNITTEST', externTeacher=
'basf2_mva_teacher')
991 x = fei.core.Teacher(particles, config)
993 self.assertEqual(basf2_mva.available(
'UNITTEST_pi+:generic ==> pi+:FSP'),
False)
994 self.assertEqual(basf2_mva.available(
'UNITTEST_K+:generic ==> K+:FSP'),
False)
995 self.assertEqual(basf2_mva.available(
'UNITTEST_D0:generic ==> K-:generic pi+:generic'),
False)
996 self.assertEqual(basf2_mva.available(
'UNITTEST_D0:generic ==> pi-:generic pi+:generic'),
False)
1000 self.assertEqual(basf2_mva.available(
'UNITTEST_pi+:generic ==> pi+:FSP'),
True)
1001 self.assertEqual(basf2_mva.available(
'UNITTEST_K+:generic ==> K+:FSP'),
False)
1002 self.assertEqual(basf2_mva.available(
'UNITTEST_D0:generic ==> K-:generic pi+:generic'),
True)
1003 self.assertEqual(basf2_mva.available(
'UNITTEST_D0:generic ==> pi-:generic pi+:generic'),
True)
1007 class TestConvertLegacyTraining(unittest.TestCase):
1012 class TestGetPath(unittest.TestCase):
1015 particles = fei.get_unittest_channels()
1017 f = ROOT.TFile(
'mcParticlesCount.root',
'RECREATE')
1020 for pdgnumber
in {abs(
pdg.from_name(particle.name))
for particle
in particles}:
1021 hist = ROOT.TH1F(f
"NumberOfMCParticlesInEvent__bo{pdgnumber}__bc",
1022 f
"NumberOfMCParticlesInEvent__bo{pdgnumber}__bc", 11, -0.5, 10.5)
1025 f.Write(f
"NumberOfMCParticlesInEvent__bo{pdgnumber}__bc")
1028 if os.path.isfile(
'mcParticlesCount.root'):
1029 os.remove(
'mcParticlesCount.root')
1030 if os.path.isfile(
'Summary.pickle'):
1031 os.remove(
'Summary.pickle')
1033 def test_get_path_default_cache(self):
1034 particles = fei.get_unittest_channels()
1035 config = fei.config.FeiConfiguration(training=
True)
1036 x = fei.core.Teacher(particles, config)
1040 feistate = fei.core.get_path(particles, config)
1041 self.assertEqual(feistate.stage, 0)
1045 config = fei.config.FeiConfiguration(training=
True)
1046 feistate = fei.core.get_path(particles, config)
1047 self.assertEqual(feistate.stage, 1)
1051 config = fei.config.FeiConfiguration(training=
True)
1052 feistate = fei.core.get_path(particles, config)
1053 self.assertEqual(feistate.stage, 1)
1056 fei.core.Teacher.create_fake_weightfile(
'pi+:generic ==> pi+:FSP')
1057 fei.core.Teacher.create_fake_weightfile(
'K+:generic ==> K+:FSP')
1058 fei.core.Teacher.create_fake_weightfile(
'mu+:generic ==> mu+:FSP')
1059 fei.core.Teacher.create_fake_weightfile(
'gamma:generic ==> gamma:FSP')
1060 fei.core.Teacher.create_fake_weightfile(
'gamma:generic ==> gamma:V0')
1064 config = fei.config.FeiConfiguration(training=
True)
1065 feistate = fei.core.get_path(particles, config)
1066 self.assertEqual(feistate.stage, 2)
1070 config = fei.config.FeiConfiguration(training=
True)
1071 feistate = fei.core.get_path(particles, config)
1072 self.assertEqual(feistate.stage, 2)
1075 fei.core.Teacher.create_fake_weightfile(
'pi0:generic ==> gamma:generic gamma:generic')
1079 config = fei.config.FeiConfiguration(training=
True)
1080 feistate = fei.core.get_path(particles, config)
1081 self.assertEqual(feistate.stage, 4)
1084 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> K-:generic pi+:generic')
1085 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> K-:generic pi+:generic pi0:generic')
1086 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> pi-:generic pi+:generic')
1087 fei.core.Teacher.create_fake_weightfile(
'D0:semileptonic ==> K-:generic mu+:generic')
1088 fei.core.Teacher.create_fake_weightfile(
'D0:semileptonic ==> K-:generic pi0:generic mu+:generic')
1092 config = fei.config.FeiConfiguration(training=
True)
1093 feistate = fei.core.get_path(particles, config)
1094 self.assertEqual(feistate.stage, 7)
1098 config = fei.config.FeiConfiguration(cache=0, training=
True)
1099 feistate = fei.core.get_path(particles, config)
1100 self.assertEqual(feistate.stage, 7)
1104 os.remove(
'pi+:generic ==> pi+:FSP.xml')
1105 os.remove(
'K+:generic ==> K+:FSP.xml')
1106 os.remove(
'mu+:generic ==> mu+:FSP.xml')
1107 os.remove(
'gamma:generic ==> gamma:FSP.xml')
1108 os.remove(
'gamma:generic ==> gamma:V0.xml')
1109 os.remove(
'pi0:generic ==> gamma:generic gamma:generic.xml')
1110 os.remove(
'D0:generic ==> K-:generic pi+:generic.xml')
1111 os.remove(
'D0:generic ==> K-:generic pi+:generic pi0:generic.xml')
1112 os.remove(
'D0:generic ==> pi-:generic pi+:generic.xml')
1113 os.remove(
'D0:semileptonic ==> K-:generic mu+:generic.xml')
1114 os.remove(
'D0:semileptonic ==> K-:generic pi0:generic mu+:generic.xml')
1116 config = fei.config.FeiConfiguration(cache=0, training=
False)
1117 feistate = fei.core.get_path(particles, config)
1118 self.assertEqual(feistate.stage, 7)
1120 def test_get_path(self):
1121 particles = fei.get_unittest_channels()
1122 config = fei.config.FeiConfiguration(cache=-1, training=
True)
1123 x = fei.core.Teacher(particles, config)
1127 feistate = fei.core.get_path(particles, config)
1128 self.assertEqual(feistate.stage, 0)
1132 config = fei.config.FeiConfiguration(cache=0, training=
True)
1133 feistate = fei.core.get_path(particles, config)
1134 self.assertEqual(feistate.stage, 1)
1138 config = fei.config.FeiConfiguration(cache=1, training=
True)
1139 feistate = fei.core.get_path(particles, config)
1140 self.assertEqual(feistate.stage, 1)
1143 fei.core.Teacher.create_fake_weightfile(
'pi+:generic ==> pi+:FSP')
1144 fei.core.Teacher.create_fake_weightfile(
'K+:generic ==> K+:FSP')
1145 fei.core.Teacher.create_fake_weightfile(
'mu+:generic ==> mu+:FSP')
1146 fei.core.Teacher.create_fake_weightfile(
'gamma:generic ==> gamma:FSP')
1147 fei.core.Teacher.create_fake_weightfile(
'gamma:generic ==> gamma:V0')
1151 config = fei.config.FeiConfiguration(cache=1, training=
True)
1152 feistate = fei.core.get_path(particles, config)
1153 self.assertEqual(feistate.stage, 2)
1157 config = fei.config.FeiConfiguration(cache=2, training=
True)
1158 feistate = fei.core.get_path(particles, config)
1159 self.assertEqual(feistate.stage, 2)
1164 config = fei.config.FeiConfiguration(cache=4, training=
True)
1165 feistate = fei.core.get_path(particles, config)
1166 self.assertEqual(feistate.stage, 2)
1169 fei.core.Teacher.create_fake_weightfile(
'pi0:generic ==> gamma:generic gamma:generic')
1173 config = fei.config.FeiConfiguration(cache=2, training=
True)
1174 feistate = fei.core.get_path(particles, config)
1175 self.assertEqual(feistate.stage, 4)
1178 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> K-:generic pi+:generic')
1179 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> K-:generic pi+:generic pi0:generic')
1180 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> pi-:generic pi+:generic')
1181 fei.core.Teacher.create_fake_weightfile(
'D0:semileptonic ==> K-:generic mu+:generic')
1182 fei.core.Teacher.create_fake_weightfile(
'D0:semileptonic ==> K-:generic pi0:generic mu+:generic')
1186 config = fei.config.FeiConfiguration(cache=4, training=
True)
1187 feistate = fei.core.get_path(particles, config)
1188 self.assertEqual(feistate.stage, 7)
1192 config = fei.config.FeiConfiguration(cache=0, training=
True)
1193 feistate = fei.core.get_path(particles, config)
1194 self.assertEqual(feistate.stage, 7)
1198 os.remove(
'pi+:generic ==> pi+:FSP.xml')
1199 os.remove(
'K+:generic ==> K+:FSP.xml')
1200 os.remove(
'mu+:generic ==> mu+:FSP.xml')
1201 os.remove(
'gamma:generic ==> gamma:FSP.xml')
1202 os.remove(
'gamma:generic ==> gamma:V0.xml')
1203 os.remove(
'pi0:generic ==> gamma:generic gamma:generic.xml')
1204 os.remove(
'D0:generic ==> K-:generic pi+:generic.xml')
1205 os.remove(
'D0:generic ==> K-:generic pi+:generic pi0:generic.xml')
1206 os.remove(
'D0:generic ==> pi-:generic pi+:generic.xml')
1207 os.remove(
'D0:semileptonic ==> K-:generic mu+:generic.xml')
1208 os.remove(
'D0:semileptonic ==> K-:generic pi0:generic mu+:generic.xml')
1210 config = fei.config.FeiConfiguration(cache=0, training=
False)
1211 feistate = fei.core.get_path(particles, config)
1212 self.assertEqual(feistate.stage, 7)
1215 if __name__ ==
'__main__':
1217 basf2.conditions.testing_payloads = [
'localdb/database.txt']
def clean_working_directory()