Belle II Software development
chargeConjugation.py
1#!/usr/bin/env python3
2
3
10import unittest
11import tempfile
12import basf2
13import b2test_utils
14import modularAnalysis as ma
15from variables import variables
16from ROOT import TFile
17
18
19class TestParticleCombiner(unittest.TestCase):
20 """The unit test case for the ParticleCombinerModule"""
21
23 """Reconstruct decays with and without charge conjugation"""
24
25 testFile = tempfile.NamedTemporaryFile()
26 # make logging more reproducible by replacing some strings.
27 # Also make sure the testfile name is replaced if necessary
28 b2test_utils.configure_logging_for_tests({testFile.name: "${testfile}"})
29
30 main = basf2.create_path()
31 ma.inputMdst(b2test_utils.require_file('analysis/tests/mdst.root'), path=main)
32
33 ma.fillParticleList('pi+:pionlike', 'pionID > 0.5', path=main)
34 ma.fillParticleList('K+:kaonlike', 'kaonID > 0.5', path=main)
35
36 # combine all kaons with all pions for both charge configurations (K- pi+ and K+ pi-)
37 ma.reconstructDecay('D0:all -> K-:kaonlike pi+:pionlike', '', chargeConjugation=True, path=main)
38
39 # only reconstruct D0
40 ma.reconstructDecay('D0:particle -> K-:kaonlike pi+:pionlike', '', chargeConjugation=False, path=main)
41
42 # only reconstruct anti-D0
43 ma.reconstructDecay('anti-D0:anti-particle -> K+:kaonlike pi-:pionlike', '', chargeConjugation=False, path=main)
44
45 # use particle's charge to separate D0 flavors,
46 ma.reconstructDecay(
47 'D0:positiveFlavour -> K-:kaonlike pi+:pionlike',
48 'daughter(0, charge) < 0',
49 chargeConjugation=True,
50 path=main)
51 ma.reconstructDecay(
52 'D0:negativeFlavour -> K-:kaonlike pi+:pionlike',
53 'daughter(0, charge) > 0',
54 chargeConjugation=True,
55 path=main)
56
57 variables.addAlias('nDs', 'nParticlesInList(D0:all)')
58 variables.addAlias('nD0s', 'nParticlesInList(D0:particle)')
59 variables.addAlias('nAntiD0s', 'nParticlesInList(anti-D0:anti-particle)')
60 variables.addAlias('nPositiveFlavourDs', 'nParticlesInList(D0:positiveFlavour)')
61 variables.addAlias('nNegativeFlavourDs', 'nParticlesInList(D0:negativeFlavour)')
62
63 allvariables = ['nDs', 'nD0s', 'nAntiD0s', 'nPositiveFlavourDs', 'nNegativeFlavourDs']
64 ma.variablesToNtuple('', variables=allvariables, filename=testFile.name, path=main)
65
66 basf2.process(main)
67
68 ntuplefile = TFile(testFile.name)
69 ntuple = ntuplefile.Get('variables')
70
71 self.assertFalse(ntuple.GetEntries() == 0, "Ntuple is empty.")
72
73 # sum of D0s and D0bars should be equal to all D0s
74 if (ntuple.GetEntries() != ntuple.GetEntries("nDs == nD0s + nAntiD0s")):
75 ntuple.Scan("nDs:nD0s:nAntiD0s:nPositiveFlavourDs:nNegativeFlavourDs", "", "", 10)
76 self.assertFalse(True, "Number of D0s does not agree with sum of both flavors!")
77
78 # D0s should be combinations of K- and pi+ only
79 if (ntuple.GetEntries() != ntuple.GetEntries("nD0s == nPositiveFlavourDs")):
80 ntuple.Scan("nDs:nD0s:nAntiD0s:nPositiveFlavourDs:nNegativeFlavourDs", "", "", 10)
81 self.assertFalse(True, "Number of D0s does not agree with number of K- pi+ combinations!")
82
83 # D0bars should be combinations of K+ and pi- only
84 if (ntuple.GetEntries() != ntuple.GetEntries("nAntiD0s == nNegativeFlavourDs")):
85 ntuple.Scan("nDs:nD0s:nAntiD0s:nPositiveFlavourDs:nNegativeFlavourDs", "", "", 10)
86 self.assertFalse(True, "Number of anti D0s does not agree with number of K+ pi- combinations!")
87
88 print("Test passed, cleaning up.")
89
90
91if __name__ == '__main__':
92 unittest.main()
def require_file(filename, data_type="", py_case=None)
Definition: __init__.py:54
def configure_logging_for_tests(user_replacements=None)
Definition: __init__.py:106