Belle II Software development
test_variables_utils.py
1#!/usr/bin/env python3
2
3
10
11import unittest
12from variables.utils import create_aliases_for_selected
13from variables import variables as vm
14
15
16class TestVariableUtilities(unittest.TestCase):
17 """Test case for the variables.utils functions"""
18
19
20 _list_of_variables = ['M', 'p']
21
22 def _expand_expected(self, expected):
23 """Expand the list of expected aliases by appending _{name} for each variable in the _list_of_variables"""
24 result = []
25 for p in expected:
26 if p:
27 result += [f"{p}_{e}" for e in self._list_of_variables]
28 else:
29 result += self._list_of_variables
30 return result
31
32 def assertAliases(self, decaystring, expected, **argk):
33 """Make sure the aliases created for given decaystring are as expected
34 Also, pass any additional keyword arguments to the create_aliases_for_selected function
35 """
36 expected = self._expand_expected(expected)
37 actual = create_aliases_for_selected(self._list_of_variables, decaystring, **argk)
38 self.assertEqual(expected, actual, f"decaystring: {decaystring}, arguments: {argk}")
39
40
43
45 """Make sure we get an error if the decaystring is not valid"""
46 with self.assertRaises(ValueError):
47 create_aliases_for_selected(["p"], "eeh <- ok")
48
50 """Make sure we get an error if o particle is selected"""
51 with self.assertRaises(ValueError):
52 create_aliases_for_selected(["p"], "B0 -> pi0")
53
55 """Make sure we get an error if the number of supplied prefixes doesn't
56 match the number of selected particles"""
57 with self.assertRaises(ValueError):
58 create_aliases_for_selected(["p"], "^B0 -> ^pi0", prefix="one")
59 with self.assertRaises(ValueError):
60 create_aliases_for_selected(["p"], "B0 -> ^pi0", prefix=["one", "two"])
61
63 """Make sure we got an error if the supplied provided prefixes are not unique"""
64 with self.assertRaises(ValueError):
65 create_aliases_for_selected(["p"], "^B0 -> ^pi0", prefix=["mine", "mine"])
66
68 """Check daughter can be selected for an specific named alias"""
69 self.assertAliases('B0 -> [^D0 -> pi+ K-] pi0', ['dzero'], prefix='dzero')
70
72 """Check mother and daughter can be selected for an specific named alias"""
73 self.assertAliases('^B0 -> [^D0 -> pi+ ^K-] pi0', ['MyB', 'MyD', 'MyK'], prefix=['MyB', 'MyD', 'MyK'])
74
76 """Check daughter can be selected w/o an specific named alias"""
77 self.assertAliases('B0 -> [^D0 -> ^pi+ ^K-] pi0', ['d0', 'd0_d0', 'd0_d1'], use_names=False)
78
80 """Check daughter can be selected w/o an specific named alias"""
81 self.assertAliases('^B0 -> pi0 ^pi0', ['', 'd1'], use_names=False)
82 # also make sure we ignore ``use_relative_indices``
83 self.assertAliases('^B0 -> pi0 ^pi0', ['', 'd1'], use_names=False, use_relative_indices=True)
84
86 """Check granddaughter can be selected for an automatic name alias"""
87 self.assertAliases('B0 -> [D0 -> ^pi+ K-] pi0', ['D0_pi'])
88
90 """Check multiple granddaughters can be selected for automatic name aliases"""
91 self.assertAliases(
92 'B0 -> [D0 -> ^pi+ ^pi- ^pi0] ^pi0',
93 [
94 'D0_pi_0',
95 'D0_pi_1',
96 'D0_pi0',
97 'pi0',
98 ])
99
100 def test_autoindex(self):
101 """ check decay-string-of-doom with automatic names """
102 self.assertAliases(
103 "^B0 -> [D0 -> ^pi+ ^pi-] [D+ -> ^pi+ pi0] [D0 -> ^pi+ ^pi-] [K- -> ^pi+ ^pi-] ^pi+ ^pi- pi0",
104 [
105 "",
106 "D0_0_pi_0",
107 "D0_0_pi_1",
108 "D_pi",
109 "D0_2_pi_0",
110 "D0_2_pi_1",
111 "K_pi_0",
112 "K_pi_1",
113 "pi_4",
114 "pi_5",
115 ])
116
118 """ check decay-string-of-doom with automatic names and relative indexing"""
119 self.assertAliases(
120 "^B0 -> [D0 -> ^pi+ ^pi-] [D+ -> ^pi+ pi0] [D0 -> ^pi+ ^pi-] [K- -> ^pi+ ^pi-] ^pi+ ^pi- pi0",
121 [
122 "",
123 "D0_0_pi_0",
124 "D0_0_pi_1",
125 "D_pi",
126 "D0_1_pi_0",
127 "D0_1_pi_1",
128 "K_pi_0",
129 "K_pi_1",
130 "pi_0",
131 "pi_1",
132 ], use_relative_indices=True)
133
135 """ check decay-string-of-doom with automatic names and forced indices"""
136 self.assertAliases(
137 "^B0 -> [D0 -> ^pi+ ^pi-] [D+ -> ^pi+ pi0] [D0 -> ^pi+ ^pi-] [K- -> ^pi+ ^pi-] ^pi+ ^pi- pi0",
138 [
139 "",
140 "D0_0_pi_0",
141 "D0_0_pi_1",
142 "D_1_pi_0",
143 "D0_2_pi_0",
144 "D0_2_pi_1",
145 "K_3_pi_0",
146 "K_3_pi_1",
147 "pi_4",
148 "pi_5",
149 ], always_include_indices=True)
150
152 """ check decay-string-of-doom with automatic names, relative indexing and forced indices"""
153 self.assertAliases(
154 "^B0 -> [D0 -> ^pi+ ^pi-] [D+ -> ^pi+ pi0] [D0 -> ^pi+ ^pi-] [K- -> ^pi+ ^pi-] ^pi+ ^pi- pi0",
155 [
156 "",
157 "D0_0_pi_0",
158 "D0_0_pi_1",
159 "D_0_pi_0",
160 "D0_1_pi_0",
161 "D0_1_pi_1",
162 "K_0_pi_0",
163 "K_0_pi_1",
164 "pi_0",
165 "pi_1",
166 ], use_relative_indices=True, always_include_indices=True)
167
168 def test_indexed(self):
169 """ check decay-string-of-doom w/o automatic names """
170 self.assertAliases(
171 "^B0 -> [D0 -> ^pi+ ^pi-] [D+ -> ^pi+ pi0] [D0 -> ^pi+ ^pi-] [K- -> ^pi+ ^pi-] ^pi+ ^pi- pi0",
172 [
173 "",
174 "d0_d0",
175 "d0_d1",
176 "d1_d0",
177 "d2_d0",
178 "d2_d1",
179 "d3_d0",
180 "d3_d1",
181 "d4",
182 "d5",
183 ], use_names=False)
184
186 """ check decay-string-of-doom w/o automatic names and make sure relative indexing is **not** honored"""
187 self.assertAliases(
188 "^B0 -> [D0 -> ^pi+ ^pi-] [D+ -> ^pi+ pi0] [D0 -> ^pi+ ^pi-] [K- -> ^pi+ ^pi-] ^pi+ ^pi- pi0",
189 [
190 "",
191 "d0_d0",
192 "d0_d1",
193 "d1_d0",
194 "d2_d0",
195 "d2_d1",
196 "d3_d0",
197 "d3_d1",
198 "d4",
199 "d5",
200 ], use_names=False, use_relative_indices=True)
201
202 def test_threedkp(self):
203 """ check if the indexing works with more than two ... """
204 self.assertAliases(
205 "B0 -> [D+ -> [K+ -> ^pi+]] [D+ -> [K+ -> ^pi+]] [D+ -> [K+ -> ^pi+]]",
206 [
207 "D_0_K_pi",
208 "D_1_K_pi",
209 "D_2_K_pi",
210 ])
211
212 def test_fourdkp(self):
213 """ check if the indexing works with more than two ... """
214 self.assertAliases(
215 "B0 -> [D+ -> [K+ -> ^pi+]] [D+ -> [K+ -> ^pi+]] [D+ -> [K+ -> ^pi+]] [D+ -> [K+ -> ^pi+]]",
216 [
217 "D_0_K_pi",
218 "D_1_K_pi",
219 "D_2_K_pi",
220 "D_3_K_pi",
221 ])
222 self.assertAliases(
223 "B0 -> [D+ -> [K+ -> pi+]] [D+ -> [K+ -> ^pi+]] [D+ -> [^K+ -> pi+]] [D+ -> [K+ -> ^pi+]]",
224 [
225 "D_1_K_pi",
226 "D_2_K",
227 "D_3_K_pi",
228 ])
229 self.assertAliases(
230 "B0 -> [D+ -> [K+ -> pi+]] [D+ -> [K+ -> ^pi+]] [D+ -> [^K+ -> pi+]] [D+ -> [K+ -> ^pi+]]",
231 [
232 "D_0_K_pi",
233 "D_1_K",
234 "D_2_K_pi",
235 ], use_relative_indices=True)
236
238 """Test many many children"""
239 self.assertAliases(
240 "B0 -> e+:0 ^e+:1 ^e+:2 e+:3 ^e+:4 e+:5 ^e+:6 mu+:7 ^mu+:8 mu+:9 ^mu+:10 ^mu+:11 mu+:12",
241 [
242 "e_1",
243 "e_2",
244 "e_4",
245 "e_6",
246 "mu_8",
247 "mu_10",
248 "mu_11",
249 ])
250
252 """Test many many children with relative indices"""
253 self.assertAliases(
254 "B0 -> e+:0 ^e+:1 ^e+:2 e+:3 ^e+:4 e+:5 ^e+:6 mu+:7 ^mu+:8 mu+:9 ^mu+:10 ^mu+:11 mu+:12",
255 [
256 "e_0",
257 "e_1",
258 "e_2",
259 "e_3",
260 "mu_0",
261 "mu_1",
262 "mu_2",
263 ], use_relative_indices=True)
264
266 """Test many many children without names"""
267 for use_relative_indices in True, False:
268 for always_include_indices in True, False:
269 self.assertAliases(
270 "B0 -> e+:0 ^e+:1 ^e+:2 e+:3 ^e+:4 e+:5 ^e+:6 mu+:7 ^mu+:8 mu+:9 ^mu+:10 ^mu+:11 mu+:12",
271 [
272 "d1",
273 "d2",
274 "d4",
275 "d6",
276 "d8",
277 "d10",
278 "d11",
279 ], use_names=False,
280 use_relative_indices=use_relative_indices,
281 always_include_indices=always_include_indices,
282 )
283
284 def test_inclusive(self):
285 """Select a decay with the inclusive particle marker"""
286 self.assertAliases("B0 -> ^Xsd e+:loose e-:loose", ["Xsd"])
287
288 def test_zfinal(self):
289 """Print all aliases as a final check"""
290 vm.printAliases()
291
292
293if __name__ == '__main__':
294 unittest.main()
def test_wrong_decaystring(self)
to add to the tests here, please add a test_something_something for you favourite complicated decay s...
list _list_of_variables
list of variables to test
def assertAliases(self, decaystring, expected, **argk)