Belle II Software  release-06-00-14
test_fei.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 
11 
12 import basf2
13 import unittest
14 import unittest.mock
15 import os
16 import tempfile
17 import atexit
18 import shutil
19 import ROOT
20 
21 import b2bii
22 
23 import fei
24 from fei.config import Particle
25 
26 import numpy as np
27 
28 import basf2_mva
29 import pdg
30 
31 # @cond
32 
33 # Define equality operators for a bunch of pybasf2 classes
34 import pybasf2
35 pybasf2.Module.__eq__ = lambda a, b: a.type() == b.type() and\
36  all(x == y for x, y in zip(a.available_params(), b.available_params()))
37 pybasf2.ModuleParamInfo.__eq__ = lambda a, b: a.name == b.name and a.values == b.values
38 pybasf2.Path.__eq__ = lambda a, b: all(x == y for x, y in zip(a.modules(), b.modules()))
39 
40 
41 def print_path(a, b):
42  """
43  Print the parts of the paths which are different
44  """
45  for x, y in zip(a.modules(), b.modules()):
46  if x.type() != y.type():
47  print(x.type(), y.type())
48  for n, m in zip(x.available_params(), y.available_params()):
49  if n.name != m.name:
50  print(n.name, m.name)
51  if n.values != m.values:
52  print(n.name, n.values, m.values)
53 
54 
55 def get_small_unittest_channels():
56  pion = Particle('pi+',
57  fei.config.MVAConfiguration(variables=['p', 'dr'],
58  target='isPrimarySignal'),
59  fei.config.PreCutConfiguration(userCut='[dr < 2] and [abs(dz) < 4]',
60  bestCandidateMode='highest',
61  bestCandidateVariable='piid',
62  bestCandidateCut=20),
63  fei.config.PostCutConfiguration(bestCandidateCut=10, value=0.01))
64  pion.addChannel(['pi+:FSP'])
65 
66  kaon = Particle('K+',
67  fei.config.MVAConfiguration(variables=['p', 'dr'],
68  target='isPrimarySignal'),
69  fei.config.PreCutConfiguration(userCut='[dr < 2] and [abs(dz) < 4]',
70  bestCandidateMode='highest',
71  bestCandidateVariable='Kid',
72  bestCandidateCut=20),
73  fei.config.PostCutConfiguration(bestCandidateCut=10, value=0.01))
74  kaon.addChannel(['K+:FSP'])
75 
76  D0 = Particle('D0',
77  fei.config.MVAConfiguration(variables=['M', 'p'],
78  target='isSignal'),
79  fei.config.PreCutConfiguration(userCut='1.7 < M < 1.95',
80  bestCandidateMode='lowest',
81  bestCandidateVariable='abs(dM)',
82  bestCandidateCut=20),
83  fei.config.PostCutConfiguration(bestCandidateCut=10, value=0.001))
84  D0.addChannel(['K-', 'pi+'])
85  D0.addChannel(['pi-', 'pi+'])
86 
87  particles = [pion, kaon, D0]
88  return particles
89 
90 
91 class TestGetStagesFromParticles(unittest.TestCase):
92  def test_get_stages_from_particles(self):
93  particles = fei.get_unittest_channels()
94  stages = fei.core.get_stages_from_particles(particles)
95  self.assertEqual(len(stages), 7)
96  self.assertEqual(len(stages[0]), 4)
97  self.assertEqual(stages[0][0].identifier, 'gamma:generic')
98  self.assertEqual(stages[0][1].identifier, 'mu+:generic')
99  self.assertEqual(stages[0][2].identifier, 'pi+:generic')
100  self.assertEqual(stages[0][3].identifier, 'K+:generic')
101  self.assertEqual(len(stages[1]), 1)
102  self.assertEqual(stages[1][0].identifier, 'pi0:generic')
103  self.assertEqual(len(stages[2]), 0)
104  self.assertEqual(len(stages[3]), 2)
105  self.assertEqual(stages[3][0].identifier, 'D0:generic')
106  self.assertEqual(stages[3][1].identifier, 'D0:semileptonic')
107  self.assertEqual(len(stages[4]), 0)
108  self.assertEqual(len(stages[5]), 0)
109  self.assertEqual(len(stages[6]), 0)
110 
111 
112 class TestTrainingDataInformation(unittest.TestCase):
113 
114  def tearDown(self):
115  if os.path.isfile('mcParticlesCount.root'):
116  os.remove('mcParticlesCount.root')
117 
118  def test_reconstruct(self):
119  particles = fei.get_unittest_channels()
120  x = fei.core.TrainingDataInformation(particles)
121 
122  path = basf2.create_path()
123  path.add_module('VariablesToHistogram', fileName='mcParticlesCount.root',
124  variables=[
125  ('NumberOfMCParticlesInEvent(321)', 100, -0.5, 99.5),
126  ('NumberOfMCParticlesInEvent(421)', 100, -0.5, 99.5),
127  ('NumberOfMCParticlesInEvent(13)', 100, -0.5, 99.5),
128  ('NumberOfMCParticlesInEvent(111)', 100, -0.5, 99.5),
129  ('NumberOfMCParticlesInEvent(211)', 100, -0.5, 99.5),
130  ('NumberOfMCParticlesInEvent(22)', 100, -0.5, 99.5)]
131  )
132  print_path(path, x.reconstruct())
133  self.assertEqual(x.reconstruct(), path)
134 
135  def test_available(self):
136  particles = fei.get_unittest_channels()
137  x = fei.core.TrainingDataInformation(particles)
138  self.assertEqual(x.available(), False)
139  f = ROOT.TFile('mcParticlesCount.root', 'RECREATE') # noqa
140  self.assertEqual(x.available(), True)
141 
142  def test_get_mc_counts(self):
143  f = ROOT.TFile('mcParticlesCount.root', 'RECREATE')
144  f.cd()
145  hist = ROOT.TH1F("NumberOfMCParticlesInEvent__bo211__bc", "NumberOfMCParticlesInEvent__bo211__bc", 11, -0.5, 10.5)
146  for i in range(10):
147  hist.Fill(5)
148  for i in range(5):
149  hist.Fill(4)
150  for i in range(3):
151  hist.Fill(3)
152  f.Write("NumberOfMCParticlesInEvent__bo211__bc")
153 
154  hist = ROOT.TH1F("NumberOfMCParticlesInEvent__bo321__bc", "NumberOfMCParticlesInEvent__bo321__bc", 11, -0.5, 10.5)
155  for i in range(8):
156  hist.Fill(4)
157  for i in range(5):
158  hist.Fill(2)
159  for i in range(5):
160  hist.Fill(7)
161  f.Write("NumberOfMCParticlesInEvent__bo321__bc")
162 
163  hist = ROOT.TH1F("NumberOfMCParticlesInEvent__bo13__bc", "NumberOfMCParticlesInEvent__bo13__bc", 11, -0.5, 10.5)
164  for i in range(18):
165  hist.Fill(5)
166  f.Write("NumberOfMCParticlesInEvent__bo13__bc")
167 
168  hist = ROOT.TH1F("NumberOfMCParticlesInEvent__bo22__bc", "NumberOfMCParticlesInEvent__bo222__bc", 11, -0.5, 10.5)
169  for i in range(18):
170  hist.Fill(0)
171  f.Write("NumberOfMCParticlesInEvent__bo22__bc")
172 
173  hist = ROOT.TH1F("NumberOfMCParticlesInEvent__bo111__bc", "NumberOfMCParticlesInEvent__bo111__bc", 11, -0.5, 10.5)
174  for i in range(5):
175  hist.Fill(5)
176  for i in range(10):
177  hist.Fill(4)
178  for i in range(3):
179  hist.Fill(3)
180  f.Write("NumberOfMCParticlesInEvent__bo111__bc")
181 
182  hist = ROOT.TH1F("NumberOfMCParticlesInEvent__bo421__bc", "NumberOfMCParticlesInEvent__bo421__bc", 11, -0.5, 10.5)
183  for i in range(10):
184  hist.Fill(9)
185  for i in range(5):
186  hist.Fill(0)
187  for i in range(3):
188  hist.Fill(1)
189  f.Write("NumberOfMCParticlesInEvent__bo421__bc")
190 
191  particles = fei.get_unittest_channels()
192  x = fei.core.TrainingDataInformation(particles)
193 
194  mcCounts = {
195  211: {'max': 5.0, 'min': 3.0, 'sum': 79.0, 'avg': 4.3888888888888893, 'std': 0.7556372504852998},
196  321: {'max': 7.0, 'min': 2.0, 'sum': 77.0, 'avg': 4.2777777777777777, 'std': 1.8798804795209585},
197  13: {'max': 5.0, 'min': 5.0, 'sum': 90.0, 'avg': 5.0, 'std': 0.0},
198  22: {'max': 0.0, 'min': 0.0, 'sum': 0.0, 'avg': 0.0, 'std': 0.0},
199  111: {'max': 5.0, 'min': 3.0, 'sum': 74.0, 'avg': 4.1111111111111107, 'std': 0.6573421981221816},
200  421: {'max': 9.0, 'min': 0.0, 'sum': 93.0, 'avg': 5.166666666666667, 'std': 4.2979323194092087},
201  0: {'sum': 18.0}}
202  self.assertDictEqual(x.get_mc_counts(), mcCounts)
203 
204 
205 class TestFSPLoader(unittest.TestCase):
206 
207  def test_belle2_without_monitoring(self):
208  particles = get_small_unittest_channels()
209  config = fei.config.FeiConfiguration(monitor=False)
210  x = fei.core.FSPLoader(particles, config)
211 
212  path = basf2.create_path()
213  fsps = ['K+:FSP', 'pi+:FSP', 'e+:FSP', 'mu+:FSP', 'gamma:FSP', 'p+:FSP', 'K_L0:FSP']
214  path.add_module('ParticleLoader', decayStrings=fsps, writeOut=True)
215  for fsp in fsps:
216  path.add_module('ParticleListManipulator', outputListName=fsp,
217  inputListNames=[fsp.split(':')[0] + ':all'], writeOut=True)
218  if 'gamma' in fsp:
219  path.add_module('ParticleSelector', decayString='gamma:FSP', cut='isFromECL')
220  path.add_module('ParticleLoader', decayStrings=['K_S0:V0 -> pi+ pi-'], writeOut=True)
221  path.add_module('ParticleLoader', decayStrings=['Lambda0:V0 -> p+ pi-'], writeOut=True)
222  path.add_module('ParticleLoader', decayStrings=['gamma:V0 -> e+ e-'], addDaughters=True, writeOut=True)
223  print_path(path, x.reconstruct())
224  self.assertEqual(x.reconstruct(), path)
225 
226  def test_belle2_with_monitoring(self):
227  particles = get_small_unittest_channels()
228  config = fei.config.FeiConfiguration(monitor=True)
229  x = fei.core.FSPLoader(particles, config)
230 
231  path = basf2.create_path()
232  fsps = ['K+:FSP', 'pi+:FSP', 'e+:FSP', 'mu+:FSP', 'gamma:FSP', 'p+:FSP', 'K_L0:FSP']
233  path.add_module('ParticleLoader', decayStrings=fsps, writeOut=True)
234  for fsp in fsps:
235  path.add_module('ParticleListManipulator', outputListName=fsp,
236  inputListNames=[fsp.split(':')[0] + ':all'], writeOut=True)
237  if 'gamma' in fsp:
238  path.add_module('ParticleSelector', decayString='gamma:FSP', cut='isFromECL')
239  path.add_module('ParticleLoader', decayStrings=['K_S0:V0 -> pi+ pi-'], writeOut=True)
240  path.add_module('ParticleLoader', decayStrings=['Lambda0:V0 -> p+ pi-'], writeOut=True)
241  path.add_module('ParticleLoader', decayStrings=['gamma:V0 -> e+ e-'], addDaughters=True, writeOut=True)
242  hist_variables = [(f'NumberOfMCParticlesInEvent({pdgcode})', 100, -0.5, 99.5)
243  for pdgcode in set([11, 321, 211, 13, 22, 310, 2212, 130, 3122, 111])]
244  path.add_module('VariablesToHistogram', particleList='',
245  variables=hist_variables,
246  fileName='Monitor_FSPLoader.root')
247  print_path(path, x.reconstruct())
248  self.assertEqual(x.reconstruct(), path)
249 
250  def test_belle1_without_monitoring(self):
251  particles = get_small_unittest_channels()
253  config = fei.config.FeiConfiguration(monitor=False)
254  x = fei.core.FSPLoader(particles, config)
255 
256  path = basf2.create_path()
257  fsps = ['K+:FSP', 'pi+:FSP', 'e+:FSP', 'mu+:FSP', 'p+:FSP']
258  path.add_module('ParticleLoader', decayStrings=fsps, writeOut=True)
259  for fsp in fsps:
260  path.add_module('ParticleListManipulator', outputListName=fsp,
261  inputListNames=[fsp.split(':')[0] + ':all'], writeOut=True)
262  path.add_module('ParticleListManipulator', outputListName='gamma:FSP', inputListNames=['gamma:mdst'], writeOut=True)
263  path.add_module('ParticleCopier', inputListNames=['gamma:FSP'])
264  path.add_module('ParticleListManipulator', outputListName='K_S0:V0', inputListNames=['K_S0:mdst'], writeOut=True)
265  path.add_module('ParticleCopier', inputListNames=['K_S0:V0'])
266  path.add_module('ParticleListManipulator', outputListName='Lambda0:V0', inputListNames=['Lambda0:mdst'], writeOut=True)
267  path.add_module('ParticleCopier', inputListNames=['Lambda0:V0'])
268  path.add_module('ParticleListManipulator', outputListName='K_L0:FSP', inputListNames=['K_L0:mdst'], writeOut=True)
269  path.add_module('ParticleCopier', inputListNames=['K_L0:FSP'])
270  path.add_module('ParticleListManipulator', outputListName='pi0:FSP', inputListNames=['pi0:mdst'], writeOut=True)
271  path.add_module('ParticleCopier', inputListNames=['pi0:FSP'])
272  path.add_module('ParticleListManipulator', outputListName='gamma:V0', inputListNames=['gamma:v0mdst'], writeOut=True)
273  path.add_module('ParticleCopier', inputListNames=['gamma:V0'])
274  print_path(path, x.reconstruct())
275  self.assertEqual(x.reconstruct(), path)
277 
278  def test_belle1_with_monitoring(self):
279  particles = get_small_unittest_channels()
281  config = fei.config.FeiConfiguration(monitor=True)
282  x = fei.core.FSPLoader(particles, config)
283 
284  path = basf2.create_path()
285  fsps = ['K+:FSP', 'pi+:FSP', 'e+:FSP', 'mu+:FSP', 'p+:FSP']
286  path.add_module('ParticleLoader', decayStrings=fsps, writeOut=True)
287  for fsp in fsps:
288  path.add_module('ParticleListManipulator', outputListName=fsp,
289  inputListNames=[fsp.split(':')[0] + ':all'], writeOut=True)
290  path.add_module('ParticleListManipulator', outputListName='gamma:FSP', inputListNames=['gamma:mdst'], writeOut=True)
291  path.add_module('ParticleCopier', inputListNames=['gamma:FSP'])
292  path.add_module('ParticleListManipulator', outputListName='K_S0:V0', inputListNames=['K_S0:mdst'], writeOut=True)
293  path.add_module('ParticleCopier', inputListNames=['K_S0:V0'])
294  path.add_module('ParticleListManipulator', outputListName='Lambda0:V0', inputListNames=['Lambda0:mdst'], writeOut=True)
295  path.add_module('ParticleCopier', inputListNames=['Lambda0:V0'])
296  path.add_module('ParticleListManipulator', outputListName='K_L0:FSP', inputListNames=['K_L0:mdst'], writeOut=True)
297  path.add_module('ParticleCopier', inputListNames=['K_L0:FSP'])
298  path.add_module('ParticleListManipulator', outputListName='pi0:FSP', inputListNames=['pi0:mdst'], writeOut=True)
299  path.add_module('ParticleCopier', inputListNames=['pi0:FSP'])
300  path.add_module('ParticleListManipulator', outputListName='gamma:V0', inputListNames=['gamma:v0mdst'], writeOut=True)
301  path.add_module('ParticleCopier', inputListNames=['gamma:V0'])
302  hist_variables = [(f'NumberOfMCParticlesInEvent({pdgcode})', 100, -0.5, 99.5)
303  for pdgcode in set([11, 321, 211, 13, 22, 310, 2212, 130, 3122, 111])]
304  path.add_module('VariablesToHistogram', particleList='',
305  variables=hist_variables,
306  fileName='Monitor_FSPLoader.root')
307  print_path(path, x.reconstruct())
308  self.assertEqual(x.reconstruct(), path)
310 
311 
312 class TestTrainingData(unittest.TestCase):
313 
314  def setUp(self):
315  self.mc_counts = {
316  211: {'sum': 79, 'avg': 4.3888888888888893, 'max': 5, 'min': 3, 'std': 0.75563725048530228},
317  321: {'sum': 77, 'avg': 4.2777777777777777, 'max': 7, 'min': 2, 'std': 1.8798804795209592},
318  421: {'sum': 93, 'avg': 5.166666666666667, 'max': 9, 'min': 0, 'std': 4.2979323194092087},
319  0: {'sum': 18}}
320 
321  def test_without_monitoring(self):
322  particles = get_small_unittest_channels()
323  config = fei.config.FeiConfiguration(monitor=False)
324  x = fei.core.TrainingData(particles, config, self.mc_counts)
325 
326  path = basf2.create_path()
327  path.add_module('VariablesToNtuple', fileName='training_input.root', treeName='pi+:generic ==> pi+:FSP variables',
328  variables=['p', 'dr', 'isPrimarySignal'],
329  particleList='pi+:generic_0', sampling=('isPrimarySignal', {}))
330  path.add_module('VariablesToNtuple', fileName='training_input.root', treeName='K+:generic ==> K+:FSP variables',
331  variables=['p', 'dr', 'isPrimarySignal'],
332  particleList='K+:generic_0', sampling=('isPrimarySignal', {}))
333  path.add_module('VariablesToNtuple', fileName='training_input.root',
334  treeName='D0:generic ==> K-:generic pi+:generic variables',
335  variables=['M', 'p', 'isSignal'],
336  particleList='D0:generic_0', sampling=('isSignal', {}))
337  path.add_module('VariablesToNtuple', fileName='training_input.root',
338  treeName='D0:generic ==> pi-:generic pi+:generic variables',
339  variables=['M', 'p', 'isSignal'],
340  particleList='D0:generic_1', sampling=('isSignal', {}))
341  print_path(path, x.reconstruct())
342  self.assertEqual(x.reconstruct(), path)
343 
344  def test_with_monitoring(self):
345  particles = get_small_unittest_channels()
346  config = fei.config.FeiConfiguration(monitor=True)
347  x = fei.core.TrainingData(particles, config, self.mc_counts)
348 
349  path = basf2.create_path()
350  path.add_module('VariablesToHistogram', particleList='pi+:generic_0',
351  variables=fei.config.variables2binnings(['mcErrors', 'mcParticleStatus', 'p', 'dr', 'isPrimarySignal']),
352  variables_2d=fei.config.variables2binnings_2d([('p', 'isPrimarySignal'), ('dr', 'isPrimarySignal')]),
353  fileName='Monitor_TrainingData.root', directory='pi+:generic ==> pi+:FSP')
354  path.add_module('VariablesToNtuple', fileName='training_input.root', treeName='pi+:generic ==> pi+:FSP variables',
355  variables=['p', 'dr', 'isPrimarySignal'],
356  particleList='pi+:generic_0', sampling=('isPrimarySignal', {}))
357  path.add_module('VariablesToHistogram', particleList='K+:generic_0',
358  variables=fei.config.variables2binnings(['mcErrors', 'mcParticleStatus', 'p', 'dr', 'isPrimarySignal']),
359  variables_2d=fei.config.variables2binnings_2d([('p', 'isPrimarySignal'), ('dr', 'isPrimarySignal')]),
360  fileName='Monitor_TrainingData.root', directory='K+:generic ==> K+:FSP')
361  path.add_module('VariablesToNtuple', fileName='training_input.root', treeName='K+:generic ==> K+:FSP variables',
362  variables=['p', 'dr', 'isPrimarySignal'],
363  particleList='K+:generic_0', sampling=('isPrimarySignal', {}))
364  path.add_module('VariablesToHistogram', particleList='D0:generic_0',
365  variables=fei.config.variables2binnings(['mcErrors', 'mcParticleStatus', 'M', 'p', 'isSignal']),
366  variables_2d=fei.config.variables2binnings_2d([('M', 'isSignal'), ('p', 'isSignal')]),
367  fileName='Monitor_TrainingData.root', directory='D0:generic ==> K-:generic pi+:generic')
368  path.add_module('VariablesToNtuple', fileName='training_input.root',
369  treeName='D0:generic ==> K-:generic pi+:generic variables',
370  variables=['M', 'p', 'isSignal'],
371  particleList='D0:generic_0', sampling=('isSignal', {}))
372  path.add_module('VariablesToHistogram', particleList='D0:generic_1',
373  variables=fei.config.variables2binnings(['mcErrors', 'mcParticleStatus', 'M', 'p', 'isSignal']),
374  variables_2d=fei.config.variables2binnings_2d([('M', 'isSignal'), ('p', 'isSignal')]),
375  fileName='Monitor_TrainingData.root', directory='D0:generic ==> pi-:generic pi+:generic')
376  path.add_module('VariablesToNtuple', fileName='training_input.root',
377  treeName='D0:generic ==> pi-:generic pi+:generic variables',
378  variables=['M', 'p', 'isSignal'],
379  particleList='D0:generic_1', sampling=('isSignal', {}))
380  print_path(path, x.reconstruct())
381  self.assertEqual(x.reconstruct(), path)
382 
383 
384 class TestPreReconstruction(unittest.TestCase):
385 
386  def test_without_monitoring(self):
387  particles = get_small_unittest_channels()
388  config = fei.config.FeiConfiguration(monitor=False)
389  x = fei.core.PreReconstruction(particles, config)
390 
391  path = basf2.create_path()
392  path.add_module('ParticleListManipulator', inputListNames=['pi+:FSP'], outputListName='pi+:generic_0',
393  cut='[dr < 2] and [abs(dz) < 4]', writeOut=True)
394  path.add_module('VariablesToExtraInfo', particleList='pi+:generic_0', variables={'constant(0)': 'decayModeID'})
395  path.add_module('BestCandidateSelection', particleList='pi+:generic_0', variable='piid', selectLowest=False,
396  numBest=20, outputVariable='preCut_rank')
397 
398  path.add_module('ParticleListManipulator', inputListNames=['K+:FSP'], outputListName='K+:generic_0',
399  cut='[dr < 2] and [abs(dz) < 4]', writeOut=True)
400  path.add_module('VariablesToExtraInfo', particleList='K+:generic_0', variables={'constant(0)': 'decayModeID'})
401  path.add_module('BestCandidateSelection', particleList='K+:generic_0', variable='Kid', selectLowest=False,
402  numBest=20, outputVariable='preCut_rank')
403 
404  path.add_module('ParticleCombiner', decayString='D0:generic_0 -> K-:generic pi+:generic', writeOut=True,
405  decayMode=0, cut='1.7 < M < 1.95')
406  path.add_module('BestCandidateSelection', particleList='D0:generic_0',
407  variable='abs(dM)', selectLowest=True, numBest=20, outputVariable='preCut_rank')
408  path.add_module('ParticleVertexFitter', listName='D0:generic_0', confidenceLevel=-2.0,
409  vertexFitter='KFit', fitType='vertex')
410 
411  path.add_module('ParticleCombiner', decayString='D0:generic_1 -> pi-:generic pi+:generic', writeOut=True,
412  decayMode=1, cut='1.7 < M < 1.95')
413  path.add_module('BestCandidateSelection', particleList='D0:generic_1',
414  variable='abs(dM)', selectLowest=True, numBest=20, outputVariable='preCut_rank')
415  path.add_module('ParticleVertexFitter', listName='D0:generic_1', confidenceLevel=-2.0,
416  vertexFitter='KFit', fitType='vertex')
417 
418  print_path(path, x.reconstruct())
419  self.assertEqual(x.reconstruct(), path)
420 
421  def test_with_monitoring(self):
422  particles = get_small_unittest_channels()
423  config = fei.config.FeiConfiguration(monitor=True)
424  x = fei.core.PreReconstruction(particles, config)
425 
426  path = basf2.create_path()
427  path.add_module('ParticleListManipulator', inputListNames=['pi+:FSP'], outputListName='pi+:generic_0',
428  cut='[dr < 2] and [abs(dz) < 4]', writeOut=True)
429  path.add_module('VariablesToExtraInfo', particleList='pi+:generic_0', variables={'constant(0)': 'decayModeID'})
430  path.add_module('MCMatcherParticles', listName='pi+:generic_0')
431  path.add_module('VariablesToHistogram', particleList='pi+:generic_0',
432  variables=fei.config.variables2binnings(['piid', 'mcErrors', 'mcParticleStatus', 'isPrimarySignal']),
433  variables_2d=fei.config.variables2binnings_2d([('piid', 'isPrimarySignal'),
434  ('piid', 'mcErrors'),
435  ('piid', 'mcParticleStatus')]),
436  fileName='Monitor_PreReconstruction_BeforeRanking.root', directory='pi+:generic ==> pi+:FSP')
437  path.add_module('BestCandidateSelection', particleList='pi+:generic_0', variable='piid', selectLowest=False,
438  numBest=20, outputVariable='preCut_rank')
439  path.add_module('VariablesToHistogram', particleList='pi+:generic_0',
440  variables=fei.config.variables2binnings(['piid', 'mcErrors', 'mcParticleStatus',
441  'isPrimarySignal', 'extraInfo(preCut_rank)']),
442  variables_2d=fei.config.variables2binnings_2d([('piid', 'isPrimarySignal'),
443  ('piid', 'mcErrors'),
444  ('piid', 'mcParticleStatus'),
445  ('extraInfo(preCut_rank)', 'isPrimarySignal'),
446  ('extraInfo(preCut_rank)', 'mcErrors'),
447  ('extraInfo(preCut_rank)', 'mcParticleStatus')]),
448  fileName='Monitor_PreReconstruction_AfterRanking.root', directory='pi+:generic ==> pi+:FSP')
449  path.add_module('VariablesToHistogram', particleList='pi+:generic_0',
450  variables=fei.config.variables2binnings(['chiProb', 'mcErrors', 'mcParticleStatus',
451  'isPrimarySignal']),
452  variables_2d=fei.config.variables2binnings_2d([('chiProb', 'isPrimarySignal'),
453  ('chiProb', 'mcErrors'),
454  ('chiProb', 'mcParticleStatus')]),
455  fileName='Monitor_PreReconstruction_AfterVertex.root', directory='pi+:generic ==> pi+:FSP')
456 
457  path.add_module('ParticleListManipulator', inputListNames=['K+:FSP'], outputListName='K+:generic_0',
458  cut='[dr < 2] and [abs(dz) < 4]', writeOut=True)
459  path.add_module('VariablesToExtraInfo', particleList='K+:generic_0', variables={'constant(0)': 'decayModeID'})
460 
461  path.add_module('MCMatcherParticles', listName='K+:generic_0')
462  path.add_module('VariablesToHistogram', particleList='K+:generic_0',
463  variables=fei.config.variables2binnings(['Kid', 'mcErrors', 'mcParticleStatus', 'isPrimarySignal']),
464  variables_2d=fei.config.variables2binnings_2d([('Kid', 'isPrimarySignal'),
465  ('Kid', 'mcErrors'),
466  ('Kid', 'mcParticleStatus')]),
467  fileName='Monitor_PreReconstruction_BeforeRanking.root', directory='K+:generic ==> K+:FSP')
468  path.add_module('BestCandidateSelection', particleList='K+:generic_0', variable='Kid', selectLowest=False,
469  numBest=20, outputVariable='preCut_rank')
470  path.add_module('VariablesToHistogram', particleList='K+:generic_0',
471  variables=fei.config.variables2binnings(['Kid', 'mcErrors', 'mcParticleStatus',
472  'isPrimarySignal', 'extraInfo(preCut_rank)']),
473  variables_2d=fei.config.variables2binnings_2d([('Kid', 'isPrimarySignal'),
474  ('Kid', 'mcErrors'),
475  ('Kid', 'mcParticleStatus'),
476  ('extraInfo(preCut_rank)', 'isPrimarySignal'),
477  ('extraInfo(preCut_rank)', 'mcErrors'),
478  ('extraInfo(preCut_rank)', 'mcParticleStatus')]),
479  fileName='Monitor_PreReconstruction_AfterRanking.root', directory='K+:generic ==> K+:FSP')
480  path.add_module('VariablesToHistogram', particleList='K+:generic_0',
481  variables=fei.config.variables2binnings(['chiProb', 'mcErrors', 'mcParticleStatus',
482  'isPrimarySignal']),
483  variables_2d=fei.config.variables2binnings_2d([('chiProb', 'isPrimarySignal'),
484  ('chiProb', 'mcErrors'),
485  ('chiProb', 'mcParticleStatus')]),
486  fileName='Monitor_PreReconstruction_AfterVertex.root', directory='K+:generic ==> K+:FSP')
487 
488  path.add_module('ParticleCombiner', decayString='D0:generic_0 -> K-:generic pi+:generic', writeOut=True,
489  decayMode=0, cut='1.7 < M < 1.95')
490  path.add_module('MCMatcherParticles', listName='D0:generic_0')
491  path.add_module('VariablesToHistogram', particleList='D0:generic_0',
492  variables=fei.config.variables2binnings(['abs(dM)', 'mcErrors', 'mcParticleStatus', 'isSignal']),
493  variables_2d=fei.config.variables2binnings_2d([('abs(dM)', 'isSignal'),
494  ('abs(dM)', 'mcErrors'),
495  ('abs(dM)', 'mcParticleStatus')]),
496  fileName='Monitor_PreReconstruction_BeforeRanking.root', directory='D0:generic ==> K-:generic pi+:generic')
497  path.add_module('BestCandidateSelection', particleList='D0:generic_0',
498  variable='abs(dM)', selectLowest=True, numBest=20, outputVariable='preCut_rank')
499  path.add_module('VariablesToHistogram', particleList='D0:generic_0',
500  variables=fei.config.variables2binnings(['abs(dM)', 'mcErrors', 'mcParticleStatus',
501  'isSignal', 'extraInfo(preCut_rank)']),
502  variables_2d=fei.config.variables2binnings_2d([('abs(dM)', 'isSignal'),
503  ('abs(dM)', 'mcErrors'),
504  ('abs(dM)', 'mcParticleStatus'),
505  ('extraInfo(preCut_rank)', 'isSignal'),
506  ('extraInfo(preCut_rank)', 'mcErrors'),
507  ('extraInfo(preCut_rank)', 'mcParticleStatus')]),
508  fileName='Monitor_PreReconstruction_AfterRanking.root', directory='D0:generic ==> K-:generic pi+:generic')
509  path.add_module('ParticleVertexFitter', listName='D0:generic_0', confidenceLevel=-2.0,
510  vertexFitter='KFit', fitType='vertex')
511  path.add_module('VariablesToHistogram', particleList='D0:generic_0',
512  variables=fei.config.variables2binnings(['chiProb', 'mcErrors', 'mcParticleStatus',
513  'isSignal']),
514  variables_2d=fei.config.variables2binnings_2d([('chiProb', 'isSignal'),
515  ('chiProb', 'mcErrors'),
516  ('chiProb', 'mcParticleStatus')]),
517  fileName='Monitor_PreReconstruction_AfterVertex.root', directory='D0:generic ==> K-:generic pi+:generic')
518 
519  path.add_module('ParticleCombiner', decayString='D0:generic_1 -> pi-:generic pi+:generic', writeOut=True,
520  decayMode=1, cut='1.7 < M < 1.95')
521  path.add_module('MCMatcherParticles', listName='D0:generic_1')
522  path.add_module('VariablesToHistogram', particleList='D0:generic_1',
523  variables=fei.config.variables2binnings(['abs(dM)', 'mcErrors', 'mcParticleStatus', 'isSignal']),
524  variables_2d=fei.config.variables2binnings_2d([('abs(dM)', 'isSignal'),
525  ('abs(dM)', 'mcErrors'),
526  ('abs(dM)', 'mcParticleStatus')]),
527  fileName='Monitor_PreReconstruction_BeforeRanking.root', directory='D0:generic ==> pi-:generic pi+:generic')
528  path.add_module('BestCandidateSelection', particleList='D0:generic_1',
529  variable='abs(dM)', selectLowest=True, numBest=20, outputVariable='preCut_rank')
530  path.add_module('VariablesToHistogram', particleList='D0:generic_1',
531  variables=fei.config.variables2binnings(['abs(dM)', 'mcErrors', 'mcParticleStatus',
532  'isSignal', 'extraInfo(preCut_rank)']),
533  variables_2d=fei.config.variables2binnings_2d([('abs(dM)', 'isSignal'),
534  ('abs(dM)', 'mcErrors'),
535  ('abs(dM)', 'mcParticleStatus'),
536  ('extraInfo(preCut_rank)', 'isSignal'),
537  ('extraInfo(preCut_rank)', 'mcErrors'),
538  ('extraInfo(preCut_rank)', 'mcParticleStatus')]),
539  fileName='Monitor_PreReconstruction_AfterRanking.root', directory='D0:generic ==> pi-:generic pi+:generic')
540  path.add_module('ParticleVertexFitter', listName='D0:generic_1', confidenceLevel=-2.0,
541  vertexFitter='KFit', fitType='vertex')
542  path.add_module('VariablesToHistogram', particleList='D0:generic_1',
543  variables=fei.config.variables2binnings(['chiProb', 'mcErrors', 'mcParticleStatus',
544  'isSignal']),
545  variables_2d=fei.config.variables2binnings_2d([('chiProb', 'isSignal'),
546  ('chiProb', 'mcErrors'),
547  ('chiProb', 'mcParticleStatus')]),
548  fileName='Monitor_PreReconstruction_AfterVertex.root', directory='D0:generic ==> pi-:generic pi+:generic')
549 
550  print_path(path, x.reconstruct())
551  self.assertEqual(x.reconstruct(), path)
552 
553 
554 class TestPostReconstruction(unittest.TestCase):
555 
556  def test_get_missing_channels(self):
557  pion = Particle('pi+:unittest', fei.config.MVAConfiguration(variables=['p', 'dr'], target='isPrimarySignal'))
558  pion.addChannel(['pi+:FSP'])
559  D0 = Particle('D0:unittest', fei.config.MVAConfiguration(variables=['M', 'p'], target='isSignal'))
560  D0.addChannel(['K-:unittest', 'pi+:unittest'])
561  D0.addChannel(['pi-:unittest', 'pi+:unittest'])
562  config = fei.config.FeiConfiguration(monitor=False, prefix="UNITTEST")
563  x = fei.core.PostReconstruction([pion, D0], config)
564 
565  self.assertEqual(x.get_missing_channels(), ['pi+:unittest ==> pi+:FSP', 'D0:unittest ==> K-:unittest pi+:unittest',
566  'D0:unittest ==> pi-:unittest pi+:unittest'])
567  self.assertEqual(x.available(), False)
568 
569  content = """
570  <?xml version="1.0" encoding="utf-8"?>
571  <method>Trivial</method>
572  <weightfile>{channel}.xml</weightfile>
573  <treename>tree</treename>
574  <target_variable>isSignal</target_variable>
575  <weight_variable>__weight__</weight_variable>
576  <signal_class>1</signal_class>
577  <max_events>0</max_events>
578  <number_feature_variables>1</number_feature_variables>
579  <variable0>M</variable0>
580  <number_spectator_variables>0</number_spectator_variables>
581  <number_data_files>1</number_data_files>
582  <datafile0>train.root</datafile0>
583  <Trivial_version>1</Trivial_version>
584  <Trivial_output>0</Trivial_output>
585  <signal_fraction>0.066082567</signal_fraction>
586  """
587 
588  channel = 'D0:unittest ==> K-:unittest pi+:unittest'
589  with open(channel + ".xml", "w") as f:
590  f.write(content.format(channel=channel))
591  basf2_mva.upload(channel + ".xml", 'UNITTEST_' + channel)
592 
593  self.assertEqual(x.get_missing_channels(), ['pi+:unittest ==> pi+:FSP',
594  'D0:unittest ==> pi-:unittest pi+:unittest'])
595  self.assertEqual(x.available(), False)
596 
597  channel = 'D0:unittest ==> pi-:unittest pi+:unittest'
598  with open(channel + ".xml", "w") as f:
599  f.write(content.format(channel=channel))
600  basf2_mva.upload(channel + ".xml", 'UNITTEST_' + channel)
601 
602  self.assertEqual(x.get_missing_channels(), ['pi+:unittest ==> pi+:FSP'])
603  self.assertEqual(x.available(), False)
604 
605  channel = 'pi+:unittest ==> pi+:FSP'
606  with open(channel + ".xml", "w") as f:
607  f.write(content.format(channel=channel))
608  basf2_mva.upload(channel + ".xml", 'UNITTEST_' + channel)
609 
610  self.assertEqual(x.get_missing_channels(), [])
611  self.assertEqual(x.available(), True)
612 
613  def tearDown(self):
614  if os.path.isfile('pi+:unittest ==> pi+:FSP.xml'):
615  os.remove('pi+:unittest ==> pi+:FSP.xml')
616  if os.path.isfile('D0:unittest ==> pi-:unittest pi+:unittest.xml'):
617  os.remove('D0:unittest ==> pi-:unittest pi+:unittest.xml')
618  if os.path.isfile('D0:unittest ==> K-:unittest pi+:unittest.xml'):
619  os.remove('D0:unittest ==> K-:unittest pi+:unittest.xml')
620 
621  def test_without_monitoring(self):
622  particles = get_small_unittest_channels()
623  config = fei.config.FeiConfiguration(monitor=False, prefix='UNITTEST')
624  x = fei.core.PostReconstruction(particles, config)
625 
626  path = basf2.create_path()
627 
628  path.add_module('MVAExpert', identifier='UNITTEST_pi+:generic ==> pi+:FSP', extraInfoName='SignalProbability',
629  listNames=['pi+:generic_0'])
630  path.add_module('TagUniqueSignal', particleList='pi+:generic_0', target='isPrimarySignal',
631  extraInfoName='uniqueSignal')
632  path.add_module('ParticleListManipulator', outputListName='pi+:generic', inputListNames=['pi+:generic_0'],
633  variable='particleSource', writeOut=True)
634  path.add_module('ParticleSelector', decayString='pi+:generic', cut='0.01 < extraInfo(SignalProbability)')
635  path.add_module('BestCandidateSelection', particleList='pi+:generic', variable='extraInfo(SignalProbability)',
636  selectLowest=False, numBest=10, outputVariable='postCut_rank')
637 
638  path.add_module('MVAExpert', identifier='UNITTEST_K+:generic ==> K+:FSP', extraInfoName='SignalProbability',
639  listNames=['K+:generic_0'])
640  path.add_module('TagUniqueSignal', particleList='K+:generic_0', target='isPrimarySignal',
641  extraInfoName='uniqueSignal')
642  path.add_module('ParticleListManipulator', outputListName='K+:generic', inputListNames=['K+:generic_0'],
643  variable='particleSource', writeOut=True)
644  path.add_module('ParticleSelector', decayString='K+:generic', cut='0.01 < extraInfo(SignalProbability)')
645  path.add_module('BestCandidateSelection', particleList='K+:generic', variable='extraInfo(SignalProbability)',
646  selectLowest=False, numBest=10, outputVariable='postCut_rank')
647 
648  path.add_module('MVAExpert', identifier='UNITTEST_D0:generic ==> K-:generic pi+:generic',
649  extraInfoName='SignalProbability', listNames=['D0:generic_0'])
650  path.add_module('TagUniqueSignal', particleList='D0:generic_0', target='isSignal',
651  extraInfoName='uniqueSignal')
652 
653  path.add_module('MVAExpert', identifier='UNITTEST_D0:generic ==> pi-:generic pi+:generic',
654  extraInfoName='SignalProbability', listNames=['D0:generic_1'])
655  path.add_module('TagUniqueSignal', particleList='D0:generic_1', target='isSignal',
656  extraInfoName='uniqueSignal')
657 
658  path.add_module('ParticleListManipulator', outputListName='D0:generic',
659  inputListNames=['D0:generic_0', 'D0:generic_1'], variable='particleSource',
660  writeOut=True)
661  path.add_module('ParticleSelector', decayString='D0:generic', cut='0.001 < extraInfo(SignalProbability)')
662  path.add_module('BestCandidateSelection', particleList='D0:generic', variable='extraInfo(SignalProbability)',
663  selectLowest=False, numBest=10, outputVariable='postCut_rank')
664 
665  print_path(path, x.reconstruct())
666  self.assertEqual(x.reconstruct(), path)
667 
668  def test_without_monitoring_training_mode(self):
669  particles = get_small_unittest_channels()
670  config = fei.config.FeiConfiguration(monitor=False, prefix='UNITTEST', training=True)
671  x = fei.core.PostReconstruction(particles, config)
672 
673  path = basf2.create_path()
674 
675  path.add_module('MVAExpert', identifier='pi+:generic ==> pi+:FSP.xml', extraInfoName='SignalProbability',
676  listNames=['pi+:generic_0'])
677  path.add_module('TagUniqueSignal', particleList='pi+:generic_0', target='isPrimarySignal',
678  extraInfoName='uniqueSignal')
679  path.add_module('ParticleListManipulator', outputListName='pi+:generic', inputListNames=['pi+:generic_0'],
680  variable='particleSource', writeOut=True)
681  path.add_module('ParticleSelector', decayString='pi+:generic', cut='0.01 < extraInfo(SignalProbability)')
682  path.add_module('BestCandidateSelection', particleList='pi+:generic', variable='extraInfo(SignalProbability)',
683  selectLowest=False, numBest=10, outputVariable='postCut_rank')
684 
685  path.add_module('MVAExpert', identifier='K+:generic ==> K+:FSP.xml', extraInfoName='SignalProbability',
686  listNames=['K+:generic_0'])
687  path.add_module('TagUniqueSignal', particleList='K+:generic_0', target='isPrimarySignal',
688  extraInfoName='uniqueSignal')
689  path.add_module('ParticleListManipulator', outputListName='K+:generic', inputListNames=['K+:generic_0'],
690  variable='particleSource', writeOut=True)
691  path.add_module('ParticleSelector', decayString='K+:generic', cut='0.01 < extraInfo(SignalProbability)')
692  path.add_module('BestCandidateSelection', particleList='K+:generic', variable='extraInfo(SignalProbability)',
693  selectLowest=False, numBest=10, outputVariable='postCut_rank')
694 
695  path.add_module('MVAExpert', identifier='D0:generic ==> K-:generic pi+:generic.xml',
696  extraInfoName='SignalProbability', listNames=['D0:generic_0'])
697  path.add_module('TagUniqueSignal', particleList='D0:generic_0', target='isSignal',
698  extraInfoName='uniqueSignal')
699 
700  path.add_module('MVAExpert', identifier='D0:generic ==> pi-:generic pi+:generic.xml',
701  extraInfoName='SignalProbability', listNames=['D0:generic_1'])
702  path.add_module('TagUniqueSignal', particleList='D0:generic_1', target='isSignal',
703  extraInfoName='uniqueSignal')
704 
705  path.add_module('ParticleListManipulator', outputListName='D0:generic',
706  inputListNames=['D0:generic_0', 'D0:generic_1'], variable='particleSource',
707  writeOut=True)
708  path.add_module('ParticleSelector', decayString='D0:generic', cut='0.001 < extraInfo(SignalProbability)')
709  path.add_module('BestCandidateSelection', particleList='D0:generic', variable='extraInfo(SignalProbability)',
710  selectLowest=False, numBest=10, outputVariable='postCut_rank')
711 
712  print_path(path, x.reconstruct())
713  self.assertEqual(x.reconstruct(), path)
714 
715  def test_with_monitoring(self):
716  particles = get_small_unittest_channels()
717  config = fei.config.FeiConfiguration(monitor=True, prefix='UNITTEST')
718  x = fei.core.PostReconstruction(particles, config)
719 
720  path = basf2.create_path()
721 
722  path.add_module('MVAExpert', identifier='UNITTEST_pi+:generic ==> pi+:FSP', extraInfoName='SignalProbability',
723  listNames=['pi+:generic_0'])
724  path.add_module('TagUniqueSignal', particleList='pi+:generic_0', target='isPrimarySignal',
725  extraInfoName='uniqueSignal')
726 
727  path.add_module('VariablesToHistogram', particleList='pi+:generic_0',
728  variables=fei.config.variables2binnings(['mcErrors', 'mcParticleStatus', 'extraInfo(uniqueSignal)',
729  'extraInfo(SignalProbability)',
730  'isPrimarySignal', 'extraInfo(decayModeID)']),
731  variables_2d=fei.config.variables2binnings_2d([('extraInfo(SignalProbability)', 'isPrimarySignal'),
732  ('extraInfo(SignalProbability)', 'mcErrors'),
733  ('extraInfo(SignalProbability)', 'mcParticleStatus'),
734  ('extraInfo(decayModeID)', 'isPrimarySignal'),
735  ('extraInfo(decayModeID)', 'mcErrors'),
736  ('extraInfo(decayModeID)', 'extraInfo(uniqueSignal)'),
737  ('extraInfo(decayModeID)', 'mcParticleStatus')]),
738  fileName='Monitor_PostReconstruction_AfterMVA.root', directory='pi+:generic ==> pi+:FSP')
739  path.add_module('ParticleListManipulator', outputListName='pi+:generic', inputListNames=['pi+:generic_0'],
740  variable='particleSource', writeOut=True)
741  path.add_module('VariablesToHistogram', particleList='pi+:generic',
742  variables=fei.config.variables2binnings(['mcErrors', 'mcParticleStatus', 'extraInfo(uniqueSignal)',
743  'extraInfo(SignalProbability)',
744  'isPrimarySignal', 'extraInfo(decayModeID)']),
745  variables_2d=fei.config.variables2binnings_2d([('extraInfo(decayModeID)', 'isPrimarySignal'),
746  ('extraInfo(decayModeID)', 'mcErrors'),
747  ('extraInfo(decayModeID)', 'mcParticleStatus')]),
748  fileName='Monitor_PostReconstruction_BeforePostCut.root', directory='pi+:generic')
749  path.add_module('ParticleSelector', decayString='pi+:generic', cut='0.01 < extraInfo(SignalProbability)')
750  path.add_module('VariablesToHistogram', particleList='pi+:generic',
751  variables=fei.config.variables2binnings(['mcErrors', 'mcParticleStatus', 'extraInfo(uniqueSignal)',
752  'extraInfo(SignalProbability)',
753  'isPrimarySignal', 'extraInfo(decayModeID)']),
754  variables_2d=fei.config.variables2binnings_2d([('extraInfo(decayModeID)', 'isPrimarySignal'),
755  ('extraInfo(decayModeID)', 'mcErrors'),
756  ('extraInfo(decayModeID)', 'mcParticleStatus')]),
757  fileName='Monitor_PostReconstruction_BeforeRanking.root', directory='pi+:generic')
758  path.add_module('BestCandidateSelection', particleList='pi+:generic', variable='extraInfo(SignalProbability)',
759  selectLowest=False, numBest=10, outputVariable='postCut_rank')
760  path.add_module('VariablesToHistogram', particleList='pi+:generic',
761  variables=fei.config.variables2binnings(['mcErrors', 'mcParticleStatus', 'extraInfo(uniqueSignal)',
762  'extraInfo(SignalProbability)', 'isPrimarySignal',
763  'extraInfo(decayModeID)', 'extraInfo(postCut_rank)']),
764  variables_2d=fei.config.variables2binnings_2d([('extraInfo(decayModeID)', 'isPrimarySignal'),
765  ('extraInfo(decayModeID)', 'mcErrors'),
766  ('extraInfo(decayModeID)', 'mcParticleStatus'),
767  ('extraInfo(decayModeID)', 'extraInfo(postCut_rank)'),
768  ('isPrimarySignal', 'extraInfo(postCut_rank)'),
769  ('mcErrors', 'extraInfo(postCut_rank)'),
770  ('mcParticleStatus', 'extraInfo(postCut_rank)')]),
771  fileName='Monitor_PostReconstruction_AfterRanking.root', directory='pi+:generic')
772  path.add_module('VariablesToNtuple', fileName='Monitor_Final.root', treeName='pi+:generic variables',
773  variables=['extraInfo(SignalProbability)', 'mcErrors', 'mcParticleStatus', 'isPrimarySignal',
774  'extraInfo(uniqueSignal)', 'extraInfo(decayModeID)'],
775  particleList='pi+:generic')
776 
777  path.add_module('MVAExpert', identifier='UNITTEST_K+:generic ==> K+:FSP', extraInfoName='SignalProbability',
778  listNames=['K+:generic_0'])
779  path.add_module('TagUniqueSignal', particleList='K+:generic_0', target='isPrimarySignal',
780  extraInfoName='uniqueSignal')
781  path.add_module('VariablesToHistogram', particleList='K+:generic_0',
782  variables=fei.config.variables2binnings(['mcErrors', 'mcParticleStatus', 'extraInfo(uniqueSignal)',
783  'extraInfo(SignalProbability)',
784  'isPrimarySignal', 'extraInfo(decayModeID)']),
785  variables_2d=fei.config.variables2binnings_2d([('extraInfo(SignalProbability)', 'isPrimarySignal'),
786  ('extraInfo(SignalProbability)', 'mcErrors'),
787  ('extraInfo(SignalProbability)', 'mcParticleStatus'),
788  ('extraInfo(decayModeID)', 'isPrimarySignal'),
789  ('extraInfo(decayModeID)', 'mcErrors'),
790  ('extraInfo(decayModeID)', 'extraInfo(uniqueSignal)'),
791  ('extraInfo(decayModeID)', 'mcParticleStatus')]),
792  fileName='Monitor_PostReconstruction_AfterMVA.root', directory='K+:generic ==> K+:FSP')
793  path.add_module('ParticleListManipulator', outputListName='K+:generic', inputListNames=['K+:generic_0'],
794  variable='particleSource', writeOut=True)
795  path.add_module('VariablesToHistogram', particleList='K+:generic',
796  variables=fei.config.variables2binnings(['mcErrors', 'mcParticleStatus', 'extraInfo(uniqueSignal)',
797  'extraInfo(SignalProbability)',
798  'isPrimarySignal', 'extraInfo(decayModeID)']),
799  variables_2d=fei.config.variables2binnings_2d([('extraInfo(decayModeID)', 'isPrimarySignal'),
800  ('extraInfo(decayModeID)', 'mcErrors'),
801  ('extraInfo(decayModeID)', 'mcParticleStatus')]),
802  fileName='Monitor_PostReconstruction_BeforePostCut.root', directory='K+:generic')
803  path.add_module('ParticleSelector', decayString='K+:generic', cut='0.01 < extraInfo(SignalProbability)')
804  path.add_module('VariablesToHistogram', particleList='K+:generic',
805  variables=fei.config.variables2binnings(['mcErrors', 'mcParticleStatus', 'extraInfo(uniqueSignal)',
806  'extraInfo(SignalProbability)',
807  'isPrimarySignal', 'extraInfo(decayModeID)']),
808  variables_2d=fei.config.variables2binnings_2d([('extraInfo(decayModeID)', 'isPrimarySignal'),
809  ('extraInfo(decayModeID)', 'mcErrors'),
810  ('extraInfo(decayModeID)', 'mcParticleStatus')]),
811  fileName='Monitor_PostReconstruction_BeforeRanking.root', directory='K+:generic')
812  path.add_module('BestCandidateSelection', particleList='K+:generic', variable='extraInfo(SignalProbability)',
813  selectLowest=False, numBest=10, outputVariable='postCut_rank')
814  path.add_module('VariablesToHistogram', particleList='K+:generic',
815  variables=fei.config.variables2binnings(['mcErrors', 'mcParticleStatus', 'extraInfo(uniqueSignal)',
816  'extraInfo(SignalProbability)', 'isPrimarySignal',
817  'extraInfo(decayModeID)', 'extraInfo(postCut_rank)']),
818  variables_2d=fei.config.variables2binnings_2d([('extraInfo(decayModeID)', 'isPrimarySignal'),
819  ('extraInfo(decayModeID)', 'mcErrors'),
820  ('extraInfo(decayModeID)', 'mcParticleStatus'),
821  ('extraInfo(decayModeID)', 'extraInfo(postCut_rank)'),
822  ('isPrimarySignal', 'extraInfo(postCut_rank)'),
823  ('mcErrors', 'extraInfo(postCut_rank)'),
824  ('mcParticleStatus', 'extraInfo(postCut_rank)')]),
825  fileName='Monitor_PostReconstruction_AfterRanking.root', directory='K+:generic')
826  path.add_module('VariablesToNtuple', fileName='Monitor_Final.root', treeName='K+:generic variables',
827  variables=['extraInfo(SignalProbability)', 'mcErrors', 'mcParticleStatus', 'isPrimarySignal',
828  'extraInfo(uniqueSignal)', 'extraInfo(decayModeID)'],
829  particleList='K+:generic')
830 
831  path.add_module('MVAExpert', identifier='UNITTEST_D0:generic ==> K-:generic pi+:generic',
832  extraInfoName='SignalProbability', listNames=['D0:generic_0'])
833  path.add_module('TagUniqueSignal', particleList='D0:generic_0', target='isSignal',
834  extraInfoName='uniqueSignal')
835  path.add_module('VariablesToHistogram', particleList='D0:generic_0',
836  variables=fei.config.variables2binnings(['mcErrors', 'mcParticleStatus', 'extraInfo(uniqueSignal)',
837  'extraInfo(SignalProbability)',
838  'isSignal', 'extraInfo(decayModeID)']),
839  variables_2d=fei.config.variables2binnings_2d([('extraInfo(SignalProbability)', 'isSignal'),
840  ('extraInfo(SignalProbability)', 'mcErrors'),
841  ('extraInfo(SignalProbability)', 'mcParticleStatus'),
842  ('extraInfo(decayModeID)', 'isSignal'),
843  ('extraInfo(decayModeID)', 'mcErrors'),
844  ('extraInfo(decayModeID)', 'extraInfo(uniqueSignal)'),
845  ('extraInfo(decayModeID)', 'mcParticleStatus')]),
846  fileName='Monitor_PostReconstruction_AfterMVA.root', directory='D0:generic ==> K-:generic pi+:generic')
847 
848  path.add_module('MVAExpert', identifier='UNITTEST_D0:generic ==> pi-:generic pi+:generic',
849  extraInfoName='SignalProbability', listNames=['D0:generic_1'])
850  path.add_module('TagUniqueSignal', particleList='D0:generic_1', target='isSignal',
851  extraInfoName='uniqueSignal')
852  path.add_module('VariablesToHistogram', particleList='D0:generic_1',
853  variables=fei.config.variables2binnings(['mcErrors', 'mcParticleStatus', 'extraInfo(uniqueSignal)',
854  'extraInfo(SignalProbability)',
855  'isSignal', 'extraInfo(decayModeID)']),
856  variables_2d=fei.config.variables2binnings_2d([('extraInfo(SignalProbability)', 'isSignal'),
857  ('extraInfo(SignalProbability)', 'mcErrors'),
858  ('extraInfo(SignalProbability)', 'mcParticleStatus'),
859  ('extraInfo(decayModeID)', 'isSignal'),
860  ('extraInfo(decayModeID)', 'mcErrors'),
861  ('extraInfo(decayModeID)', 'extraInfo(uniqueSignal)'),
862  ('extraInfo(decayModeID)', 'mcParticleStatus')]),
863  fileName='Monitor_PostReconstruction_AfterMVA.root', directory='D0:generic ==> pi-:generic pi+:generic')
864 
865  path.add_module('ParticleListManipulator', outputListName='D0:generic',
866  inputListNames=['D0:generic_0', 'D0:generic_1'], variable='particleSource',
867  writeOut=True)
868  path.add_module('VariablesToHistogram', particleList='D0:generic',
869  variables=fei.config.variables2binnings(['mcErrors', 'mcParticleStatus', 'extraInfo(uniqueSignal)',
870  'extraInfo(SignalProbability)',
871  'isSignal', 'extraInfo(decayModeID)']),
872  variables_2d=fei.config.variables2binnings_2d([('extraInfo(decayModeID)', 'isSignal'),
873  ('extraInfo(decayModeID)', 'mcErrors'),
874  ('extraInfo(decayModeID)', 'mcParticleStatus')]),
875  fileName='Monitor_PostReconstruction_BeforePostCut.root', directory='D0:generic')
876  path.add_module('ParticleSelector', decayString='D0:generic', cut='0.001 < extraInfo(SignalProbability)')
877  path.add_module('VariablesToHistogram', particleList='D0:generic',
878  variables=fei.config.variables2binnings(['mcErrors', 'mcParticleStatus', 'extraInfo(uniqueSignal)',
879  'extraInfo(SignalProbability)',
880  'isSignal', 'extraInfo(decayModeID)']),
881  variables_2d=fei.config.variables2binnings_2d([('extraInfo(decayModeID)', 'isSignal'),
882  ('extraInfo(decayModeID)', 'mcErrors'),
883  ('extraInfo(decayModeID)', 'mcParticleStatus')]),
884  fileName='Monitor_PostReconstruction_BeforeRanking.root', directory='D0:generic')
885  path.add_module('BestCandidateSelection', particleList='D0:generic', variable='extraInfo(SignalProbability)',
886  selectLowest=False, numBest=10, outputVariable='postCut_rank')
887  path.add_module('VariablesToHistogram', particleList='D0:generic',
888  variables=fei.config.variables2binnings(['mcErrors', 'mcParticleStatus', 'extraInfo(uniqueSignal)',
889  'extraInfo(SignalProbability)', 'isSignal',
890  'extraInfo(decayModeID)', 'extraInfo(postCut_rank)']),
891  variables_2d=fei.config.variables2binnings_2d([('extraInfo(decayModeID)', 'isSignal'),
892  ('extraInfo(decayModeID)', 'mcErrors'),
893  ('extraInfo(decayModeID)', 'mcParticleStatus'),
894  ('extraInfo(decayModeID)', 'extraInfo(postCut_rank)'),
895  ('isSignal', 'extraInfo(postCut_rank)'),
896  ('mcErrors', 'extraInfo(postCut_rank)'),
897  ('mcParticleStatus', 'extraInfo(postCut_rank)')]),
898  fileName='Monitor_PostReconstruction_AfterRanking.root', directory='D0:generic')
899  path.add_module('VariablesToNtuple', fileName='Monitor_Final.root', treeName='D0:generic variables',
900  variables=['extraInfo(SignalProbability)', 'mcErrors', 'mcParticleStatus', 'isSignal',
901  'extraInfo(uniqueSignal)', 'extraInfo(decayModeID)'],
902  particleList='D0:generic')
903 
904  print_path(path, x.reconstruct())
905  self.assertEqual(x.reconstruct(), path)
906 
907 
908 class TestTeacher(unittest.TestCase):
909  def setUp(self):
910  fei.core.Teacher.MaximumNumberOfMVASamples = int(1e7)
911  fei.core.Teacher.MinimumNumberOfMVASamples = int(10)
912 
913  f = ROOT.TFile('training_input.root', 'RECREATE')
914  f.cd()
915  tree = ROOT.TTree('pi+:generic ==> pi+:FSP variables', 'pi+:generic ==> pi+:FSP variables')
916  isSignal = np.zeros(1, dtype=float)
917  p = np.zeros(1, dtype=float)
918  pt = np.zeros(1, dtype=float)
919  tree.Branch('isPrimarySignal', isSignal, 'isPrimarySignal/D')
920  tree.Branch('p', p, 'p/D')
921  tree.Branch('dr', pt, 'dr/D')
922  for i in range(1000):
923  isSignal[0] = i % 2
924  p[0] = i
925  pt[0] = i * 2
926  tree.Fill()
927  tree.Write("", ROOT.TObject.kOverwrite)
928 
929  # Test case, where tree not existent for K+:generic ==> K+:FSP, so skip creating it
930 
931  tree = ROOT.TTree('D0:generic ==> K-:generic pi+:generic variables', 'D0:generic ==> K-:generic pi+:generic variables')
932  isSignal = np.zeros(1, dtype=float)
933  p = np.zeros(1, dtype=float)
934  pt = np.zeros(1, dtype=float)
935  tree.Branch('isSignal', isSignal, 'isSignal/D')
936  tree.Branch('M', p, 'M/D')
937  tree.Branch('p', pt, 'p/D')
938  # Too few signal events here!
939  for i in range(10):
940  isSignal[0] = i % 2
941  p[0] = i
942  pt[0] = i * 2
943  tree.Fill()
944  tree.Write("", ROOT.TObject.kOverwrite)
945 
946  tree = ROOT.TTree('D0:generic ==> pi-:generic pi+:generic variables', 'D0:generic ==> pi-:generic pi+:generic variables')
947  isSignal = np.zeros(1, dtype=float)
948  p = np.zeros(1, dtype=float)
949  pt = np.zeros(1, dtype=float)
950  tree.Branch('isSignal', isSignal, 'isSignal/D')
951  tree.Branch('M', p, 'M/D')
952  tree.Branch('p', pt, 'p/D')
953  for i in range(1000):
954  isSignal[0] = i % 2
955  p[0] = i
956  pt[0] = i * 2
957  tree.Fill()
958  tree.Write("", ROOT.TObject.kOverwrite)
959 
960  def tearDown(self):
961  if os.path.isfile('UNITTEST_TEACHER.xml'):
962  os.remove('UNITTEST_TEACHER.xml')
963  if os.path.isfile('UNITTEST_pi+:generic ==> pi+:FSP.xml'):
964  os.remove('UNITTEST_pi+:generic ==> pi+:FSP.xml')
965  if os.path.isfile('UNITTEST_K+:generic ==> K+:FSP.xml'):
966  os.remove('UNITTEST_K+:generic ==> K+:FSP.xml')
967  if os.path.isfile('UNITTEST_D0:generic ==> K-:generic pi+:generic.xml'):
968  os.remove('UNITTEST_D0:generic ==> K-:generic pi+:generic.xml')
969  if os.path.isfile('UNITTEST_D0:generic ==> pi-:generic pi+:generic.xml'):
970  os.remove('UNITTEST_D0:generic ==> pi-:generic pi+:generic.xml')
971  if os.path.isfile('training_input.root'):
972  os.remove('training_input.root')
973 
974  def test_create_fake_weightfile(self):
975  self.assertEqual(os.path.isfile('UNITTEST_pi+:generic ==> pi+:FSP.xml'), False)
976  self.assertEqual(basf2_mva.available('UNITTEST_pi+:generic ==> pi+:FSP.xml'), False)
977  fei.core.Teacher.create_fake_weightfile('UNITTEST_pi+:generic ==> pi+:FSP')
978  self.assertEqual(os.path.isfile('UNITTEST_pi+:generic ==> pi+:FSP.xml'), True)
979  self.assertEqual(basf2_mva.available('UNITTEST_pi+:generic ==> pi+:FSP.xml'), True)
980 
981  def test_upload(self):
982  particles = get_small_unittest_channels()
983  config = fei.config.FeiConfiguration(monitor=False, prefix='UNITTEST', externTeacher='basf2_mva_teacher')
984  x = fei.core.Teacher(particles, config)
985  fei.core.Teacher.create_fake_weightfile('TEACHER')
986  self.assertEqual(basf2_mva.available('UNITTEST_TEACHER'), False)
987  r = x.upload('TEACHER')
988  self.assertEqual(basf2_mva.available('UNITTEST_TEACHER'), True)
989  self.assertEqual(r, ('TEACHER.xml', 'UNITTEST_TEACHER'))
990 
991  def test_without_monitoring(self):
992  particles = get_small_unittest_channels()
993  config = fei.config.FeiConfiguration(monitor=False, prefix='UNITTEST', externTeacher='basf2_mva_teacher')
994  x = fei.core.Teacher(particles, config)
995 
996  self.assertEqual(basf2_mva.available('UNITTEST_pi+:generic ==> pi+:FSP'), False)
997  self.assertEqual(basf2_mva.available('UNITTEST_K+:generic ==> K+:FSP'), False)
998  self.assertEqual(basf2_mva.available('UNITTEST_D0:generic ==> K-:generic pi+:generic'), False)
999  self.assertEqual(basf2_mva.available('UNITTEST_D0:generic ==> pi-:generic pi+:generic'), False)
1000 
1001  x.do_all_trainings()
1002 
1003  self.assertEqual(basf2_mva.available('UNITTEST_pi+:generic ==> pi+:FSP'), True)
1004  self.assertEqual(basf2_mva.available('UNITTEST_K+:generic ==> K+:FSP'), False)
1005  self.assertEqual(basf2_mva.available('UNITTEST_D0:generic ==> K-:generic pi+:generic'), True)
1006  self.assertEqual(basf2_mva.available('UNITTEST_D0:generic ==> pi-:generic pi+:generic'), True)
1007 
1008 
1009 """
1010 class TestConvertLegacyTraining(unittest.TestCase):
1011  pass
1012 """
1013 
1014 
1015 class TestGetPath(unittest.TestCase):
1016 
1017  def setUp(self):
1018  particles = fei.get_unittest_channels()
1019 
1020  f = ROOT.TFile('mcParticlesCount.root', 'RECREATE')
1021  f.cd()
1022 
1023  for pdgnumber in set([abs(pdg.from_name(particle.name)) for particle in particles]):
1024  hist = ROOT.TH1F(f"NumberOfMCParticlesInEvent__bo{pdgnumber}__bc",
1025  f"NumberOfMCParticlesInEvent__bo{pdgnumber}__bc", 11, -0.5, 10.5)
1026  for i in range(10):
1027  hist.Fill(5)
1028  f.Write(f"NumberOfMCParticlesInEvent__bo{pdgnumber}__bc")
1029 
1030  def tearDown(self):
1031  if os.path.isfile('mcParticlesCount.root'):
1032  os.remove('mcParticlesCount.root')
1033  if os.path.isfile('Summary.pickle'):
1034  os.remove('Summary.pickle')
1035 
1036  def test_get_path_default_cache(self):
1037  particles = fei.get_unittest_channels()
1038  config = fei.config.FeiConfiguration(training=True)
1039  x = fei.core.Teacher(particles, config) # noqa
1040 
1041  # Should try to create mcParticlesCount
1042  # -> Returns at stage 0
1043  feistate = fei.core.get_path(particles, config)
1044  self.assertEqual(feistate.stage, 0)
1045 
1046  # Should try to create training data for FSPs
1047  # -> Returns at stage 1
1048  config = fei.config.FeiConfiguration(training=True)
1049  feistate = fei.core.get_path(particles, config)
1050  self.assertEqual(feistate.stage, 1)
1051 
1052  # No weightfiles were created, hence the algorithm
1053  # cannot go forward and tries to create the training data again
1054  config = fei.config.FeiConfiguration(training=True)
1055  feistate = fei.core.get_path(particles, config)
1056  self.assertEqual(feistate.stage, 1)
1057 
1058  # We create the FSP weightfiles by hand
1059  fei.core.Teacher.create_fake_weightfile('pi+:generic ==> pi+:FSP')
1060  fei.core.Teacher.create_fake_weightfile('K+:generic ==> K+:FSP')
1061  fei.core.Teacher.create_fake_weightfile('mu+:generic ==> mu+:FSP')
1062  fei.core.Teacher.create_fake_weightfile('gamma:generic ==> gamma:FSP')
1063  fei.core.Teacher.create_fake_weightfile('gamma:generic ==> gamma:V0')
1064 
1065  # Should try to create training data for pi0
1066  # -> Returns at stage 2
1067  config = fei.config.FeiConfiguration(training=True)
1068  feistate = fei.core.get_path(particles, config)
1069  self.assertEqual(feistate.stage, 2)
1070 
1071  # No weightfiles were created, hence the algorithm
1072  # cannot go forward and tries to create the training data again
1073  config = fei.config.FeiConfiguration(training=True)
1074  feistate = fei.core.get_path(particles, config)
1075  self.assertEqual(feistate.stage, 2)
1076 
1077  # We create the pi0 weightfile by hand
1078  fei.core.Teacher.create_fake_weightfile('pi0:generic ==> gamma:generic gamma:generic')
1079 
1080  # Should try to create training data for D0
1081  # -> Returns stage 4 (stage 3 is skipped because it only contains K_S0)
1082  config = fei.config.FeiConfiguration(training=True)
1083  feistate = fei.core.get_path(particles, config)
1084  self.assertEqual(feistate.stage, 4)
1085 
1086  # We create the D0 weightfiles by hand
1087  fei.core.Teacher.create_fake_weightfile('D0:generic ==> K-:generic pi+:generic')
1088  fei.core.Teacher.create_fake_weightfile('D0:generic ==> K-:generic pi+:generic pi0:generic')
1089  fei.core.Teacher.create_fake_weightfile('D0:generic ==> pi-:generic pi+:generic')
1090  fei.core.Teacher.create_fake_weightfile('D0:semileptonic ==> K-:generic mu+:generic')
1091  fei.core.Teacher.create_fake_weightfile('D0:semileptonic ==> K-:generic pi0:generic mu+:generic')
1092 
1093  # Unittest channels do not contain anymore stages,
1094  # -> Returns last stage + 1
1095  config = fei.config.FeiConfiguration(training=True)
1096  feistate = fei.core.get_path(particles, config)
1097  self.assertEqual(feistate.stage, 7)
1098 
1099  # If we start at 0, we should be get the whole path
1100  # -> Returns last stage + 1
1101  config = fei.config.FeiConfiguration(cache=0, training=True)
1102  feistate = fei.core.get_path(particles, config)
1103  self.assertEqual(feistate.stage, 7)
1104 
1105  # If training is False we should get the whole path without
1106  # checking if weightfiles exist.
1107  os.remove('pi+:generic ==> pi+:FSP.xml')
1108  os.remove('K+:generic ==> K+:FSP.xml')
1109  os.remove('mu+:generic ==> mu+:FSP.xml')
1110  os.remove('gamma:generic ==> gamma:FSP.xml')
1111  os.remove('gamma:generic ==> gamma:V0.xml')
1112  os.remove('pi0:generic ==> gamma:generic gamma:generic.xml')
1113  os.remove('D0:generic ==> K-:generic pi+:generic.xml')
1114  os.remove('D0:generic ==> K-:generic pi+:generic pi0:generic.xml')
1115  os.remove('D0:generic ==> pi-:generic pi+:generic.xml')
1116  os.remove('D0:semileptonic ==> K-:generic mu+:generic.xml')
1117  os.remove('D0:semileptonic ==> K-:generic pi0:generic mu+:generic.xml')
1118 
1119  config = fei.config.FeiConfiguration(cache=0, training=False)
1120  feistate = fei.core.get_path(particles, config)
1121  self.assertEqual(feistate.stage, 7)
1122 
1123  def test_get_path(self):
1124  particles = fei.get_unittest_channels()
1125  config = fei.config.FeiConfiguration(cache=-1, training=True)
1126  x = fei.core.Teacher(particles, config) # noqa
1127 
1128  # Should try to create mcParticlesCount
1129  # -> Returns at stage 0
1130  feistate = fei.core.get_path(particles, config)
1131  self.assertEqual(feistate.stage, 0)
1132 
1133  # Should try to create training data for FSPs
1134  # -> Returns at stage 1
1135  config = fei.config.FeiConfiguration(cache=0, training=True)
1136  feistate = fei.core.get_path(particles, config)
1137  self.assertEqual(feistate.stage, 1)
1138 
1139  # No weightfiles were created, hence the algorithm
1140  # cannot go forward and tries to create the training data again
1141  config = fei.config.FeiConfiguration(cache=1, training=True)
1142  feistate = fei.core.get_path(particles, config)
1143  self.assertEqual(feistate.stage, 1)
1144 
1145  # We create the FSP weightfiles by hand
1146  fei.core.Teacher.create_fake_weightfile('pi+:generic ==> pi+:FSP')
1147  fei.core.Teacher.create_fake_weightfile('K+:generic ==> K+:FSP')
1148  fei.core.Teacher.create_fake_weightfile('mu+:generic ==> mu+:FSP')
1149  fei.core.Teacher.create_fake_weightfile('gamma:generic ==> gamma:FSP')
1150  fei.core.Teacher.create_fake_weightfile('gamma:generic ==> gamma:V0')
1151 
1152  # Should try to create training data for pi0
1153  # -> Returns at stage 2
1154  config = fei.config.FeiConfiguration(cache=1, training=True)
1155  feistate = fei.core.get_path(particles, config)
1156  self.assertEqual(feistate.stage, 2)
1157 
1158  # No weightfiles were created, hence the algorithm
1159  # cannot go forward and tries to create the training data again
1160  config = fei.config.FeiConfiguration(cache=2, training=True)
1161  feistate = fei.core.get_path(particles, config)
1162  self.assertEqual(feistate.stage, 2)
1163 
1164  # No weightfiles were created, hence the algorithm
1165  # cannot go forward and tries to create the training data again
1166  # This applies as well if the stage is even bigger
1167  config = fei.config.FeiConfiguration(cache=4, training=True)
1168  feistate = fei.core.get_path(particles, config)
1169  self.assertEqual(feistate.stage, 2)
1170 
1171  # We create the pi0 weightfile by hand
1172  fei.core.Teacher.create_fake_weightfile('pi0:generic ==> gamma:generic gamma:generic')
1173 
1174  # Should try to create training data for D0
1175  # -> Returns stage 4 (stage 3 is skipped because it only contains K_S0)
1176  config = fei.config.FeiConfiguration(cache=2, training=True)
1177  feistate = fei.core.get_path(particles, config)
1178  self.assertEqual(feistate.stage, 4)
1179 
1180  # We create the D0 weightfiles by hand
1181  fei.core.Teacher.create_fake_weightfile('D0:generic ==> K-:generic pi+:generic')
1182  fei.core.Teacher.create_fake_weightfile('D0:generic ==> K-:generic pi+:generic pi0:generic')
1183  fei.core.Teacher.create_fake_weightfile('D0:generic ==> pi-:generic pi+:generic')
1184  fei.core.Teacher.create_fake_weightfile('D0:semileptonic ==> K-:generic mu+:generic')
1185  fei.core.Teacher.create_fake_weightfile('D0:semileptonic ==> K-:generic pi0:generic mu+:generic')
1186 
1187  # Unittest channels do not contain anymore stages,
1188  # -> Returns last stage + 1
1189  config = fei.config.FeiConfiguration(cache=4, training=True)
1190  feistate = fei.core.get_path(particles, config)
1191  self.assertEqual(feistate.stage, 7)
1192 
1193  # If we start at 0, we should be get the whole path
1194  # -> Returns last stage + 1
1195  config = fei.config.FeiConfiguration(cache=0, training=True)
1196  feistate = fei.core.get_path(particles, config)
1197  self.assertEqual(feistate.stage, 7)
1198 
1199  # If training is False we should get the whole path without
1200  # checking if weightfiles exist.
1201  os.remove('pi+:generic ==> pi+:FSP.xml')
1202  os.remove('K+:generic ==> K+:FSP.xml')
1203  os.remove('mu+:generic ==> mu+:FSP.xml')
1204  os.remove('gamma:generic ==> gamma:FSP.xml')
1205  os.remove('gamma:generic ==> gamma:V0.xml')
1206  os.remove('pi0:generic ==> gamma:generic gamma:generic.xml')
1207  os.remove('D0:generic ==> K-:generic pi+:generic.xml')
1208  os.remove('D0:generic ==> K-:generic pi+:generic pi0:generic.xml')
1209  os.remove('D0:generic ==> pi-:generic pi+:generic.xml')
1210  os.remove('D0:semileptonic ==> K-:generic mu+:generic.xml')
1211  os.remove('D0:semileptonic ==> K-:generic pi0:generic mu+:generic.xml')
1212 
1213  config = fei.config.FeiConfiguration(cache=0, training=False)
1214  feistate = fei.core.get_path(particles, config)
1215  self.assertEqual(feistate.stage, 7)
1216 
1217 
1218 if __name__ == '__main__':
1219  # We have to call basf2_mva once, so that ROOT can load the dictionaries
1220  # otherwise it will try to load them later after we changed the directory and it will fail to do so
1221  basf2_mva.loadRootDictionary()
1222  tempdir = tempfile.mkdtemp()
1223  os.chdir(tempdir)
1224  basf2.conditions.testing_payloads = ['localdb/database.txt']
1225  # main() never returns, so install exit handler to do our cleanup
1226  atexit.register(shutil.rmtree, tempdir)
1227  unittest.main()
1228 
1229 # @endcond
def setB2BII()
Definition: b2bii.py:21
def unsetB2BII()
Definition: b2bii.py:25
def from_name(name)
Definition: pdg.py:62