Belle II Software  release-08-01-10
test_fei.py
1 #!/usr/bin/env python3
2 
3 
10 
11 import basf2
12 import basf2_mva
13 import unittest
14 import unittest.mock
15 import b2test_utils
16 import os
17 import ROOT
18 
19 import b2bii
20 
21 import fei
22 from fei.config import Particle
23 
24 import numpy as np
25 
26 import pdg
27 
28 # @cond
29 
30 # Define equality operators for a bunch of pybasf2 classes
31 import pybasf2
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()))
36 
37 
38 def print_path(a, b):
39  """
40  Print the parts of the paths which are different
41  """
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()):
46  if n.name != m.name:
47  print(n.name, m.name)
48  if n.values != m.values:
49  print(n.name, n.values, m.values)
50 
51 
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',
59  bestCandidateCut=20),
60  fei.config.PostCutConfiguration(bestCandidateCut=10, value=0.01))
61  pion.addChannel(['pi+:FSP'])
62 
63  kaon = Particle('K+',
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',
69  bestCandidateCut=20),
70  fei.config.PostCutConfiguration(bestCandidateCut=10, value=0.01))
71  kaon.addChannel(['K+:FSP'])
72 
73  D0 = Particle('D0',
74  fei.config.MVAConfiguration(variables=['M', 'p'],
75  target='isSignal'),
76  fei.config.PreCutConfiguration(userCut='1.7 < M < 1.95',
77  bestCandidateMode='lowest',
78  bestCandidateVariable='abs(dM)',
79  bestCandidateCut=20),
80  fei.config.PostCutConfiguration(bestCandidateCut=10, value=0.001))
81  D0.addChannel(['K-', 'pi+'])
82  D0.addChannel(['pi-', 'pi+'])
83 
84  particles = [pion, kaon, D0]
85  return particles
86 
87 
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)
107 
108 
109 class TestTrainingDataInformation(unittest.TestCase):
110 
111  def tearDown(self):
112  if os.path.isfile('mcParticlesCount.root'):
113  os.remove('mcParticlesCount.root')
114 
115  def test_reconstruct(self):
116  particles = fei.get_unittest_channels()
117  x = fei.core.TrainingDataInformation(particles)
118 
119  path = basf2.create_path()
120  path.add_module('VariablesToHistogram', fileName='mcParticlesCount.root',
121  variables=[
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)]
128  )
129  print_path(path, x.reconstruct())
130  self.assertEqual(x.reconstruct(), path)
131 
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') # noqa
137  self.assertEqual(x.available(), True)
138 
139  def test_get_mc_counts(self):
140  f = ROOT.TFile('mcParticlesCount.root', 'RECREATE')
141  f.cd()
142  hist = ROOT.TH1F("NumberOfMCParticlesInEvent__bo211__bc", "NumberOfMCParticlesInEvent__bo211__bc", 11, -0.5, 10.5)
143  for i in range(10):
144  hist.Fill(5)
145  for i in range(5):
146  hist.Fill(4)
147  for i in range(3):
148  hist.Fill(3)
149  f.Write("NumberOfMCParticlesInEvent__bo211__bc")
150 
151  hist = ROOT.TH1F("NumberOfMCParticlesInEvent__bo321__bc", "NumberOfMCParticlesInEvent__bo321__bc", 11, -0.5, 10.5)
152  for i in range(8):
153  hist.Fill(4)
154  for i in range(5):
155  hist.Fill(2)
156  for i in range(5):
157  hist.Fill(7)
158  f.Write("NumberOfMCParticlesInEvent__bo321__bc")
159 
160  hist = ROOT.TH1F("NumberOfMCParticlesInEvent__bo13__bc", "NumberOfMCParticlesInEvent__bo13__bc", 11, -0.5, 10.5)
161  for i in range(18):
162  hist.Fill(5)
163  f.Write("NumberOfMCParticlesInEvent__bo13__bc")
164 
165  hist = ROOT.TH1F("NumberOfMCParticlesInEvent__bo22__bc", "NumberOfMCParticlesInEvent__bo222__bc", 11, -0.5, 10.5)
166  for i in range(18):
167  hist.Fill(0)
168  f.Write("NumberOfMCParticlesInEvent__bo22__bc")
169 
170  hist = ROOT.TH1F("NumberOfMCParticlesInEvent__bo111__bc", "NumberOfMCParticlesInEvent__bo111__bc", 11, -0.5, 10.5)
171  for i in range(5):
172  hist.Fill(5)
173  for i in range(10):
174  hist.Fill(4)
175  for i in range(3):
176  hist.Fill(3)
177  f.Write("NumberOfMCParticlesInEvent__bo111__bc")
178 
179  hist = ROOT.TH1F("NumberOfMCParticlesInEvent__bo421__bc", "NumberOfMCParticlesInEvent__bo421__bc", 11, -0.5, 10.5)
180  for i in range(10):
181  hist.Fill(9)
182  for i in range(5):
183  hist.Fill(0)
184  for i in range(3):
185  hist.Fill(1)
186  f.Write("NumberOfMCParticlesInEvent__bo421__bc")
187 
188  particles = fei.get_unittest_channels()
189  x = fei.core.TrainingDataInformation(particles)
190 
191  mcCounts = {
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},
198  0: {'sum': 18.0}}
199  self.assertDictEqual(x.get_mc_counts(), mcCounts)
200 
201 
202 class TestFSPLoader(unittest.TestCase):
203 
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)
208 
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)
212  for fsp in fsps:
213  path.add_module('ParticleListManipulator', outputListName=fsp,
214  inputListNames=[fsp.split(':')[0] + ':all'], writeOut=True)
215  if 'gamma' in fsp:
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)
222 
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)
227 
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)
231  for fsp in fsps:
232  path.add_module('ParticleListManipulator', outputListName=fsp,
233  inputListNames=[fsp.split(':')[0] + ':all'], writeOut=True)
234  if 'gamma' in fsp:
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)
246 
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)
252 
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)
256  for fsp in fsps:
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)
274 
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)
280 
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)
284  for fsp in fsps:
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)
307 
308 
309 class TestTrainingData(unittest.TestCase):
310 
311  def setUp(self):
312  self.mc_counts = {
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},
316  0: {'sum': 18}}
317 
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)
322 
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)
340 
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)
345 
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)
379 
380 
381 class TestPreReconstruction(unittest.TestCase):
382 
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)
387 
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')
394 
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')
400 
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')
407 
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')
414 
415  print_path(path, x.reconstruct())
416  self.assertEqual(x.reconstruct(), path)
417 
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)
422 
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',
448  'isPrimarySignal']),
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')
453 
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'})
457 
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'),
462  ('Kid', 'mcErrors'),
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'),
471  ('Kid', 'mcErrors'),
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',
479  'isPrimarySignal']),
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')
484 
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',
510  'isSignal']),
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')
515 
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',
541  'isSignal']),
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')
546 
547  print_path(path, x.reconstruct())
548  self.assertEqual(x.reconstruct(), path)
549 
550 
551 class TestPostReconstruction(unittest.TestCase):
552 
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)
561 
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)
565 
566  content = """
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>
583  """
584 
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)
589 
590  self.assertEqual(x.get_missing_channels(), ['pi+:unittest ==> pi+:FSP',
591  'D0:unittest ==> pi-:unittest pi+:unittest'])
592  self.assertEqual(x.available(), False)
593 
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)
598 
599  self.assertEqual(x.get_missing_channels(), ['pi+:unittest ==> pi+:FSP'])
600  self.assertEqual(x.available(), False)
601 
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)
606 
607  self.assertEqual(x.get_missing_channels(), [])
608  self.assertEqual(x.available(), True)
609 
610  def tearDown(self):
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')
617 
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)
622 
623  path = basf2.create_path()
624 
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')
634 
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')
644 
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')
649 
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')
654 
655  path.add_module('ParticleListManipulator', outputListName='D0:generic',
656  inputListNames=['D0:generic_0', 'D0:generic_1'], variable='particleSource',
657  writeOut=True)
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')
661 
662  print_path(path, x.reconstruct())
663  self.assertEqual(x.reconstruct(), path)
664 
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)
669 
670  path = basf2.create_path()
671 
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')
681 
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')
691 
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')
696 
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')
701 
702  path.add_module('ParticleListManipulator', outputListName='D0:generic',
703  inputListNames=['D0:generic_0', 'D0:generic_1'], variable='particleSource',
704  writeOut=True)
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')
708 
709  print_path(path, x.reconstruct())
710  self.assertEqual(x.reconstruct(), path)
711 
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)
716 
717  path = basf2.create_path()
718 
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')
723 
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')
773 
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')
827 
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')
844 
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')
861 
862  path.add_module('ParticleListManipulator', outputListName='D0:generic',
863  inputListNames=['D0:generic_0', 'D0:generic_1'], variable='particleSource',
864  writeOut=True)
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')
900 
901  print_path(path, x.reconstruct())
902  self.assertEqual(x.reconstruct(), path)
903 
904 
905 class TestTeacher(unittest.TestCase):
906  def setUp(self):
907  fei.core.Teacher.MaximumNumberOfMVASamples = int(1e7)
908  fei.core.Teacher.MinimumNumberOfMVASamples = int(10)
909 
910  f = ROOT.TFile('training_input.root', 'RECREATE')
911  f.cd()
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):
920  isSignal[0] = i % 2
921  p[0] = i
922  pt[0] = i * 2
923  tree.Fill()
924  tree.Write("", ROOT.TObject.kOverwrite)
925 
926  # Test case, where tree not existent for K+:generic ==> K+:FSP, so skip creating it
927 
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')
935  # Too few signal events here!
936  for i in range(10):
937  isSignal[0] = i % 2
938  p[0] = i
939  pt[0] = i * 2
940  tree.Fill()
941  tree.Write("", ROOT.TObject.kOverwrite)
942 
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):
951  isSignal[0] = i % 2
952  p[0] = i
953  pt[0] = i * 2
954  tree.Fill()
955  tree.Write("", ROOT.TObject.kOverwrite)
956 
957  def tearDown(self):
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')
970 
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)
977 
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'))
987 
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)
992 
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)
997 
998  x.do_all_trainings()
999 
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)
1004 
1005 
1006 """
1007 class TestConvertLegacyTraining(unittest.TestCase):
1008  pass
1009 """
1010 
1011 
1012 class TestGetPath(unittest.TestCase):
1013 
1014  def setUp(self):
1015  particles = fei.get_unittest_channels()
1016 
1017  f = ROOT.TFile('mcParticlesCount.root', 'RECREATE')
1018  f.cd()
1019 
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)
1023  for i in range(10):
1024  hist.Fill(5)
1025  f.Write(f"NumberOfMCParticlesInEvent__bo{pdgnumber}__bc")
1026 
1027  def tearDown(self):
1028  if os.path.isfile('mcParticlesCount.root'):
1029  os.remove('mcParticlesCount.root')
1030  if os.path.isfile('Summary.pickle'):
1031  os.remove('Summary.pickle')
1032 
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) # noqa
1037 
1038  # Should try to create mcParticlesCount
1039  # -> Returns at stage 0
1040  feistate = fei.core.get_path(particles, config)
1041  self.assertEqual(feistate.stage, 0)
1042 
1043  # Should try to create training data for FSPs
1044  # -> Returns at stage 1
1045  config = fei.config.FeiConfiguration(training=True)
1046  feistate = fei.core.get_path(particles, config)
1047  self.assertEqual(feistate.stage, 1)
1048 
1049  # No weightfiles were created, hence the algorithm
1050  # cannot go forward and tries to create the training data again
1051  config = fei.config.FeiConfiguration(training=True)
1052  feistate = fei.core.get_path(particles, config)
1053  self.assertEqual(feistate.stage, 1)
1054 
1055  # We create the FSP weightfiles by hand
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')
1061 
1062  # Should try to create training data for pi0
1063  # -> Returns at stage 2
1064  config = fei.config.FeiConfiguration(training=True)
1065  feistate = fei.core.get_path(particles, config)
1066  self.assertEqual(feistate.stage, 2)
1067 
1068  # No weightfiles were created, hence the algorithm
1069  # cannot go forward and tries to create the training data again
1070  config = fei.config.FeiConfiguration(training=True)
1071  feistate = fei.core.get_path(particles, config)
1072  self.assertEqual(feistate.stage, 2)
1073 
1074  # We create the pi0 weightfile by hand
1075  fei.core.Teacher.create_fake_weightfile('pi0:generic ==> gamma:generic gamma:generic')
1076 
1077  # Should try to create training data for D0
1078  # -> Returns stage 4 (stage 3 is skipped because it only contains K_S0)
1079  config = fei.config.FeiConfiguration(training=True)
1080  feistate = fei.core.get_path(particles, config)
1081  self.assertEqual(feistate.stage, 4)
1082 
1083  # We create the D0 weightfiles by hand
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')
1089 
1090  # Unittest channels do not contain anymore stages,
1091  # -> Returns last stage + 1
1092  config = fei.config.FeiConfiguration(training=True)
1093  feistate = fei.core.get_path(particles, config)
1094  self.assertEqual(feistate.stage, 7)
1095 
1096  # If we start at 0, we should be get the whole path
1097  # -> Returns last stage + 1
1098  config = fei.config.FeiConfiguration(cache=0, training=True)
1099  feistate = fei.core.get_path(particles, config)
1100  self.assertEqual(feistate.stage, 7)
1101 
1102  # If training is False we should get the whole path without
1103  # checking if weightfiles exist.
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')
1115 
1116  config = fei.config.FeiConfiguration(cache=0, training=False)
1117  feistate = fei.core.get_path(particles, config)
1118  self.assertEqual(feistate.stage, 7)
1119 
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) # noqa
1124 
1125  # Should try to create mcParticlesCount
1126  # -> Returns at stage 0
1127  feistate = fei.core.get_path(particles, config)
1128  self.assertEqual(feistate.stage, 0)
1129 
1130  # Should try to create training data for FSPs
1131  # -> Returns at stage 1
1132  config = fei.config.FeiConfiguration(cache=0, training=True)
1133  feistate = fei.core.get_path(particles, config)
1134  self.assertEqual(feistate.stage, 1)
1135 
1136  # No weightfiles were created, hence the algorithm
1137  # cannot go forward and tries to create the training data again
1138  config = fei.config.FeiConfiguration(cache=1, training=True)
1139  feistate = fei.core.get_path(particles, config)
1140  self.assertEqual(feistate.stage, 1)
1141 
1142  # We create the FSP weightfiles by hand
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')
1148 
1149  # Should try to create training data for pi0
1150  # -> Returns at stage 2
1151  config = fei.config.FeiConfiguration(cache=1, training=True)
1152  feistate = fei.core.get_path(particles, config)
1153  self.assertEqual(feistate.stage, 2)
1154 
1155  # No weightfiles were created, hence the algorithm
1156  # cannot go forward and tries to create the training data again
1157  config = fei.config.FeiConfiguration(cache=2, training=True)
1158  feistate = fei.core.get_path(particles, config)
1159  self.assertEqual(feistate.stage, 2)
1160 
1161  # No weightfiles were created, hence the algorithm
1162  # cannot go forward and tries to create the training data again
1163  # This applies as well if the stage is even bigger
1164  config = fei.config.FeiConfiguration(cache=4, training=True)
1165  feistate = fei.core.get_path(particles, config)
1166  self.assertEqual(feistate.stage, 2)
1167 
1168  # We create the pi0 weightfile by hand
1169  fei.core.Teacher.create_fake_weightfile('pi0:generic ==> gamma:generic gamma:generic')
1170 
1171  # Should try to create training data for D0
1172  # -> Returns stage 4 (stage 3 is skipped because it only contains K_S0)
1173  config = fei.config.FeiConfiguration(cache=2, training=True)
1174  feistate = fei.core.get_path(particles, config)
1175  self.assertEqual(feistate.stage, 4)
1176 
1177  # We create the D0 weightfiles by hand
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')
1183 
1184  # Unittest channels do not contain anymore stages,
1185  # -> Returns last stage + 1
1186  config = fei.config.FeiConfiguration(cache=4, training=True)
1187  feistate = fei.core.get_path(particles, config)
1188  self.assertEqual(feistate.stage, 7)
1189 
1190  # If we start at 0, we should be get the whole path
1191  # -> Returns last stage + 1
1192  config = fei.config.FeiConfiguration(cache=0, training=True)
1193  feistate = fei.core.get_path(particles, config)
1194  self.assertEqual(feistate.stage, 7)
1195 
1196  # If training is False we should get the whole path without
1197  # checking if weightfiles exist.
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')
1209 
1210  config = fei.config.FeiConfiguration(cache=0, training=False)
1211  feistate = fei.core.get_path(particles, config)
1212  self.assertEqual(feistate.stage, 7)
1213 
1214 
1215 if __name__ == '__main__':
1217  basf2.conditions.testing_payloads = ['localdb/database.txt']
1218  unittest.main()
1219 
1220 # @endcond
def setB2BII()
Definition: b2bii.py:21
def unsetB2BII()
Definition: b2bii.py:25
def clean_working_directory()
Definition: __init__.py:189
def from_name(name)
Definition: pdg.py:62