33 pybasf2.Module.__eq__ =
lambda a, b: a.type() == b.type()
and\
34 all(x == y
for x, y
in zip(a.available_params(), b.available_params()))
35 pybasf2.ModuleParamInfo.__eq__ =
lambda a, b: a.name == b.name
and a.values == b.values
36 pybasf2.Path.__eq__ =
lambda a, b: all(x == y
for x, y
in zip(a.modules(), b.modules()))
41 Print the parts of the paths which are different
43 for x, y
in zip(a.modules(), b.modules()):
44 if x.type() != y.type():
45 print(x.type(), y.type())
46 for n, m
in zip(x.available_params(), y.available_params()):
49 if n.values != m.values:
50 print(n.name, n.values, m.values)
53 def get_small_unittest_channels():
54 pion = Particle(
'pi+',
55 fei.config.MVAConfiguration(variables=[
'p',
'dr'],
56 target=
'isPrimarySignal'),
57 fei.config.PreCutConfiguration(userCut=
'[dr < 2] and [abs(dz) < 4]',
58 bestCandidateMode=
'highest',
59 bestCandidateVariable=
'piid',
61 fei.config.PostCutConfiguration(bestCandidateCut=10, value=0.01))
62 pion.addChannel([
'pi+:FSP'])
65 fei.config.MVAConfiguration(variables=[
'p',
'dr'],
66 target=
'isPrimarySignal'),
67 fei.config.PreCutConfiguration(userCut=
'[dr < 2] and [abs(dz) < 4]',
68 bestCandidateMode=
'highest',
69 bestCandidateVariable=
'Kid',
71 fei.config.PostCutConfiguration(bestCandidateCut=10, value=0.01))
72 kaon.addChannel([
'K+:FSP'])
75 fei.config.MVAConfiguration(variables=[
'M',
'p'],
77 fei.config.PreCutConfiguration(userCut=
'1.7 < M < 1.95',
78 bestCandidateMode=
'lowest',
79 bestCandidateVariable=
'abs(dM)',
81 fei.config.PostCutConfiguration(bestCandidateCut=10, value=0.001))
82 D0.addChannel([
'K-',
'pi+'])
83 D0.addChannel([
'pi-',
'pi+'])
85 particles = [pion, kaon, D0]
89 class TestGetStagesFromParticles(unittest.TestCase):
90 def test_get_stages_from_particles(self):
91 particles = fei.get_unittest_channels()
92 stages = fei.core.get_stages_from_particles(particles)
93 self.assertEqual(len(stages), 7)
94 self.assertEqual(len(stages[0]), 4)
95 self.assertEqual(stages[0][0].identifier,
'gamma:generic')
96 self.assertEqual(stages[0][1].identifier,
'mu+:generic')
97 self.assertEqual(stages[0][2].identifier,
'pi+:generic')
98 self.assertEqual(stages[0][3].identifier,
'K+:generic')
99 self.assertEqual(len(stages[1]), 1)
100 self.assertEqual(stages[1][0].identifier,
'pi0:generic')
101 self.assertEqual(len(stages[2]), 0)
102 self.assertEqual(len(stages[3]), 2)
103 self.assertEqual(stages[3][0].identifier,
'D0:generic')
104 self.assertEqual(stages[3][1].identifier,
'D0:semileptonic')
105 self.assertEqual(len(stages[4]), 0)
106 self.assertEqual(len(stages[5]), 0)
107 self.assertEqual(len(stages[6]), 0)
110 class TestTrainingDataInformation(unittest.TestCase):
113 if os.path.isfile(
'mcParticlesCount.root'):
114 os.remove(
'mcParticlesCount.root')
116 def test_reconstruct(self):
117 particles = fei.get_unittest_channels()
118 x = fei.core.TrainingDataInformation(particles)
120 path = basf2.create_path()
121 path.add_module(
'VariablesToHistogram', fileName=
'mcParticlesCount.root',
123 (
'NumberOfMCParticlesInEvent(321)', 100, -0.5, 99.5),
124 (
'NumberOfMCParticlesInEvent(421)', 100, -0.5, 99.5),
125 (
'NumberOfMCParticlesInEvent(13)', 100, -0.5, 99.5),
126 (
'NumberOfMCParticlesInEvent(111)', 100, -0.5, 99.5),
127 (
'NumberOfMCParticlesInEvent(211)', 100, -0.5, 99.5),
128 (
'NumberOfMCParticlesInEvent(22)', 100, -0.5, 99.5)]
130 print_path(path, x.reconstruct())
131 self.assertEqual(x.reconstruct(), path)
133 def test_available(self):
134 particles = fei.get_unittest_channels()
135 x = fei.core.TrainingDataInformation(particles)
136 self.assertEqual(x.available(),
False)
137 f = ROOT.TFile(
'mcParticlesCount.root',
'RECREATE')
138 self.assertEqual(x.available(),
True)
140 def test_get_mc_counts(self):
141 f = ROOT.TFile(
'mcParticlesCount.root',
'RECREATE')
143 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo211__bc",
"NumberOfMCParticlesInEvent__bo211__bc", 11, -0.5, 10.5)
150 f.Write(
"NumberOfMCParticlesInEvent__bo211__bc")
152 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo321__bc",
"NumberOfMCParticlesInEvent__bo321__bc", 11, -0.5, 10.5)
159 f.Write(
"NumberOfMCParticlesInEvent__bo321__bc")
161 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo13__bc",
"NumberOfMCParticlesInEvent__bo13__bc", 11, -0.5, 10.5)
164 f.Write(
"NumberOfMCParticlesInEvent__bo13__bc")
166 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo22__bc",
"NumberOfMCParticlesInEvent__bo222__bc", 11, -0.5, 10.5)
169 f.Write(
"NumberOfMCParticlesInEvent__bo22__bc")
171 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo111__bc",
"NumberOfMCParticlesInEvent__bo111__bc", 11, -0.5, 10.5)
178 f.Write(
"NumberOfMCParticlesInEvent__bo111__bc")
180 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo421__bc",
"NumberOfMCParticlesInEvent__bo421__bc", 11, -0.5, 10.5)
187 f.Write(
"NumberOfMCParticlesInEvent__bo421__bc")
189 particles = fei.get_unittest_channels()
190 x = fei.core.TrainingDataInformation(particles)
193 211: {
'max': 5.0,
'min': 3.0,
'sum': 79.0,
'avg': 4.3888888888888893,
'std': 0.7556372504852998},
194 321: {
'max': 7.0,
'min': 2.0,
'sum': 77.0,
'avg': 4.2777777777777777,
'std': 1.8798804795209585},
195 13: {
'max': 5.0,
'min': 5.0,
'sum': 90.0,
'avg': 5.0,
'std': 0.0},
196 22: {
'max': 0.0,
'min': 0.0,
'sum': 0.0,
'avg': 0.0,
'std': 0.0},
197 111: {
'max': 5.0,
'min': 3.0,
'sum': 74.0,
'avg': 4.1111111111111107,
'std': 0.6573421981221816},
198 421: {
'max': 9.0,
'min': 0.0,
'sum': 93.0,
'avg': 5.166666666666667,
'std': 4.2979323194092087},
200 self.assertDictEqual(x.get_mc_counts(), mcCounts)
203 class TestFSPLoader(unittest.TestCase):
205 def test_belle2_without_monitoring(self):
206 particles = get_small_unittest_channels()
207 config = fei.config.FeiConfiguration(monitor=
False)
208 x = fei.core.FSPLoader(particles, config)
210 path = basf2.create_path()
211 fsps = [
'K+:FSP',
'pi+:FSP',
'e+:FSP',
'mu+:FSP',
'gamma:FSP',
'p+:FSP',
'K_L0:FSP']
212 path.add_module(
'ParticleLoader', decayStrings=fsps, writeOut=
True)
214 path.add_module(
'ParticleListManipulator', outputListName=fsp,
215 inputListNames=[fsp.split(
':')[0] +
':all'], writeOut=
True)
217 path.add_module(
'ParticleSelector', decayString=
'gamma:FSP', cut=
'isFromECL')
218 path.add_module(
'ParticleLoader', decayStrings=[
'K_S0:V0 -> pi+ pi-'], writeOut=
True)
219 path.add_module(
'ParticleLoader', decayStrings=[
'Lambda0:V0 -> p+ pi-'], writeOut=
True)
220 path.add_module(
'ParticleLoader', decayStrings=[
'gamma:V0 -> e+ e-'], addDaughters=
True, writeOut=
True)
221 print_path(path, x.reconstruct())
222 self.assertEqual(x.reconstruct(), path)
224 def test_belle2_with_monitoring(self):
225 particles = get_small_unittest_channels()
226 config = fei.config.FeiConfiguration(monitor=
True)
227 x = fei.core.FSPLoader(particles, config)
229 path = basf2.create_path()
230 fsps = [
'K+:FSP',
'pi+:FSP',
'e+:FSP',
'mu+:FSP',
'gamma:FSP',
'p+:FSP',
'K_L0:FSP']
231 path.add_module(
'ParticleLoader', decayStrings=fsps, writeOut=
True)
233 path.add_module(
'ParticleListManipulator', outputListName=fsp,
234 inputListNames=[fsp.split(
':')[0] +
':all'], writeOut=
True)
236 path.add_module(
'ParticleSelector', decayString=
'gamma:FSP', cut=
'isFromECL')
237 path.add_module(
'ParticleLoader', decayStrings=[
'K_S0:V0 -> pi+ pi-'], writeOut=
True)
238 path.add_module(
'ParticleLoader', decayStrings=[
'Lambda0:V0 -> p+ pi-'], writeOut=
True)
239 path.add_module(
'ParticleLoader', decayStrings=[
'gamma:V0 -> e+ e-'], addDaughters=
True, writeOut=
True)
240 hist_variables = [(f
'NumberOfMCParticlesInEvent({pdgcode})', 100, -0.5, 99.5)
241 for pdgcode
in set([11, 321, 211, 13, 22, 310, 2212, 130, 3122, 111])]
242 path.add_module(
'VariablesToHistogram', particleList=
'',
243 variables=hist_variables,
244 fileName=
'Monitor_FSPLoader.root')
245 print_path(path, x.reconstruct())
246 self.assertEqual(x.reconstruct(), path)
248 def test_belle1_without_monitoring(self):
249 particles = get_small_unittest_channels()
251 config = fei.config.FeiConfiguration(monitor=
False)
252 x = fei.core.FSPLoader(particles, config)
254 path = basf2.create_path()
255 fsps = [
'K+:FSP',
'pi+:FSP',
'e+:FSP',
'mu+:FSP',
'p+:FSP']
256 path.add_module(
'ParticleLoader', decayStrings=fsps, writeOut=
True)
258 path.add_module(
'ParticleListManipulator', outputListName=fsp,
259 inputListNames=[fsp.split(
':')[0] +
':all'], writeOut=
True)
260 path.add_module(
'ParticleListManipulator', outputListName=
'gamma:FSP', inputListNames=[
'gamma:mdst'], writeOut=
True)
261 path.add_module(
'ParticleCopier', inputListNames=[
'gamma:FSP'])
262 path.add_module(
'ParticleListManipulator', outputListName=
'K_S0:V0', inputListNames=[
'K_S0:mdst'], writeOut=
True)
263 path.add_module(
'ParticleCopier', inputListNames=[
'K_S0:V0'])
264 path.add_module(
'ParticleListManipulator', outputListName=
'Lambda0:V0', inputListNames=[
'Lambda0:mdst'], writeOut=
True)
265 path.add_module(
'ParticleCopier', inputListNames=[
'Lambda0:V0'])
266 path.add_module(
'ParticleListManipulator', outputListName=
'K_L0:FSP', inputListNames=[
'K_L0:mdst'], writeOut=
True)
267 path.add_module(
'ParticleCopier', inputListNames=[
'K_L0:FSP'])
268 path.add_module(
'ParticleListManipulator', outputListName=
'pi0:FSP', inputListNames=[
'pi0:mdst'], writeOut=
True)
269 path.add_module(
'ParticleCopier', inputListNames=[
'pi0:FSP'])
270 path.add_module(
'ParticleListManipulator', outputListName=
'gamma:V0', inputListNames=[
'gamma:v0mdst'], writeOut=
True)
271 path.add_module(
'ParticleCopier', inputListNames=[
'gamma:V0'])
272 print_path(path, x.reconstruct())
273 self.assertEqual(x.reconstruct(), path)
276 def test_belle1_with_monitoring(self):
277 particles = get_small_unittest_channels()
279 config = fei.config.FeiConfiguration(monitor=
True)
280 x = fei.core.FSPLoader(particles, config)
282 path = basf2.create_path()
283 fsps = [
'K+:FSP',
'pi+:FSP',
'e+:FSP',
'mu+:FSP',
'p+:FSP']
284 path.add_module(
'ParticleLoader', decayStrings=fsps, writeOut=
True)
286 path.add_module(
'ParticleListManipulator', outputListName=fsp,
287 inputListNames=[fsp.split(
':')[0] +
':all'], writeOut=
True)
288 path.add_module(
'ParticleListManipulator', outputListName=
'gamma:FSP', inputListNames=[
'gamma:mdst'], writeOut=
True)
289 path.add_module(
'ParticleCopier', inputListNames=[
'gamma:FSP'])
290 path.add_module(
'ParticleListManipulator', outputListName=
'K_S0:V0', inputListNames=[
'K_S0:mdst'], writeOut=
True)
291 path.add_module(
'ParticleCopier', inputListNames=[
'K_S0:V0'])
292 path.add_module(
'ParticleListManipulator', outputListName=
'Lambda0:V0', inputListNames=[
'Lambda0:mdst'], writeOut=
True)
293 path.add_module(
'ParticleCopier', inputListNames=[
'Lambda0:V0'])
294 path.add_module(
'ParticleListManipulator', outputListName=
'K_L0:FSP', inputListNames=[
'K_L0:mdst'], writeOut=
True)
295 path.add_module(
'ParticleCopier', inputListNames=[
'K_L0:FSP'])
296 path.add_module(
'ParticleListManipulator', outputListName=
'pi0:FSP', inputListNames=[
'pi0:mdst'], writeOut=
True)
297 path.add_module(
'ParticleCopier', inputListNames=[
'pi0:FSP'])
298 path.add_module(
'ParticleListManipulator', outputListName=
'gamma:V0', inputListNames=[
'gamma:v0mdst'], writeOut=
True)
299 path.add_module(
'ParticleCopier', inputListNames=[
'gamma:V0'])
300 hist_variables = [(f
'NumberOfMCParticlesInEvent({pdgcode})', 100, -0.5, 99.5)
301 for pdgcode
in set([11, 321, 211, 13, 22, 310, 2212, 130, 3122, 111])]
302 path.add_module(
'VariablesToHistogram', particleList=
'',
303 variables=hist_variables,
304 fileName=
'Monitor_FSPLoader.root')
305 print_path(path, x.reconstruct())
306 self.assertEqual(x.reconstruct(), path)
310 class TestTrainingData(unittest.TestCase):
314 211: {
'sum': 79,
'avg': 4.3888888888888893,
'max': 5,
'min': 3,
'std': 0.75563725048530228},
315 321: {
'sum': 77,
'avg': 4.2777777777777777,
'max': 7,
'min': 2,
'std': 1.8798804795209592},
316 421: {
'sum': 93,
'avg': 5.166666666666667,
'max': 9,
'min': 0,
'std': 4.2979323194092087},
319 def test_without_monitoring(self):
320 particles = get_small_unittest_channels()
321 config = fei.config.FeiConfiguration(monitor=
False)
322 x = fei.core.TrainingData(particles, config, self.mc_counts)
324 path = basf2.create_path()
325 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root', treeName=
'pi+:generic ==> pi+:FSP variables',
326 variables=[
'p',
'dr',
'isPrimarySignal'],
327 particleList=
'pi+:generic_0', sampling=(
'isPrimarySignal', {}))
328 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root', treeName=
'K+:generic ==> K+:FSP variables',
329 variables=[
'p',
'dr',
'isPrimarySignal'],
330 particleList=
'K+:generic_0', sampling=(
'isPrimarySignal', {}))
331 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root',
332 treeName=
'D0:generic ==> K-:generic pi+:generic variables',
333 variables=[
'M',
'p',
'isSignal'],
334 particleList=
'D0:generic_0', sampling=(
'isSignal', {}))
335 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root',
336 treeName=
'D0:generic ==> pi-:generic pi+:generic variables',
337 variables=[
'M',
'p',
'isSignal'],
338 particleList=
'D0:generic_1', sampling=(
'isSignal', {}))
339 print_path(path, x.reconstruct())
340 self.assertEqual(x.reconstruct(), path)
342 def test_with_monitoring(self):
343 particles = get_small_unittest_channels()
344 config = fei.config.FeiConfiguration(monitor=
True)
345 x = fei.core.TrainingData(particles, config, self.mc_counts)
347 path = basf2.create_path()
348 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic_0',
349 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'p',
'dr',
'isPrimarySignal']),
350 variables_2d=fei.config.variables2binnings_2d([(
'p',
'isPrimarySignal'), (
'dr',
'isPrimarySignal')]),
351 fileName=
'Monitor_TrainingData.root', directory=
'pi+:generic ==> pi+:FSP')
352 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root', treeName=
'pi+:generic ==> pi+:FSP variables',
353 variables=[
'p',
'dr',
'isPrimarySignal'],
354 particleList=
'pi+:generic_0', sampling=(
'isPrimarySignal', {}))
355 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic_0',
356 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'p',
'dr',
'isPrimarySignal']),
357 variables_2d=fei.config.variables2binnings_2d([(
'p',
'isPrimarySignal'), (
'dr',
'isPrimarySignal')]),
358 fileName=
'Monitor_TrainingData.root', directory=
'K+:generic ==> K+:FSP')
359 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root', treeName=
'K+:generic ==> K+:FSP variables',
360 variables=[
'p',
'dr',
'isPrimarySignal'],
361 particleList=
'K+:generic_0', sampling=(
'isPrimarySignal', {}))
362 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_0',
363 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'M',
'p',
'isSignal']),
364 variables_2d=fei.config.variables2binnings_2d([(
'M',
'isSignal'), (
'p',
'isSignal')]),
365 fileName=
'Monitor_TrainingData.root', directory=
'D0:generic ==> K-:generic pi+:generic')
366 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root',
367 treeName=
'D0:generic ==> K-:generic pi+:generic variables',
368 variables=[
'M',
'p',
'isSignal'],
369 particleList=
'D0:generic_0', sampling=(
'isSignal', {}))
370 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_1',
371 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'M',
'p',
'isSignal']),
372 variables_2d=fei.config.variables2binnings_2d([(
'M',
'isSignal'), (
'p',
'isSignal')]),
373 fileName=
'Monitor_TrainingData.root', directory=
'D0:generic ==> pi-:generic pi+:generic')
374 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root',
375 treeName=
'D0:generic ==> pi-:generic pi+:generic variables',
376 variables=[
'M',
'p',
'isSignal'],
377 particleList=
'D0:generic_1', sampling=(
'isSignal', {}))
378 print_path(path, x.reconstruct())
379 self.assertEqual(x.reconstruct(), path)
382 class TestPreReconstruction(unittest.TestCase):
384 def test_without_monitoring(self):
385 particles = get_small_unittest_channels()
386 config = fei.config.FeiConfiguration(monitor=
False)
387 x = fei.core.PreReconstruction(particles, config)
389 path = basf2.create_path()
390 path.add_module(
'ParticleListManipulator', inputListNames=[
'pi+:FSP'], outputListName=
'pi+:generic_0',
391 cut=
'[dr < 2] and [abs(dz) < 4]', writeOut=
True)
392 path.add_module(
'VariablesToExtraInfo', particleList=
'pi+:generic_0', variables={
'constant(0)':
'decayModeID'})
393 path.add_module(
'BestCandidateSelection', particleList=
'pi+:generic_0', variable=
'piid', selectLowest=
False,
394 numBest=20, outputVariable=
'preCut_rank')
396 path.add_module(
'ParticleListManipulator', inputListNames=[
'K+:FSP'], outputListName=
'K+:generic_0',
397 cut=
'[dr < 2] and [abs(dz) < 4]', writeOut=
True)
398 path.add_module(
'VariablesToExtraInfo', particleList=
'K+:generic_0', variables={
'constant(0)':
'decayModeID'})
399 path.add_module(
'BestCandidateSelection', particleList=
'K+:generic_0', variable=
'Kid', selectLowest=
False,
400 numBest=20, outputVariable=
'preCut_rank')
402 path.add_module(
'ParticleCombiner', decayString=
'D0:generic_0 -> K-:generic pi+:generic', writeOut=
True,
403 decayMode=0, cut=
'1.7 < M < 1.95')
404 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic_0',
405 variable=
'abs(dM)', selectLowest=
True, numBest=20, outputVariable=
'preCut_rank')
406 path.add_module(
'ParticleVertexFitter', listName=
'D0:generic_0', confidenceLevel=-2.0,
407 vertexFitter=
'KFit', fitType=
'vertex')
409 path.add_module(
'ParticleCombiner', decayString=
'D0:generic_1 -> pi-:generic pi+:generic', writeOut=
True,
410 decayMode=1, cut=
'1.7 < M < 1.95')
411 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic_1',
412 variable=
'abs(dM)', selectLowest=
True, numBest=20, outputVariable=
'preCut_rank')
413 path.add_module(
'ParticleVertexFitter', listName=
'D0:generic_1', confidenceLevel=-2.0,
414 vertexFitter=
'KFit', fitType=
'vertex')
416 print_path(path, x.reconstruct())
417 self.assertEqual(x.reconstruct(), path)
419 def test_with_monitoring(self):
420 particles = get_small_unittest_channels()
421 config = fei.config.FeiConfiguration(monitor=
True)
422 x = fei.core.PreReconstruction(particles, config)
424 path = basf2.create_path()
425 path.add_module(
'ParticleListManipulator', inputListNames=[
'pi+:FSP'], outputListName=
'pi+:generic_0',
426 cut=
'[dr < 2] and [abs(dz) < 4]', writeOut=
True)
427 path.add_module(
'VariablesToExtraInfo', particleList=
'pi+:generic_0', variables={
'constant(0)':
'decayModeID'})
428 path.add_module(
'MCMatcherParticles', listName=
'pi+:generic_0')
429 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic_0',
430 variables=fei.config.variables2binnings([
'piid',
'mcErrors',
'mcParticleStatus',
'isPrimarySignal']),
431 variables_2d=fei.config.variables2binnings_2d([(
'piid',
'isPrimarySignal'),
432 (
'piid',
'mcErrors'),
433 (
'piid',
'mcParticleStatus')]),
434 fileName=
'Monitor_PreReconstruction_BeforeRanking.root', directory=
'pi+:generic ==> pi+:FSP')
435 path.add_module(
'BestCandidateSelection', particleList=
'pi+:generic_0', variable=
'piid', selectLowest=
False,
436 numBest=20, outputVariable=
'preCut_rank')
437 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic_0',
438 variables=fei.config.variables2binnings([
'piid',
'mcErrors',
'mcParticleStatus',
439 'isPrimarySignal',
'extraInfo(preCut_rank)']),
440 variables_2d=fei.config.variables2binnings_2d([(
'piid',
'isPrimarySignal'),
441 (
'piid',
'mcErrors'),
442 (
'piid',
'mcParticleStatus'),
443 (
'extraInfo(preCut_rank)',
'isPrimarySignal'),
444 (
'extraInfo(preCut_rank)',
'mcErrors'),
445 (
'extraInfo(preCut_rank)',
'mcParticleStatus')]),
446 fileName=
'Monitor_PreReconstruction_AfterRanking.root', directory=
'pi+:generic ==> pi+:FSP')
447 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic_0',
448 variables=fei.config.variables2binnings([
'chiProb',
'mcErrors',
'mcParticleStatus',
450 variables_2d=fei.config.variables2binnings_2d([(
'chiProb',
'isPrimarySignal'),
451 (
'chiProb',
'mcErrors'),
452 (
'chiProb',
'mcParticleStatus')]),
453 fileName=
'Monitor_PreReconstruction_AfterVertex.root', directory=
'pi+:generic ==> pi+:FSP')
455 path.add_module(
'ParticleListManipulator', inputListNames=[
'K+:FSP'], outputListName=
'K+:generic_0',
456 cut=
'[dr < 2] and [abs(dz) < 4]', writeOut=
True)
457 path.add_module(
'VariablesToExtraInfo', particleList=
'K+:generic_0', variables={
'constant(0)':
'decayModeID'})
459 path.add_module(
'MCMatcherParticles', listName=
'K+:generic_0')
460 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic_0',
461 variables=fei.config.variables2binnings([
'Kid',
'mcErrors',
'mcParticleStatus',
'isPrimarySignal']),
462 variables_2d=fei.config.variables2binnings_2d([(
'Kid',
'isPrimarySignal'),
464 (
'Kid',
'mcParticleStatus')]),
465 fileName=
'Monitor_PreReconstruction_BeforeRanking.root', directory=
'K+:generic ==> K+:FSP')
466 path.add_module(
'BestCandidateSelection', particleList=
'K+:generic_0', variable=
'Kid', selectLowest=
False,
467 numBest=20, outputVariable=
'preCut_rank')
468 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic_0',
469 variables=fei.config.variables2binnings([
'Kid',
'mcErrors',
'mcParticleStatus',
470 'isPrimarySignal',
'extraInfo(preCut_rank)']),
471 variables_2d=fei.config.variables2binnings_2d([(
'Kid',
'isPrimarySignal'),
473 (
'Kid',
'mcParticleStatus'),
474 (
'extraInfo(preCut_rank)',
'isPrimarySignal'),
475 (
'extraInfo(preCut_rank)',
'mcErrors'),
476 (
'extraInfo(preCut_rank)',
'mcParticleStatus')]),
477 fileName=
'Monitor_PreReconstruction_AfterRanking.root', directory=
'K+:generic ==> K+:FSP')
478 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic_0',
479 variables=fei.config.variables2binnings([
'chiProb',
'mcErrors',
'mcParticleStatus',
481 variables_2d=fei.config.variables2binnings_2d([(
'chiProb',
'isPrimarySignal'),
482 (
'chiProb',
'mcErrors'),
483 (
'chiProb',
'mcParticleStatus')]),
484 fileName=
'Monitor_PreReconstruction_AfterVertex.root', directory=
'K+:generic ==> K+:FSP')
486 path.add_module(
'ParticleCombiner', decayString=
'D0:generic_0 -> K-:generic pi+:generic', writeOut=
True,
487 decayMode=0, cut=
'1.7 < M < 1.95')
488 path.add_module(
'MCMatcherParticles', listName=
'D0:generic_0')
489 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_0',
490 variables=fei.config.variables2binnings([
'abs(dM)',
'mcErrors',
'mcParticleStatus',
'isSignal']),
491 variables_2d=fei.config.variables2binnings_2d([(
'abs(dM)',
'isSignal'),
492 (
'abs(dM)',
'mcErrors'),
493 (
'abs(dM)',
'mcParticleStatus')]),
494 fileName=
'Monitor_PreReconstruction_BeforeRanking.root', directory=
'D0:generic ==> K-:generic pi+:generic')
495 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic_0',
496 variable=
'abs(dM)', selectLowest=
True, numBest=20, outputVariable=
'preCut_rank')
497 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_0',
498 variables=fei.config.variables2binnings([
'abs(dM)',
'mcErrors',
'mcParticleStatus',
499 'isSignal',
'extraInfo(preCut_rank)']),
500 variables_2d=fei.config.variables2binnings_2d([(
'abs(dM)',
'isSignal'),
501 (
'abs(dM)',
'mcErrors'),
502 (
'abs(dM)',
'mcParticleStatus'),
503 (
'extraInfo(preCut_rank)',
'isSignal'),
504 (
'extraInfo(preCut_rank)',
'mcErrors'),
505 (
'extraInfo(preCut_rank)',
'mcParticleStatus')]),
506 fileName=
'Monitor_PreReconstruction_AfterRanking.root', directory=
'D0:generic ==> K-:generic pi+:generic')
507 path.add_module(
'ParticleVertexFitter', listName=
'D0:generic_0', confidenceLevel=-2.0,
508 vertexFitter=
'KFit', fitType=
'vertex')
509 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_0',
510 variables=fei.config.variables2binnings([
'chiProb',
'mcErrors',
'mcParticleStatus',
512 variables_2d=fei.config.variables2binnings_2d([(
'chiProb',
'isSignal'),
513 (
'chiProb',
'mcErrors'),
514 (
'chiProb',
'mcParticleStatus')]),
515 fileName=
'Monitor_PreReconstruction_AfterVertex.root', directory=
'D0:generic ==> K-:generic pi+:generic')
517 path.add_module(
'ParticleCombiner', decayString=
'D0:generic_1 -> pi-:generic pi+:generic', writeOut=
True,
518 decayMode=1, cut=
'1.7 < M < 1.95')
519 path.add_module(
'MCMatcherParticles', listName=
'D0:generic_1')
520 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_1',
521 variables=fei.config.variables2binnings([
'abs(dM)',
'mcErrors',
'mcParticleStatus',
'isSignal']),
522 variables_2d=fei.config.variables2binnings_2d([(
'abs(dM)',
'isSignal'),
523 (
'abs(dM)',
'mcErrors'),
524 (
'abs(dM)',
'mcParticleStatus')]),
525 fileName=
'Monitor_PreReconstruction_BeforeRanking.root', directory=
'D0:generic ==> pi-:generic pi+:generic')
526 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic_1',
527 variable=
'abs(dM)', selectLowest=
True, numBest=20, outputVariable=
'preCut_rank')
528 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_1',
529 variables=fei.config.variables2binnings([
'abs(dM)',
'mcErrors',
'mcParticleStatus',
530 'isSignal',
'extraInfo(preCut_rank)']),
531 variables_2d=fei.config.variables2binnings_2d([(
'abs(dM)',
'isSignal'),
532 (
'abs(dM)',
'mcErrors'),
533 (
'abs(dM)',
'mcParticleStatus'),
534 (
'extraInfo(preCut_rank)',
'isSignal'),
535 (
'extraInfo(preCut_rank)',
'mcErrors'),
536 (
'extraInfo(preCut_rank)',
'mcParticleStatus')]),
537 fileName=
'Monitor_PreReconstruction_AfterRanking.root', directory=
'D0:generic ==> pi-:generic pi+:generic')
538 path.add_module(
'ParticleVertexFitter', listName=
'D0:generic_1', confidenceLevel=-2.0,
539 vertexFitter=
'KFit', fitType=
'vertex')
540 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_1',
541 variables=fei.config.variables2binnings([
'chiProb',
'mcErrors',
'mcParticleStatus',
543 variables_2d=fei.config.variables2binnings_2d([(
'chiProb',
'isSignal'),
544 (
'chiProb',
'mcErrors'),
545 (
'chiProb',
'mcParticleStatus')]),
546 fileName=
'Monitor_PreReconstruction_AfterVertex.root', directory=
'D0:generic ==> pi-:generic pi+:generic')
548 print_path(path, x.reconstruct())
549 self.assertEqual(x.reconstruct(), path)
552 class TestPostReconstruction(unittest.TestCase):
554 def test_get_missing_channels(self):
555 pion = Particle(
'pi+:unittest', fei.config.MVAConfiguration(variables=[
'p',
'dr'], target=
'isPrimarySignal'))
556 pion.addChannel([
'pi+:FSP'])
557 D0 = Particle(
'D0:unittest', fei.config.MVAConfiguration(variables=[
'M',
'p'], target=
'isSignal'))
558 D0.addChannel([
'K-:unittest',
'pi+:unittest'])
559 D0.addChannel([
'pi-:unittest',
'pi+:unittest'])
560 config = fei.config.FeiConfiguration(monitor=
False, prefix=
"UNITTEST")
561 x = fei.core.PostReconstruction([pion, D0], config)
563 self.assertEqual(x.get_missing_channels(), [
'pi+:unittest ==> pi+:FSP',
'D0:unittest ==> K-:unittest pi+:unittest',
564 'D0:unittest ==> pi-:unittest pi+:unittest'])
565 self.assertEqual(x.available(),
False)
568 <?xml version="1.0" encoding="utf-8"?>
569 <method>Trivial</method>
570 <weightfile>{channel}.xml</weightfile>
571 <treename>tree</treename>
572 <target_variable>isSignal</target_variable>
573 <weight_variable>__weight__</weight_variable>
574 <signal_class>1</signal_class>
575 <max_events>0</max_events>
576 <number_feature_variables>1</number_feature_variables>
577 <variable0>M</variable0>
578 <number_spectator_variables>0</number_spectator_variables>
579 <number_data_files>1</number_data_files>
580 <datafile0>train.root</datafile0>
581 <Trivial_version>1</Trivial_version>
582 <Trivial_output>0</Trivial_output>
583 <signal_fraction>0.066082567</signal_fraction>
586 channel =
'D0:unittest ==> K-:unittest pi+:unittest'
587 with open(channel +
".xml",
"w")
as f:
588 f.write(content.format(channel=channel))
589 basf2_mva.upload(channel +
".xml",
'UNITTEST_' + channel)
591 self.assertEqual(x.get_missing_channels(), [
'pi+:unittest ==> pi+:FSP',
592 'D0:unittest ==> pi-:unittest pi+:unittest'])
593 self.assertEqual(x.available(),
False)
595 channel =
'D0:unittest ==> pi-:unittest pi+:unittest'
596 with open(channel +
".xml",
"w")
as f:
597 f.write(content.format(channel=channel))
598 basf2_mva.upload(channel +
".xml",
'UNITTEST_' + channel)
600 self.assertEqual(x.get_missing_channels(), [
'pi+:unittest ==> pi+:FSP'])
601 self.assertEqual(x.available(),
False)
603 channel =
'pi+:unittest ==> pi+:FSP'
604 with open(channel +
".xml",
"w")
as f:
605 f.write(content.format(channel=channel))
606 basf2_mva.upload(channel +
".xml",
'UNITTEST_' + channel)
608 self.assertEqual(x.get_missing_channels(), [])
609 self.assertEqual(x.available(),
True)
612 if os.path.isfile(
'pi+:unittest ==> pi+:FSP.xml'):
613 os.remove(
'pi+:unittest ==> pi+:FSP.xml')
614 if os.path.isfile(
'D0:unittest ==> pi-:unittest pi+:unittest.xml'):
615 os.remove(
'D0:unittest ==> pi-:unittest pi+:unittest.xml')
616 if os.path.isfile(
'D0:unittest ==> K-:unittest pi+:unittest.xml'):
617 os.remove(
'D0:unittest ==> K-:unittest pi+:unittest.xml')
619 def test_without_monitoring(self):
620 particles = get_small_unittest_channels()
621 config = fei.config.FeiConfiguration(monitor=
False, prefix=
'UNITTEST')
622 x = fei.core.PostReconstruction(particles, config)
624 path = basf2.create_path()
626 path.add_module(
'MVAExpert', identifier=
'UNITTEST_pi+:generic ==> pi+:FSP', extraInfoName=
'SignalProbability',
627 listNames=[
'pi+:generic_0'])
628 path.add_module(
'TagUniqueSignal', particleList=
'pi+:generic_0', target=
'isPrimarySignal',
629 extraInfoName=
'uniqueSignal')
630 path.add_module(
'ParticleListManipulator', outputListName=
'pi+:generic', inputListNames=[
'pi+:generic_0'],
631 variable=
'particleSource', writeOut=
True)
632 path.add_module(
'ParticleSelector', decayString=
'pi+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
633 path.add_module(
'BestCandidateSelection', particleList=
'pi+:generic', variable=
'extraInfo(SignalProbability)',
634 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
636 path.add_module(
'MVAExpert', identifier=
'UNITTEST_K+:generic ==> K+:FSP', extraInfoName=
'SignalProbability',
637 listNames=[
'K+:generic_0'])
638 path.add_module(
'TagUniqueSignal', particleList=
'K+:generic_0', target=
'isPrimarySignal',
639 extraInfoName=
'uniqueSignal')
640 path.add_module(
'ParticleListManipulator', outputListName=
'K+:generic', inputListNames=[
'K+:generic_0'],
641 variable=
'particleSource', writeOut=
True)
642 path.add_module(
'ParticleSelector', decayString=
'K+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
643 path.add_module(
'BestCandidateSelection', particleList=
'K+:generic', variable=
'extraInfo(SignalProbability)',
644 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
646 path.add_module(
'MVAExpert', identifier=
'UNITTEST_D0:generic ==> K-:generic pi+:generic',
647 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_0'])
648 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_0', target=
'isSignal',
649 extraInfoName=
'uniqueSignal')
651 path.add_module(
'MVAExpert', identifier=
'UNITTEST_D0:generic ==> pi-:generic pi+:generic',
652 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_1'])
653 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_1', target=
'isSignal',
654 extraInfoName=
'uniqueSignal')
656 path.add_module(
'ParticleListManipulator', outputListName=
'D0:generic',
657 inputListNames=[
'D0:generic_0',
'D0:generic_1'], variable=
'particleSource',
659 path.add_module(
'ParticleSelector', decayString=
'D0:generic', cut=
'0.001 < extraInfo(SignalProbability)')
660 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic', variable=
'extraInfo(SignalProbability)',
661 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
663 print_path(path, x.reconstruct())
664 self.assertEqual(x.reconstruct(), path)
666 def test_without_monitoring_training_mode(self):
667 particles = get_small_unittest_channels()
668 config = fei.config.FeiConfiguration(monitor=
False, prefix=
'UNITTEST', training=
True)
669 x = fei.core.PostReconstruction(particles, config)
671 path = basf2.create_path()
673 path.add_module(
'MVAExpert', identifier=
'pi+:generic ==> pi+:FSP.xml', extraInfoName=
'SignalProbability',
674 listNames=[
'pi+:generic_0'])
675 path.add_module(
'TagUniqueSignal', particleList=
'pi+:generic_0', target=
'isPrimarySignal',
676 extraInfoName=
'uniqueSignal')
677 path.add_module(
'ParticleListManipulator', outputListName=
'pi+:generic', inputListNames=[
'pi+:generic_0'],
678 variable=
'particleSource', writeOut=
True)
679 path.add_module(
'ParticleSelector', decayString=
'pi+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
680 path.add_module(
'BestCandidateSelection', particleList=
'pi+:generic', variable=
'extraInfo(SignalProbability)',
681 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
683 path.add_module(
'MVAExpert', identifier=
'K+:generic ==> K+:FSP.xml', extraInfoName=
'SignalProbability',
684 listNames=[
'K+:generic_0'])
685 path.add_module(
'TagUniqueSignal', particleList=
'K+:generic_0', target=
'isPrimarySignal',
686 extraInfoName=
'uniqueSignal')
687 path.add_module(
'ParticleListManipulator', outputListName=
'K+:generic', inputListNames=[
'K+:generic_0'],
688 variable=
'particleSource', writeOut=
True)
689 path.add_module(
'ParticleSelector', decayString=
'K+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
690 path.add_module(
'BestCandidateSelection', particleList=
'K+:generic', variable=
'extraInfo(SignalProbability)',
691 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
693 path.add_module(
'MVAExpert', identifier=
'D0:generic ==> K-:generic pi+:generic.xml',
694 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_0'])
695 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_0', target=
'isSignal',
696 extraInfoName=
'uniqueSignal')
698 path.add_module(
'MVAExpert', identifier=
'D0:generic ==> pi-:generic pi+:generic.xml',
699 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_1'])
700 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_1', target=
'isSignal',
701 extraInfoName=
'uniqueSignal')
703 path.add_module(
'ParticleListManipulator', outputListName=
'D0:generic',
704 inputListNames=[
'D0:generic_0',
'D0:generic_1'], variable=
'particleSource',
706 path.add_module(
'ParticleSelector', decayString=
'D0:generic', cut=
'0.001 < extraInfo(SignalProbability)')
707 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic', variable=
'extraInfo(SignalProbability)',
708 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
710 print_path(path, x.reconstruct())
711 self.assertEqual(x.reconstruct(), path)
713 def test_with_monitoring(self):
714 particles = get_small_unittest_channels()
715 config = fei.config.FeiConfiguration(monitor=
True, prefix=
'UNITTEST')
716 x = fei.core.PostReconstruction(particles, config)
718 path = basf2.create_path()
720 path.add_module(
'MVAExpert', identifier=
'UNITTEST_pi+:generic ==> pi+:FSP', extraInfoName=
'SignalProbability',
721 listNames=[
'pi+:generic_0'])
722 path.add_module(
'TagUniqueSignal', particleList=
'pi+:generic_0', target=
'isPrimarySignal',
723 extraInfoName=
'uniqueSignal')
725 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic_0',
726 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
727 'extraInfo(SignalProbability)',
728 'isPrimarySignal',
'extraInfo(decayModeID)']),
729 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(SignalProbability)',
'isPrimarySignal'),
730 (
'extraInfo(SignalProbability)',
'mcErrors'),
731 (
'extraInfo(SignalProbability)',
'mcParticleStatus'),
732 (
'extraInfo(decayModeID)',
'isPrimarySignal'),
733 (
'extraInfo(decayModeID)',
'mcErrors'),
734 (
'extraInfo(decayModeID)',
'extraInfo(uniqueSignal)'),
735 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
736 fileName=
'Monitor_PostReconstruction_AfterMVA.root', directory=
'pi+:generic ==> pi+:FSP')
737 path.add_module(
'ParticleListManipulator', outputListName=
'pi+:generic', inputListNames=[
'pi+:generic_0'],
738 variable=
'particleSource', writeOut=
True)
739 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic',
740 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
741 'extraInfo(SignalProbability)',
742 'isPrimarySignal',
'extraInfo(decayModeID)']),
743 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
744 (
'extraInfo(decayModeID)',
'mcErrors'),
745 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
746 fileName=
'Monitor_PostReconstruction_BeforePostCut.root', directory=
'pi+:generic')
747 path.add_module(
'ParticleSelector', decayString=
'pi+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
748 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic',
749 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
750 'extraInfo(SignalProbability)',
751 'isPrimarySignal',
'extraInfo(decayModeID)']),
752 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
753 (
'extraInfo(decayModeID)',
'mcErrors'),
754 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
755 fileName=
'Monitor_PostReconstruction_BeforeRanking.root', directory=
'pi+:generic')
756 path.add_module(
'BestCandidateSelection', particleList=
'pi+:generic', variable=
'extraInfo(SignalProbability)',
757 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
758 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic',
759 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
760 'extraInfo(SignalProbability)',
'isPrimarySignal',
761 'extraInfo(decayModeID)',
'extraInfo(postCut_rank)']),
762 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
763 (
'extraInfo(decayModeID)',
'mcErrors'),
764 (
'extraInfo(decayModeID)',
'mcParticleStatus'),
765 (
'extraInfo(decayModeID)',
'extraInfo(postCut_rank)'),
766 (
'isPrimarySignal',
'extraInfo(postCut_rank)'),
767 (
'mcErrors',
'extraInfo(postCut_rank)'),
768 (
'mcParticleStatus',
'extraInfo(postCut_rank)')]),
769 fileName=
'Monitor_PostReconstruction_AfterRanking.root', directory=
'pi+:generic')
770 path.add_module(
'VariablesToNtuple', fileName=
'Monitor_Final.root', treeName=
'pi+:generic variables',
771 variables=[
'extraInfo(SignalProbability)',
'mcErrors',
'mcParticleStatus',
'isPrimarySignal',
772 'extraInfo(uniqueSignal)',
'extraInfo(decayModeID)'],
773 particleList=
'pi+:generic')
775 path.add_module(
'MVAExpert', identifier=
'UNITTEST_K+:generic ==> K+:FSP', extraInfoName=
'SignalProbability',
776 listNames=[
'K+:generic_0'])
777 path.add_module(
'TagUniqueSignal', particleList=
'K+:generic_0', target=
'isPrimarySignal',
778 extraInfoName=
'uniqueSignal')
779 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic_0',
780 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
781 'extraInfo(SignalProbability)',
782 'isPrimarySignal',
'extraInfo(decayModeID)']),
783 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(SignalProbability)',
'isPrimarySignal'),
784 (
'extraInfo(SignalProbability)',
'mcErrors'),
785 (
'extraInfo(SignalProbability)',
'mcParticleStatus'),
786 (
'extraInfo(decayModeID)',
'isPrimarySignal'),
787 (
'extraInfo(decayModeID)',
'mcErrors'),
788 (
'extraInfo(decayModeID)',
'extraInfo(uniqueSignal)'),
789 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
790 fileName=
'Monitor_PostReconstruction_AfterMVA.root', directory=
'K+:generic ==> K+:FSP')
791 path.add_module(
'ParticleListManipulator', outputListName=
'K+:generic', inputListNames=[
'K+:generic_0'],
792 variable=
'particleSource', writeOut=
True)
793 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic',
794 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
795 'extraInfo(SignalProbability)',
796 'isPrimarySignal',
'extraInfo(decayModeID)']),
797 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
798 (
'extraInfo(decayModeID)',
'mcErrors'),
799 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
800 fileName=
'Monitor_PostReconstruction_BeforePostCut.root', directory=
'K+:generic')
801 path.add_module(
'ParticleSelector', decayString=
'K+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
802 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic',
803 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
804 'extraInfo(SignalProbability)',
805 'isPrimarySignal',
'extraInfo(decayModeID)']),
806 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
807 (
'extraInfo(decayModeID)',
'mcErrors'),
808 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
809 fileName=
'Monitor_PostReconstruction_BeforeRanking.root', directory=
'K+:generic')
810 path.add_module(
'BestCandidateSelection', particleList=
'K+:generic', variable=
'extraInfo(SignalProbability)',
811 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
812 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic',
813 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
814 'extraInfo(SignalProbability)',
'isPrimarySignal',
815 'extraInfo(decayModeID)',
'extraInfo(postCut_rank)']),
816 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
817 (
'extraInfo(decayModeID)',
'mcErrors'),
818 (
'extraInfo(decayModeID)',
'mcParticleStatus'),
819 (
'extraInfo(decayModeID)',
'extraInfo(postCut_rank)'),
820 (
'isPrimarySignal',
'extraInfo(postCut_rank)'),
821 (
'mcErrors',
'extraInfo(postCut_rank)'),
822 (
'mcParticleStatus',
'extraInfo(postCut_rank)')]),
823 fileName=
'Monitor_PostReconstruction_AfterRanking.root', directory=
'K+:generic')
824 path.add_module(
'VariablesToNtuple', fileName=
'Monitor_Final.root', treeName=
'K+:generic variables',
825 variables=[
'extraInfo(SignalProbability)',
'mcErrors',
'mcParticleStatus',
'isPrimarySignal',
826 'extraInfo(uniqueSignal)',
'extraInfo(decayModeID)'],
827 particleList=
'K+:generic')
829 path.add_module(
'MVAExpert', identifier=
'UNITTEST_D0:generic ==> K-:generic pi+:generic',
830 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_0'])
831 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_0', target=
'isSignal',
832 extraInfoName=
'uniqueSignal')
833 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_0',
834 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
835 'extraInfo(SignalProbability)',
836 'isSignal',
'extraInfo(decayModeID)']),
837 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(SignalProbability)',
'isSignal'),
838 (
'extraInfo(SignalProbability)',
'mcErrors'),
839 (
'extraInfo(SignalProbability)',
'mcParticleStatus'),
840 (
'extraInfo(decayModeID)',
'isSignal'),
841 (
'extraInfo(decayModeID)',
'mcErrors'),
842 (
'extraInfo(decayModeID)',
'extraInfo(uniqueSignal)'),
843 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
844 fileName=
'Monitor_PostReconstruction_AfterMVA.root', directory=
'D0:generic ==> K-:generic pi+:generic')
846 path.add_module(
'MVAExpert', identifier=
'UNITTEST_D0:generic ==> pi-:generic pi+:generic',
847 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_1'])
848 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_1', target=
'isSignal',
849 extraInfoName=
'uniqueSignal')
850 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_1',
851 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
852 'extraInfo(SignalProbability)',
853 'isSignal',
'extraInfo(decayModeID)']),
854 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(SignalProbability)',
'isSignal'),
855 (
'extraInfo(SignalProbability)',
'mcErrors'),
856 (
'extraInfo(SignalProbability)',
'mcParticleStatus'),
857 (
'extraInfo(decayModeID)',
'isSignal'),
858 (
'extraInfo(decayModeID)',
'mcErrors'),
859 (
'extraInfo(decayModeID)',
'extraInfo(uniqueSignal)'),
860 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
861 fileName=
'Monitor_PostReconstruction_AfterMVA.root', directory=
'D0:generic ==> pi-:generic pi+:generic')
863 path.add_module(
'ParticleListManipulator', outputListName=
'D0:generic',
864 inputListNames=[
'D0:generic_0',
'D0:generic_1'], variable=
'particleSource',
866 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic',
867 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
868 'extraInfo(SignalProbability)',
869 'isSignal',
'extraInfo(decayModeID)']),
870 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isSignal'),
871 (
'extraInfo(decayModeID)',
'mcErrors'),
872 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
873 fileName=
'Monitor_PostReconstruction_BeforePostCut.root', directory=
'D0:generic')
874 path.add_module(
'ParticleSelector', decayString=
'D0:generic', cut=
'0.001 < extraInfo(SignalProbability)')
875 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic',
876 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
877 'extraInfo(SignalProbability)',
878 'isSignal',
'extraInfo(decayModeID)']),
879 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isSignal'),
880 (
'extraInfo(decayModeID)',
'mcErrors'),
881 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
882 fileName=
'Monitor_PostReconstruction_BeforeRanking.root', directory=
'D0:generic')
883 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic', variable=
'extraInfo(SignalProbability)',
884 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
885 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic',
886 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
887 'extraInfo(SignalProbability)',
'isSignal',
888 'extraInfo(decayModeID)',
'extraInfo(postCut_rank)']),
889 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isSignal'),
890 (
'extraInfo(decayModeID)',
'mcErrors'),
891 (
'extraInfo(decayModeID)',
'mcParticleStatus'),
892 (
'extraInfo(decayModeID)',
'extraInfo(postCut_rank)'),
893 (
'isSignal',
'extraInfo(postCut_rank)'),
894 (
'mcErrors',
'extraInfo(postCut_rank)'),
895 (
'mcParticleStatus',
'extraInfo(postCut_rank)')]),
896 fileName=
'Monitor_PostReconstruction_AfterRanking.root', directory=
'D0:generic')
897 path.add_module(
'VariablesToNtuple', fileName=
'Monitor_Final.root', treeName=
'D0:generic variables',
898 variables=[
'extraInfo(SignalProbability)',
'mcErrors',
'mcParticleStatus',
'isSignal',
899 'extraInfo(uniqueSignal)',
'extraInfo(decayModeID)'],
900 particleList=
'D0:generic')
902 print_path(path, x.reconstruct())
903 self.assertEqual(x.reconstruct(), path)
906 class TestTeacher(unittest.TestCase):
908 fei.core.Teacher.MaximumNumberOfMVASamples = int(1e7)
909 fei.core.Teacher.MinimumNumberOfMVASamples = int(10)
911 f = ROOT.TFile(
'training_input.root',
'RECREATE')
913 tree = ROOT.TTree(
'pi+:generic ==> pi+:FSP variables',
'pi+:generic ==> pi+:FSP variables')
914 isSignal = np.zeros(1, dtype=float)
915 p = np.zeros(1, dtype=float)
916 pt = np.zeros(1, dtype=float)
917 tree.Branch(
'isPrimarySignal', isSignal,
'isPrimarySignal/D')
918 tree.Branch(
'p', p,
'p/D')
919 tree.Branch(
'dr', pt,
'dr/D')
920 for i
in range(1000):
925 tree.Write(
"", ROOT.TObject.kOverwrite)
929 tree = ROOT.TTree(
'D0:generic ==> K-:generic pi+:generic variables',
'D0:generic ==> K-:generic pi+:generic variables')
930 isSignal = np.zeros(1, dtype=float)
931 p = np.zeros(1, dtype=float)
932 pt = np.zeros(1, dtype=float)
933 tree.Branch(
'isSignal', isSignal,
'isSignal/D')
934 tree.Branch(
'M', p,
'M/D')
935 tree.Branch(
'p', pt,
'p/D')
942 tree.Write(
"", ROOT.TObject.kOverwrite)
944 tree = ROOT.TTree(
'D0:generic ==> pi-:generic pi+:generic variables',
'D0:generic ==> pi-:generic pi+:generic variables')
945 isSignal = np.zeros(1, dtype=float)
946 p = np.zeros(1, dtype=float)
947 pt = np.zeros(1, dtype=float)
948 tree.Branch(
'isSignal', isSignal,
'isSignal/D')
949 tree.Branch(
'M', p,
'M/D')
950 tree.Branch(
'p', pt,
'p/D')
951 for i
in range(1000):
956 tree.Write(
"", ROOT.TObject.kOverwrite)
959 if os.path.isfile(
'UNITTEST_TEACHER.xml'):
960 os.remove(
'UNITTEST_TEACHER.xml')
961 if os.path.isfile(
'UNITTEST_pi+:generic ==> pi+:FSP.xml'):
962 os.remove(
'UNITTEST_pi+:generic ==> pi+:FSP.xml')
963 if os.path.isfile(
'UNITTEST_K+:generic ==> K+:FSP.xml'):
964 os.remove(
'UNITTEST_K+:generic ==> K+:FSP.xml')
965 if os.path.isfile(
'UNITTEST_D0:generic ==> K-:generic pi+:generic.xml'):
966 os.remove(
'UNITTEST_D0:generic ==> K-:generic pi+:generic.xml')
967 if os.path.isfile(
'UNITTEST_D0:generic ==> pi-:generic pi+:generic.xml'):
968 os.remove(
'UNITTEST_D0:generic ==> pi-:generic pi+:generic.xml')
969 if os.path.isfile(
'training_input.root'):
970 os.remove(
'training_input.root')
972 def test_create_fake_weightfile(self):
973 self.assertEqual(os.path.isfile(
'UNITTEST_pi+:generic ==> pi+:FSP.xml'),
False)
974 self.assertEqual(basf2_mva.available(
'UNITTEST_pi+:generic ==> pi+:FSP.xml'),
False)
975 fei.core.Teacher.create_fake_weightfile(
'UNITTEST_pi+:generic ==> pi+:FSP')
976 self.assertEqual(os.path.isfile(
'UNITTEST_pi+:generic ==> pi+:FSP.xml'),
True)
977 self.assertEqual(basf2_mva.available(
'UNITTEST_pi+:generic ==> pi+:FSP.xml'),
True)
979 def test_upload(self):
980 particles = get_small_unittest_channels()
981 config = fei.config.FeiConfiguration(monitor=
False, prefix=
'UNITTEST', externTeacher=
'basf2_mva_teacher')
982 x = fei.core.Teacher(particles, config)
983 fei.core.Teacher.create_fake_weightfile(
'TEACHER')
984 self.assertEqual(basf2_mva.available(
'UNITTEST_TEACHER'),
False)
985 r = x.upload(
'TEACHER')
986 self.assertEqual(basf2_mva.available(
'UNITTEST_TEACHER'),
True)
987 self.assertEqual(r, (
'TEACHER.xml',
'UNITTEST_TEACHER'))
989 def test_without_monitoring(self):
990 particles = get_small_unittest_channels()
991 config = fei.config.FeiConfiguration(monitor=
False, prefix=
'UNITTEST', externTeacher=
'basf2_mva_teacher')
992 x = fei.core.Teacher(particles, config)
994 self.assertEqual(basf2_mva.available(
'UNITTEST_pi+:generic ==> pi+:FSP'),
False)
995 self.assertEqual(basf2_mva.available(
'UNITTEST_K+:generic ==> K+:FSP'),
False)
996 self.assertEqual(basf2_mva.available(
'UNITTEST_D0:generic ==> K-:generic pi+:generic'),
False)
997 self.assertEqual(basf2_mva.available(
'UNITTEST_D0:generic ==> pi-:generic pi+:generic'),
False)
1001 self.assertEqual(basf2_mva.available(
'UNITTEST_pi+:generic ==> pi+:FSP'),
True)
1002 self.assertEqual(basf2_mva.available(
'UNITTEST_K+:generic ==> K+:FSP'),
False)
1003 self.assertEqual(basf2_mva.available(
'UNITTEST_D0:generic ==> K-:generic pi+:generic'),
True)
1004 self.assertEqual(basf2_mva.available(
'UNITTEST_D0:generic ==> pi-:generic pi+:generic'),
True)
1008 class TestConvertLegacyTraining(unittest.TestCase):
1013 class TestGetPath(unittest.TestCase):
1016 particles = fei.get_unittest_channels()
1018 f = ROOT.TFile(
'mcParticlesCount.root',
'RECREATE')
1021 for pdgnumber
in set([abs(
pdg.from_name(particle.name))
for particle
in particles]):
1022 hist = ROOT.TH1F(f
"NumberOfMCParticlesInEvent__bo{pdgnumber}__bc",
1023 f
"NumberOfMCParticlesInEvent__bo{pdgnumber}__bc", 11, -0.5, 10.5)
1026 f.Write(f
"NumberOfMCParticlesInEvent__bo{pdgnumber}__bc")
1029 if os.path.isfile(
'mcParticlesCount.root'):
1030 os.remove(
'mcParticlesCount.root')
1031 if os.path.isfile(
'Summary.pickle'):
1032 os.remove(
'Summary.pickle')
1034 def test_get_path_default_cache(self):
1035 particles = fei.get_unittest_channels()
1036 config = fei.config.FeiConfiguration(training=
True)
1037 x = fei.core.Teacher(particles, config)
1041 feistate = fei.core.get_path(particles, config)
1042 self.assertEqual(feistate.stage, 0)
1046 config = fei.config.FeiConfiguration(training=
True)
1047 feistate = fei.core.get_path(particles, config)
1048 self.assertEqual(feistate.stage, 1)
1052 config = fei.config.FeiConfiguration(training=
True)
1053 feistate = fei.core.get_path(particles, config)
1054 self.assertEqual(feistate.stage, 1)
1057 fei.core.Teacher.create_fake_weightfile(
'pi+:generic ==> pi+:FSP')
1058 fei.core.Teacher.create_fake_weightfile(
'K+:generic ==> K+:FSP')
1059 fei.core.Teacher.create_fake_weightfile(
'mu+:generic ==> mu+:FSP')
1060 fei.core.Teacher.create_fake_weightfile(
'gamma:generic ==> gamma:FSP')
1061 fei.core.Teacher.create_fake_weightfile(
'gamma:generic ==> gamma:V0')
1065 config = fei.config.FeiConfiguration(training=
True)
1066 feistate = fei.core.get_path(particles, config)
1067 self.assertEqual(feistate.stage, 2)
1071 config = fei.config.FeiConfiguration(training=
True)
1072 feistate = fei.core.get_path(particles, config)
1073 self.assertEqual(feistate.stage, 2)
1076 fei.core.Teacher.create_fake_weightfile(
'pi0:generic ==> gamma:generic gamma:generic')
1080 config = fei.config.FeiConfiguration(training=
True)
1081 feistate = fei.core.get_path(particles, config)
1082 self.assertEqual(feistate.stage, 4)
1085 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> K-:generic pi+:generic')
1086 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> K-:generic pi+:generic pi0:generic')
1087 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> pi-:generic pi+:generic')
1088 fei.core.Teacher.create_fake_weightfile(
'D0:semileptonic ==> K-:generic mu+:generic')
1089 fei.core.Teacher.create_fake_weightfile(
'D0:semileptonic ==> K-:generic pi0:generic mu+:generic')
1093 config = fei.config.FeiConfiguration(training=
True)
1094 feistate = fei.core.get_path(particles, config)
1095 self.assertEqual(feistate.stage, 7)
1099 config = fei.config.FeiConfiguration(cache=0, training=
True)
1100 feistate = fei.core.get_path(particles, config)
1101 self.assertEqual(feistate.stage, 7)
1105 os.remove(
'pi+:generic ==> pi+:FSP.xml')
1106 os.remove(
'K+:generic ==> K+:FSP.xml')
1107 os.remove(
'mu+:generic ==> mu+:FSP.xml')
1108 os.remove(
'gamma:generic ==> gamma:FSP.xml')
1109 os.remove(
'gamma:generic ==> gamma:V0.xml')
1110 os.remove(
'pi0:generic ==> gamma:generic gamma:generic.xml')
1111 os.remove(
'D0:generic ==> K-:generic pi+:generic.xml')
1112 os.remove(
'D0:generic ==> K-:generic pi+:generic pi0:generic.xml')
1113 os.remove(
'D0:generic ==> pi-:generic pi+:generic.xml')
1114 os.remove(
'D0:semileptonic ==> K-:generic mu+:generic.xml')
1115 os.remove(
'D0:semileptonic ==> K-:generic pi0:generic mu+:generic.xml')
1117 config = fei.config.FeiConfiguration(cache=0, training=
False)
1118 feistate = fei.core.get_path(particles, config)
1119 self.assertEqual(feistate.stage, 7)
1121 def test_get_path(self):
1122 particles = fei.get_unittest_channels()
1123 config = fei.config.FeiConfiguration(cache=-1, training=
True)
1124 x = fei.core.Teacher(particles, config)
1128 feistate = fei.core.get_path(particles, config)
1129 self.assertEqual(feistate.stage, 0)
1133 config = fei.config.FeiConfiguration(cache=0, training=
True)
1134 feistate = fei.core.get_path(particles, config)
1135 self.assertEqual(feistate.stage, 1)
1139 config = fei.config.FeiConfiguration(cache=1, training=
True)
1140 feistate = fei.core.get_path(particles, config)
1141 self.assertEqual(feistate.stage, 1)
1144 fei.core.Teacher.create_fake_weightfile(
'pi+:generic ==> pi+:FSP')
1145 fei.core.Teacher.create_fake_weightfile(
'K+:generic ==> K+:FSP')
1146 fei.core.Teacher.create_fake_weightfile(
'mu+:generic ==> mu+:FSP')
1147 fei.core.Teacher.create_fake_weightfile(
'gamma:generic ==> gamma:FSP')
1148 fei.core.Teacher.create_fake_weightfile(
'gamma:generic ==> gamma:V0')
1152 config = fei.config.FeiConfiguration(cache=1, training=
True)
1153 feistate = fei.core.get_path(particles, config)
1154 self.assertEqual(feistate.stage, 2)
1158 config = fei.config.FeiConfiguration(cache=2, training=
True)
1159 feistate = fei.core.get_path(particles, config)
1160 self.assertEqual(feistate.stage, 2)
1165 config = fei.config.FeiConfiguration(cache=4, training=
True)
1166 feistate = fei.core.get_path(particles, config)
1167 self.assertEqual(feistate.stage, 2)
1170 fei.core.Teacher.create_fake_weightfile(
'pi0:generic ==> gamma:generic gamma:generic')
1174 config = fei.config.FeiConfiguration(cache=2, training=
True)
1175 feistate = fei.core.get_path(particles, config)
1176 self.assertEqual(feistate.stage, 4)
1179 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> K-:generic pi+:generic')
1180 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> K-:generic pi+:generic pi0:generic')
1181 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> pi-:generic pi+:generic')
1182 fei.core.Teacher.create_fake_weightfile(
'D0:semileptonic ==> K-:generic mu+:generic')
1183 fei.core.Teacher.create_fake_weightfile(
'D0:semileptonic ==> K-:generic pi0:generic mu+:generic')
1187 config = fei.config.FeiConfiguration(cache=4, training=
True)
1188 feistate = fei.core.get_path(particles, config)
1189 self.assertEqual(feistate.stage, 7)
1193 config = fei.config.FeiConfiguration(cache=0, training=
True)
1194 feistate = fei.core.get_path(particles, config)
1195 self.assertEqual(feistate.stage, 7)
1199 os.remove(
'pi+:generic ==> pi+:FSP.xml')
1200 os.remove(
'K+:generic ==> K+:FSP.xml')
1201 os.remove(
'mu+:generic ==> mu+:FSP.xml')
1202 os.remove(
'gamma:generic ==> gamma:FSP.xml')
1203 os.remove(
'gamma:generic ==> gamma:V0.xml')
1204 os.remove(
'pi0:generic ==> gamma:generic gamma:generic.xml')
1205 os.remove(
'D0:generic ==> K-:generic pi+:generic.xml')
1206 os.remove(
'D0:generic ==> K-:generic pi+:generic pi0:generic.xml')
1207 os.remove(
'D0:generic ==> pi-:generic pi+:generic.xml')
1208 os.remove(
'D0:semileptonic ==> K-:generic mu+:generic.xml')
1209 os.remove(
'D0:semileptonic ==> K-:generic pi0:generic mu+:generic.xml')
1211 config = fei.config.FeiConfiguration(cache=0, training=
False)
1212 feistate = fei.core.get_path(particles, config)
1213 self.assertEqual(feistate.stage, 7)
1216 if __name__ ==
'__main__':
1218 basf2.conditions.testing_payloads = [
'localdb/database.txt']
def clean_working_directory()