35 pybasf2.Module.__eq__ =
lambda a, b: a.type() == b.type()
and\
36 all(x == y
for x, y
in zip(a.available_params(), b.available_params()))
37 pybasf2.ModuleParamInfo.__eq__ =
lambda a, b: a.name == b.name
and a.values == b.values
38 pybasf2.Path.__eq__ =
lambda a, b: all(x == y
for x, y
in zip(a.modules(), b.modules()))
43 Print the parts of the paths which are different
45 for x, y
in zip(a.modules(), b.modules()):
46 if x.type() != y.type():
47 print(x.type(), y.type())
48 for n, m
in zip(x.available_params(), y.available_params()):
51 if n.values != m.values:
52 print(n.name, n.values, m.values)
55 def get_small_unittest_channels():
56 pion = Particle(
'pi+',
57 fei.config.MVAConfiguration(variables=[
'p',
'dr'],
58 target=
'isPrimarySignal'),
59 fei.config.PreCutConfiguration(userCut=
'[dr < 2] and [abs(dz) < 4]',
60 bestCandidateMode=
'highest',
61 bestCandidateVariable=
'piid',
63 fei.config.PostCutConfiguration(bestCandidateCut=10, value=0.01))
64 pion.addChannel([
'pi+:FSP'])
67 fei.config.MVAConfiguration(variables=[
'p',
'dr'],
68 target=
'isPrimarySignal'),
69 fei.config.PreCutConfiguration(userCut=
'[dr < 2] and [abs(dz) < 4]',
70 bestCandidateMode=
'highest',
71 bestCandidateVariable=
'Kid',
73 fei.config.PostCutConfiguration(bestCandidateCut=10, value=0.01))
74 kaon.addChannel([
'K+:FSP'])
77 fei.config.MVAConfiguration(variables=[
'M',
'p'],
79 fei.config.PreCutConfiguration(userCut=
'1.7 < M < 1.95',
80 bestCandidateMode=
'lowest',
81 bestCandidateVariable=
'abs(dM)',
83 fei.config.PostCutConfiguration(bestCandidateCut=10, value=0.001))
84 D0.addChannel([
'K-',
'pi+'])
85 D0.addChannel([
'pi-',
'pi+'])
87 particles = [pion, kaon, D0]
91 class TestGetStagesFromParticles(unittest.TestCase):
92 def test_get_stages_from_particles(self):
93 particles = fei.get_unittest_channels()
94 stages = fei.core.get_stages_from_particles(particles)
95 self.assertEqual(len(stages), 7)
96 self.assertEqual(len(stages[0]), 4)
97 self.assertEqual(stages[0][0].identifier,
'gamma:generic')
98 self.assertEqual(stages[0][1].identifier,
'mu+:generic')
99 self.assertEqual(stages[0][2].identifier,
'pi+:generic')
100 self.assertEqual(stages[0][3].identifier,
'K+:generic')
101 self.assertEqual(len(stages[1]), 1)
102 self.assertEqual(stages[1][0].identifier,
'pi0:generic')
103 self.assertEqual(len(stages[2]), 0)
104 self.assertEqual(len(stages[3]), 2)
105 self.assertEqual(stages[3][0].identifier,
'D0:generic')
106 self.assertEqual(stages[3][1].identifier,
'D0:semileptonic')
107 self.assertEqual(len(stages[4]), 0)
108 self.assertEqual(len(stages[5]), 0)
109 self.assertEqual(len(stages[6]), 0)
112 class TestTrainingDataInformation(unittest.TestCase):
115 if os.path.isfile(
'mcParticlesCount.root'):
116 os.remove(
'mcParticlesCount.root')
118 def test_reconstruct(self):
119 particles = fei.get_unittest_channels()
120 x = fei.core.TrainingDataInformation(particles)
122 path = basf2.create_path()
123 path.add_module(
'VariablesToHistogram', fileName=
'mcParticlesCount.root',
125 (
'NumberOfMCParticlesInEvent(321)', 100, -0.5, 99.5),
126 (
'NumberOfMCParticlesInEvent(421)', 100, -0.5, 99.5),
127 (
'NumberOfMCParticlesInEvent(13)', 100, -0.5, 99.5),
128 (
'NumberOfMCParticlesInEvent(111)', 100, -0.5, 99.5),
129 (
'NumberOfMCParticlesInEvent(211)', 100, -0.5, 99.5),
130 (
'NumberOfMCParticlesInEvent(22)', 100, -0.5, 99.5)]
132 print_path(path, x.reconstruct())
133 self.assertEqual(x.reconstruct(), path)
135 def test_available(self):
136 particles = fei.get_unittest_channels()
137 x = fei.core.TrainingDataInformation(particles)
138 self.assertEqual(x.available(),
False)
139 f = ROOT.TFile(
'mcParticlesCount.root',
'RECREATE')
140 self.assertEqual(x.available(),
True)
142 def test_get_mc_counts(self):
143 f = ROOT.TFile(
'mcParticlesCount.root',
'RECREATE')
145 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo211__bc",
"NumberOfMCParticlesInEvent__bo211__bc", 11, -0.5, 10.5)
152 f.Write(
"NumberOfMCParticlesInEvent__bo211__bc")
154 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo321__bc",
"NumberOfMCParticlesInEvent__bo321__bc", 11, -0.5, 10.5)
161 f.Write(
"NumberOfMCParticlesInEvent__bo321__bc")
163 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo13__bc",
"NumberOfMCParticlesInEvent__bo13__bc", 11, -0.5, 10.5)
166 f.Write(
"NumberOfMCParticlesInEvent__bo13__bc")
168 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo22__bc",
"NumberOfMCParticlesInEvent__bo222__bc", 11, -0.5, 10.5)
171 f.Write(
"NumberOfMCParticlesInEvent__bo22__bc")
173 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo111__bc",
"NumberOfMCParticlesInEvent__bo111__bc", 11, -0.5, 10.5)
180 f.Write(
"NumberOfMCParticlesInEvent__bo111__bc")
182 hist = ROOT.TH1F(
"NumberOfMCParticlesInEvent__bo421__bc",
"NumberOfMCParticlesInEvent__bo421__bc", 11, -0.5, 10.5)
189 f.Write(
"NumberOfMCParticlesInEvent__bo421__bc")
191 particles = fei.get_unittest_channels()
192 x = fei.core.TrainingDataInformation(particles)
195 211: {
'max': 5.0,
'min': 3.0,
'sum': 79.0,
'avg': 4.3888888888888893,
'std': 0.7556372504852998},
196 321: {
'max': 7.0,
'min': 2.0,
'sum': 77.0,
'avg': 4.2777777777777777,
'std': 1.8798804795209585},
197 13: {
'max': 5.0,
'min': 5.0,
'sum': 90.0,
'avg': 5.0,
'std': 0.0},
198 22: {
'max': 0.0,
'min': 0.0,
'sum': 0.0,
'avg': 0.0,
'std': 0.0},
199 111: {
'max': 5.0,
'min': 3.0,
'sum': 74.0,
'avg': 4.1111111111111107,
'std': 0.6573421981221816},
200 421: {
'max': 9.0,
'min': 0.0,
'sum': 93.0,
'avg': 5.166666666666667,
'std': 4.2979323194092087},
202 self.assertDictEqual(x.get_mc_counts(), mcCounts)
205 class TestFSPLoader(unittest.TestCase):
207 def test_belle2_without_monitoring(self):
208 particles = get_small_unittest_channels()
209 config = fei.config.FeiConfiguration(monitor=
False)
210 x = fei.core.FSPLoader(particles, config)
212 path = basf2.create_path()
213 fsps = [
'K+:FSP',
'pi+:FSP',
'e+:FSP',
'mu+:FSP',
'gamma:FSP',
'p+:FSP',
'K_L0:FSP']
214 path.add_module(
'ParticleLoader', decayStrings=fsps, writeOut=
True)
216 path.add_module(
'ParticleListManipulator', outputListName=fsp,
217 inputListNames=[fsp.split(
':')[0] +
':all'], writeOut=
True)
219 path.add_module(
'ParticleSelector', decayString=
'gamma:FSP', cut=
'isFromECL')
220 path.add_module(
'ParticleLoader', decayStrings=[
'K_S0:V0 -> pi+ pi-'], writeOut=
True)
221 path.add_module(
'ParticleLoader', decayStrings=[
'Lambda0:V0 -> p+ pi-'], writeOut=
True)
222 path.add_module(
'ParticleLoader', decayStrings=[
'gamma:V0 -> e+ e-'], addDaughters=
True, writeOut=
True)
223 print_path(path, x.reconstruct())
224 self.assertEqual(x.reconstruct(), path)
226 def test_belle2_with_monitoring(self):
227 particles = get_small_unittest_channels()
228 config = fei.config.FeiConfiguration(monitor=
True)
229 x = fei.core.FSPLoader(particles, config)
231 path = basf2.create_path()
232 fsps = [
'K+:FSP',
'pi+:FSP',
'e+:FSP',
'mu+:FSP',
'gamma:FSP',
'p+:FSP',
'K_L0:FSP']
233 path.add_module(
'ParticleLoader', decayStrings=fsps, writeOut=
True)
235 path.add_module(
'ParticleListManipulator', outputListName=fsp,
236 inputListNames=[fsp.split(
':')[0] +
':all'], writeOut=
True)
238 path.add_module(
'ParticleSelector', decayString=
'gamma:FSP', cut=
'isFromECL')
239 path.add_module(
'ParticleLoader', decayStrings=[
'K_S0:V0 -> pi+ pi-'], writeOut=
True)
240 path.add_module(
'ParticleLoader', decayStrings=[
'Lambda0:V0 -> p+ pi-'], writeOut=
True)
241 path.add_module(
'ParticleLoader', decayStrings=[
'gamma:V0 -> e+ e-'], addDaughters=
True, writeOut=
True)
242 hist_variables = [(f
'NumberOfMCParticlesInEvent({pdgcode})', 100, -0.5, 99.5)
243 for pdgcode
in set([11, 321, 211, 13, 22, 310, 2212, 130, 3122, 111])]
244 path.add_module(
'VariablesToHistogram', particleList=
'',
245 variables=hist_variables,
246 fileName=
'Monitor_FSPLoader.root')
247 print_path(path, x.reconstruct())
248 self.assertEqual(x.reconstruct(), path)
250 def test_belle1_without_monitoring(self):
251 particles = get_small_unittest_channels()
253 config = fei.config.FeiConfiguration(monitor=
False)
254 x = fei.core.FSPLoader(particles, config)
256 path = basf2.create_path()
257 fsps = [
'K+:FSP',
'pi+:FSP',
'e+:FSP',
'mu+:FSP',
'p+:FSP']
258 path.add_module(
'ParticleLoader', decayStrings=fsps, writeOut=
True)
260 path.add_module(
'ParticleListManipulator', outputListName=fsp,
261 inputListNames=[fsp.split(
':')[0] +
':all'], writeOut=
True)
262 path.add_module(
'ParticleListManipulator', outputListName=
'gamma:FSP', inputListNames=[
'gamma:mdst'], writeOut=
True)
263 path.add_module(
'ParticleCopier', inputListNames=[
'gamma:FSP'])
264 path.add_module(
'ParticleListManipulator', outputListName=
'K_S0:V0', inputListNames=[
'K_S0:mdst'], writeOut=
True)
265 path.add_module(
'ParticleCopier', inputListNames=[
'K_S0:V0'])
266 path.add_module(
'ParticleListManipulator', outputListName=
'Lambda0:V0', inputListNames=[
'Lambda0:mdst'], writeOut=
True)
267 path.add_module(
'ParticleCopier', inputListNames=[
'Lambda0:V0'])
268 path.add_module(
'ParticleListManipulator', outputListName=
'K_L0:FSP', inputListNames=[
'K_L0:mdst'], writeOut=
True)
269 path.add_module(
'ParticleCopier', inputListNames=[
'K_L0:FSP'])
270 path.add_module(
'ParticleListManipulator', outputListName=
'pi0:FSP', inputListNames=[
'pi0:mdst'], writeOut=
True)
271 path.add_module(
'ParticleCopier', inputListNames=[
'pi0:FSP'])
272 path.add_module(
'ParticleListManipulator', outputListName=
'gamma:V0', inputListNames=[
'gamma:v0mdst'], writeOut=
True)
273 path.add_module(
'ParticleCopier', inputListNames=[
'gamma:V0'])
274 print_path(path, x.reconstruct())
275 self.assertEqual(x.reconstruct(), path)
278 def test_belle1_with_monitoring(self):
279 particles = get_small_unittest_channels()
281 config = fei.config.FeiConfiguration(monitor=
True)
282 x = fei.core.FSPLoader(particles, config)
284 path = basf2.create_path()
285 fsps = [
'K+:FSP',
'pi+:FSP',
'e+:FSP',
'mu+:FSP',
'p+:FSP']
286 path.add_module(
'ParticleLoader', decayStrings=fsps, writeOut=
True)
288 path.add_module(
'ParticleListManipulator', outputListName=fsp,
289 inputListNames=[fsp.split(
':')[0] +
':all'], writeOut=
True)
290 path.add_module(
'ParticleListManipulator', outputListName=
'gamma:FSP', inputListNames=[
'gamma:mdst'], writeOut=
True)
291 path.add_module(
'ParticleCopier', inputListNames=[
'gamma:FSP'])
292 path.add_module(
'ParticleListManipulator', outputListName=
'K_S0:V0', inputListNames=[
'K_S0:mdst'], writeOut=
True)
293 path.add_module(
'ParticleCopier', inputListNames=[
'K_S0:V0'])
294 path.add_module(
'ParticleListManipulator', outputListName=
'Lambda0:V0', inputListNames=[
'Lambda0:mdst'], writeOut=
True)
295 path.add_module(
'ParticleCopier', inputListNames=[
'Lambda0:V0'])
296 path.add_module(
'ParticleListManipulator', outputListName=
'K_L0:FSP', inputListNames=[
'K_L0:mdst'], writeOut=
True)
297 path.add_module(
'ParticleCopier', inputListNames=[
'K_L0:FSP'])
298 path.add_module(
'ParticleListManipulator', outputListName=
'pi0:FSP', inputListNames=[
'pi0:mdst'], writeOut=
True)
299 path.add_module(
'ParticleCopier', inputListNames=[
'pi0:FSP'])
300 path.add_module(
'ParticleListManipulator', outputListName=
'gamma:V0', inputListNames=[
'gamma:v0mdst'], writeOut=
True)
301 path.add_module(
'ParticleCopier', inputListNames=[
'gamma:V0'])
302 hist_variables = [(f
'NumberOfMCParticlesInEvent({pdgcode})', 100, -0.5, 99.5)
303 for pdgcode
in set([11, 321, 211, 13, 22, 310, 2212, 130, 3122, 111])]
304 path.add_module(
'VariablesToHistogram', particleList=
'',
305 variables=hist_variables,
306 fileName=
'Monitor_FSPLoader.root')
307 print_path(path, x.reconstruct())
308 self.assertEqual(x.reconstruct(), path)
312 class TestTrainingData(unittest.TestCase):
316 211: {
'sum': 79,
'avg': 4.3888888888888893,
'max': 5,
'min': 3,
'std': 0.75563725048530228},
317 321: {
'sum': 77,
'avg': 4.2777777777777777,
'max': 7,
'min': 2,
'std': 1.8798804795209592},
318 421: {
'sum': 93,
'avg': 5.166666666666667,
'max': 9,
'min': 0,
'std': 4.2979323194092087},
321 def test_without_monitoring(self):
322 particles = get_small_unittest_channels()
323 config = fei.config.FeiConfiguration(monitor=
False)
324 x = fei.core.TrainingData(particles, config, self.mc_counts)
326 path = basf2.create_path()
327 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root', treeName=
'pi+:generic ==> pi+:FSP variables',
328 variables=[
'p',
'dr',
'isPrimarySignal'],
329 particleList=
'pi+:generic_0', sampling=(
'isPrimarySignal', {}))
330 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root', treeName=
'K+:generic ==> K+:FSP variables',
331 variables=[
'p',
'dr',
'isPrimarySignal'],
332 particleList=
'K+:generic_0', sampling=(
'isPrimarySignal', {}))
333 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root',
334 treeName=
'D0:generic ==> K-:generic pi+:generic variables',
335 variables=[
'M',
'p',
'isSignal'],
336 particleList=
'D0:generic_0', sampling=(
'isSignal', {}))
337 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root',
338 treeName=
'D0:generic ==> pi-:generic pi+:generic variables',
339 variables=[
'M',
'p',
'isSignal'],
340 particleList=
'D0:generic_1', sampling=(
'isSignal', {}))
341 print_path(path, x.reconstruct())
342 self.assertEqual(x.reconstruct(), path)
344 def test_with_monitoring(self):
345 particles = get_small_unittest_channels()
346 config = fei.config.FeiConfiguration(monitor=
True)
347 x = fei.core.TrainingData(particles, config, self.mc_counts)
349 path = basf2.create_path()
350 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic_0',
351 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'p',
'dr',
'isPrimarySignal']),
352 variables_2d=fei.config.variables2binnings_2d([(
'p',
'isPrimarySignal'), (
'dr',
'isPrimarySignal')]),
353 fileName=
'Monitor_TrainingData.root', directory=
'pi+:generic ==> pi+:FSP')
354 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root', treeName=
'pi+:generic ==> pi+:FSP variables',
355 variables=[
'p',
'dr',
'isPrimarySignal'],
356 particleList=
'pi+:generic_0', sampling=(
'isPrimarySignal', {}))
357 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic_0',
358 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'p',
'dr',
'isPrimarySignal']),
359 variables_2d=fei.config.variables2binnings_2d([(
'p',
'isPrimarySignal'), (
'dr',
'isPrimarySignal')]),
360 fileName=
'Monitor_TrainingData.root', directory=
'K+:generic ==> K+:FSP')
361 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root', treeName=
'K+:generic ==> K+:FSP variables',
362 variables=[
'p',
'dr',
'isPrimarySignal'],
363 particleList=
'K+:generic_0', sampling=(
'isPrimarySignal', {}))
364 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_0',
365 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'M',
'p',
'isSignal']),
366 variables_2d=fei.config.variables2binnings_2d([(
'M',
'isSignal'), (
'p',
'isSignal')]),
367 fileName=
'Monitor_TrainingData.root', directory=
'D0:generic ==> K-:generic pi+:generic')
368 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root',
369 treeName=
'D0:generic ==> K-:generic pi+:generic variables',
370 variables=[
'M',
'p',
'isSignal'],
371 particleList=
'D0:generic_0', sampling=(
'isSignal', {}))
372 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_1',
373 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'M',
'p',
'isSignal']),
374 variables_2d=fei.config.variables2binnings_2d([(
'M',
'isSignal'), (
'p',
'isSignal')]),
375 fileName=
'Monitor_TrainingData.root', directory=
'D0:generic ==> pi-:generic pi+:generic')
376 path.add_module(
'VariablesToNtuple', fileName=
'training_input.root',
377 treeName=
'D0:generic ==> pi-:generic pi+:generic variables',
378 variables=[
'M',
'p',
'isSignal'],
379 particleList=
'D0:generic_1', sampling=(
'isSignal', {}))
380 print_path(path, x.reconstruct())
381 self.assertEqual(x.reconstruct(), path)
384 class TestPreReconstruction(unittest.TestCase):
386 def test_without_monitoring(self):
387 particles = get_small_unittest_channels()
388 config = fei.config.FeiConfiguration(monitor=
False)
389 x = fei.core.PreReconstruction(particles, config)
391 path = basf2.create_path()
392 path.add_module(
'ParticleListManipulator', inputListNames=[
'pi+:FSP'], outputListName=
'pi+:generic_0',
393 cut=
'[dr < 2] and [abs(dz) < 4]', writeOut=
True)
394 path.add_module(
'VariablesToExtraInfo', particleList=
'pi+:generic_0', variables={
'constant(0)':
'decayModeID'})
395 path.add_module(
'BestCandidateSelection', particleList=
'pi+:generic_0', variable=
'piid', selectLowest=
False,
396 numBest=20, outputVariable=
'preCut_rank')
398 path.add_module(
'ParticleListManipulator', inputListNames=[
'K+:FSP'], outputListName=
'K+:generic_0',
399 cut=
'[dr < 2] and [abs(dz) < 4]', writeOut=
True)
400 path.add_module(
'VariablesToExtraInfo', particleList=
'K+:generic_0', variables={
'constant(0)':
'decayModeID'})
401 path.add_module(
'BestCandidateSelection', particleList=
'K+:generic_0', variable=
'Kid', selectLowest=
False,
402 numBest=20, outputVariable=
'preCut_rank')
404 path.add_module(
'ParticleCombiner', decayString=
'D0:generic_0 -> K-:generic pi+:generic', writeOut=
True,
405 decayMode=0, cut=
'1.7 < M < 1.95')
406 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic_0',
407 variable=
'abs(dM)', selectLowest=
True, numBest=20, outputVariable=
'preCut_rank')
408 path.add_module(
'ParticleVertexFitter', listName=
'D0:generic_0', confidenceLevel=-2.0,
409 vertexFitter=
'KFit', fitType=
'vertex')
411 path.add_module(
'ParticleCombiner', decayString=
'D0:generic_1 -> pi-:generic pi+:generic', writeOut=
True,
412 decayMode=1, cut=
'1.7 < M < 1.95')
413 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic_1',
414 variable=
'abs(dM)', selectLowest=
True, numBest=20, outputVariable=
'preCut_rank')
415 path.add_module(
'ParticleVertexFitter', listName=
'D0:generic_1', confidenceLevel=-2.0,
416 vertexFitter=
'KFit', fitType=
'vertex')
418 print_path(path, x.reconstruct())
419 self.assertEqual(x.reconstruct(), path)
421 def test_with_monitoring(self):
422 particles = get_small_unittest_channels()
423 config = fei.config.FeiConfiguration(monitor=
True)
424 x = fei.core.PreReconstruction(particles, config)
426 path = basf2.create_path()
427 path.add_module(
'ParticleListManipulator', inputListNames=[
'pi+:FSP'], outputListName=
'pi+:generic_0',
428 cut=
'[dr < 2] and [abs(dz) < 4]', writeOut=
True)
429 path.add_module(
'VariablesToExtraInfo', particleList=
'pi+:generic_0', variables={
'constant(0)':
'decayModeID'})
430 path.add_module(
'MCMatcherParticles', listName=
'pi+:generic_0')
431 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic_0',
432 variables=fei.config.variables2binnings([
'piid',
'mcErrors',
'mcParticleStatus',
'isPrimarySignal']),
433 variables_2d=fei.config.variables2binnings_2d([(
'piid',
'isPrimarySignal'),
434 (
'piid',
'mcErrors'),
435 (
'piid',
'mcParticleStatus')]),
436 fileName=
'Monitor_PreReconstruction_BeforeRanking.root', directory=
'pi+:generic ==> pi+:FSP')
437 path.add_module(
'BestCandidateSelection', particleList=
'pi+:generic_0', variable=
'piid', selectLowest=
False,
438 numBest=20, outputVariable=
'preCut_rank')
439 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic_0',
440 variables=fei.config.variables2binnings([
'piid',
'mcErrors',
'mcParticleStatus',
441 'isPrimarySignal',
'extraInfo(preCut_rank)']),
442 variables_2d=fei.config.variables2binnings_2d([(
'piid',
'isPrimarySignal'),
443 (
'piid',
'mcErrors'),
444 (
'piid',
'mcParticleStatus'),
445 (
'extraInfo(preCut_rank)',
'isPrimarySignal'),
446 (
'extraInfo(preCut_rank)',
'mcErrors'),
447 (
'extraInfo(preCut_rank)',
'mcParticleStatus')]),
448 fileName=
'Monitor_PreReconstruction_AfterRanking.root', directory=
'pi+:generic ==> pi+:FSP')
449 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic_0',
450 variables=fei.config.variables2binnings([
'chiProb',
'mcErrors',
'mcParticleStatus',
452 variables_2d=fei.config.variables2binnings_2d([(
'chiProb',
'isPrimarySignal'),
453 (
'chiProb',
'mcErrors'),
454 (
'chiProb',
'mcParticleStatus')]),
455 fileName=
'Monitor_PreReconstruction_AfterVertex.root', directory=
'pi+:generic ==> pi+:FSP')
457 path.add_module(
'ParticleListManipulator', inputListNames=[
'K+:FSP'], outputListName=
'K+:generic_0',
458 cut=
'[dr < 2] and [abs(dz) < 4]', writeOut=
True)
459 path.add_module(
'VariablesToExtraInfo', particleList=
'K+:generic_0', variables={
'constant(0)':
'decayModeID'})
461 path.add_module(
'MCMatcherParticles', listName=
'K+:generic_0')
462 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic_0',
463 variables=fei.config.variables2binnings([
'Kid',
'mcErrors',
'mcParticleStatus',
'isPrimarySignal']),
464 variables_2d=fei.config.variables2binnings_2d([(
'Kid',
'isPrimarySignal'),
466 (
'Kid',
'mcParticleStatus')]),
467 fileName=
'Monitor_PreReconstruction_BeforeRanking.root', directory=
'K+:generic ==> K+:FSP')
468 path.add_module(
'BestCandidateSelection', particleList=
'K+:generic_0', variable=
'Kid', selectLowest=
False,
469 numBest=20, outputVariable=
'preCut_rank')
470 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic_0',
471 variables=fei.config.variables2binnings([
'Kid',
'mcErrors',
'mcParticleStatus',
472 'isPrimarySignal',
'extraInfo(preCut_rank)']),
473 variables_2d=fei.config.variables2binnings_2d([(
'Kid',
'isPrimarySignal'),
475 (
'Kid',
'mcParticleStatus'),
476 (
'extraInfo(preCut_rank)',
'isPrimarySignal'),
477 (
'extraInfo(preCut_rank)',
'mcErrors'),
478 (
'extraInfo(preCut_rank)',
'mcParticleStatus')]),
479 fileName=
'Monitor_PreReconstruction_AfterRanking.root', directory=
'K+:generic ==> K+:FSP')
480 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic_0',
481 variables=fei.config.variables2binnings([
'chiProb',
'mcErrors',
'mcParticleStatus',
483 variables_2d=fei.config.variables2binnings_2d([(
'chiProb',
'isPrimarySignal'),
484 (
'chiProb',
'mcErrors'),
485 (
'chiProb',
'mcParticleStatus')]),
486 fileName=
'Monitor_PreReconstruction_AfterVertex.root', directory=
'K+:generic ==> K+:FSP')
488 path.add_module(
'ParticleCombiner', decayString=
'D0:generic_0 -> K-:generic pi+:generic', writeOut=
True,
489 decayMode=0, cut=
'1.7 < M < 1.95')
490 path.add_module(
'MCMatcherParticles', listName=
'D0:generic_0')
491 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_0',
492 variables=fei.config.variables2binnings([
'abs(dM)',
'mcErrors',
'mcParticleStatus',
'isSignal']),
493 variables_2d=fei.config.variables2binnings_2d([(
'abs(dM)',
'isSignal'),
494 (
'abs(dM)',
'mcErrors'),
495 (
'abs(dM)',
'mcParticleStatus')]),
496 fileName=
'Monitor_PreReconstruction_BeforeRanking.root', directory=
'D0:generic ==> K-:generic pi+:generic')
497 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic_0',
498 variable=
'abs(dM)', selectLowest=
True, numBest=20, outputVariable=
'preCut_rank')
499 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_0',
500 variables=fei.config.variables2binnings([
'abs(dM)',
'mcErrors',
'mcParticleStatus',
501 'isSignal',
'extraInfo(preCut_rank)']),
502 variables_2d=fei.config.variables2binnings_2d([(
'abs(dM)',
'isSignal'),
503 (
'abs(dM)',
'mcErrors'),
504 (
'abs(dM)',
'mcParticleStatus'),
505 (
'extraInfo(preCut_rank)',
'isSignal'),
506 (
'extraInfo(preCut_rank)',
'mcErrors'),
507 (
'extraInfo(preCut_rank)',
'mcParticleStatus')]),
508 fileName=
'Monitor_PreReconstruction_AfterRanking.root', directory=
'D0:generic ==> K-:generic pi+:generic')
509 path.add_module(
'ParticleVertexFitter', listName=
'D0:generic_0', confidenceLevel=-2.0,
510 vertexFitter=
'KFit', fitType=
'vertex')
511 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_0',
512 variables=fei.config.variables2binnings([
'chiProb',
'mcErrors',
'mcParticleStatus',
514 variables_2d=fei.config.variables2binnings_2d([(
'chiProb',
'isSignal'),
515 (
'chiProb',
'mcErrors'),
516 (
'chiProb',
'mcParticleStatus')]),
517 fileName=
'Monitor_PreReconstruction_AfterVertex.root', directory=
'D0:generic ==> K-:generic pi+:generic')
519 path.add_module(
'ParticleCombiner', decayString=
'D0:generic_1 -> pi-:generic pi+:generic', writeOut=
True,
520 decayMode=1, cut=
'1.7 < M < 1.95')
521 path.add_module(
'MCMatcherParticles', listName=
'D0:generic_1')
522 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_1',
523 variables=fei.config.variables2binnings([
'abs(dM)',
'mcErrors',
'mcParticleStatus',
'isSignal']),
524 variables_2d=fei.config.variables2binnings_2d([(
'abs(dM)',
'isSignal'),
525 (
'abs(dM)',
'mcErrors'),
526 (
'abs(dM)',
'mcParticleStatus')]),
527 fileName=
'Monitor_PreReconstruction_BeforeRanking.root', directory=
'D0:generic ==> pi-:generic pi+:generic')
528 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic_1',
529 variable=
'abs(dM)', selectLowest=
True, numBest=20, outputVariable=
'preCut_rank')
530 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_1',
531 variables=fei.config.variables2binnings([
'abs(dM)',
'mcErrors',
'mcParticleStatus',
532 'isSignal',
'extraInfo(preCut_rank)']),
533 variables_2d=fei.config.variables2binnings_2d([(
'abs(dM)',
'isSignal'),
534 (
'abs(dM)',
'mcErrors'),
535 (
'abs(dM)',
'mcParticleStatus'),
536 (
'extraInfo(preCut_rank)',
'isSignal'),
537 (
'extraInfo(preCut_rank)',
'mcErrors'),
538 (
'extraInfo(preCut_rank)',
'mcParticleStatus')]),
539 fileName=
'Monitor_PreReconstruction_AfterRanking.root', directory=
'D0:generic ==> pi-:generic pi+:generic')
540 path.add_module(
'ParticleVertexFitter', listName=
'D0:generic_1', confidenceLevel=-2.0,
541 vertexFitter=
'KFit', fitType=
'vertex')
542 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_1',
543 variables=fei.config.variables2binnings([
'chiProb',
'mcErrors',
'mcParticleStatus',
545 variables_2d=fei.config.variables2binnings_2d([(
'chiProb',
'isSignal'),
546 (
'chiProb',
'mcErrors'),
547 (
'chiProb',
'mcParticleStatus')]),
548 fileName=
'Monitor_PreReconstruction_AfterVertex.root', directory=
'D0:generic ==> pi-:generic pi+:generic')
550 print_path(path, x.reconstruct())
551 self.assertEqual(x.reconstruct(), path)
554 class TestPostReconstruction(unittest.TestCase):
556 def test_get_missing_channels(self):
557 pion = Particle(
'pi+:unittest', fei.config.MVAConfiguration(variables=[
'p',
'dr'], target=
'isPrimarySignal'))
558 pion.addChannel([
'pi+:FSP'])
559 D0 = Particle(
'D0:unittest', fei.config.MVAConfiguration(variables=[
'M',
'p'], target=
'isSignal'))
560 D0.addChannel([
'K-:unittest',
'pi+:unittest'])
561 D0.addChannel([
'pi-:unittest',
'pi+:unittest'])
562 config = fei.config.FeiConfiguration(monitor=
False, prefix=
"UNITTEST")
563 x = fei.core.PostReconstruction([pion, D0], config)
565 self.assertEqual(x.get_missing_channels(), [
'pi+:unittest ==> pi+:FSP',
'D0:unittest ==> K-:unittest pi+:unittest',
566 'D0:unittest ==> pi-:unittest pi+:unittest'])
567 self.assertEqual(x.available(),
False)
570 <?xml version="1.0" encoding="utf-8"?>
571 <method>Trivial</method>
572 <weightfile>{channel}.xml</weightfile>
573 <treename>tree</treename>
574 <target_variable>isSignal</target_variable>
575 <weight_variable>__weight__</weight_variable>
576 <signal_class>1</signal_class>
577 <max_events>0</max_events>
578 <number_feature_variables>1</number_feature_variables>
579 <variable0>M</variable0>
580 <number_spectator_variables>0</number_spectator_variables>
581 <number_data_files>1</number_data_files>
582 <datafile0>train.root</datafile0>
583 <Trivial_version>1</Trivial_version>
584 <Trivial_output>0</Trivial_output>
585 <signal_fraction>0.066082567</signal_fraction>
588 channel =
'D0:unittest ==> K-:unittest pi+:unittest'
589 with open(channel +
".xml",
"w")
as f:
590 f.write(content.format(channel=channel))
591 basf2_mva.upload(channel +
".xml",
'UNITTEST_' + channel)
593 self.assertEqual(x.get_missing_channels(), [
'pi+:unittest ==> pi+:FSP',
594 'D0:unittest ==> pi-:unittest pi+:unittest'])
595 self.assertEqual(x.available(),
False)
597 channel =
'D0:unittest ==> pi-:unittest pi+:unittest'
598 with open(channel +
".xml",
"w")
as f:
599 f.write(content.format(channel=channel))
600 basf2_mva.upload(channel +
".xml",
'UNITTEST_' + channel)
602 self.assertEqual(x.get_missing_channels(), [
'pi+:unittest ==> pi+:FSP'])
603 self.assertEqual(x.available(),
False)
605 channel =
'pi+:unittest ==> pi+:FSP'
606 with open(channel +
".xml",
"w")
as f:
607 f.write(content.format(channel=channel))
608 basf2_mva.upload(channel +
".xml",
'UNITTEST_' + channel)
610 self.assertEqual(x.get_missing_channels(), [])
611 self.assertEqual(x.available(),
True)
614 if os.path.isfile(
'pi+:unittest ==> pi+:FSP.xml'):
615 os.remove(
'pi+:unittest ==> pi+:FSP.xml')
616 if os.path.isfile(
'D0:unittest ==> pi-:unittest pi+:unittest.xml'):
617 os.remove(
'D0:unittest ==> pi-:unittest pi+:unittest.xml')
618 if os.path.isfile(
'D0:unittest ==> K-:unittest pi+:unittest.xml'):
619 os.remove(
'D0:unittest ==> K-:unittest pi+:unittest.xml')
621 def test_without_monitoring(self):
622 particles = get_small_unittest_channels()
623 config = fei.config.FeiConfiguration(monitor=
False, prefix=
'UNITTEST')
624 x = fei.core.PostReconstruction(particles, config)
626 path = basf2.create_path()
628 path.add_module(
'MVAExpert', identifier=
'UNITTEST_pi+:generic ==> pi+:FSP', extraInfoName=
'SignalProbability',
629 listNames=[
'pi+:generic_0'])
630 path.add_module(
'TagUniqueSignal', particleList=
'pi+:generic_0', target=
'isPrimarySignal',
631 extraInfoName=
'uniqueSignal')
632 path.add_module(
'ParticleListManipulator', outputListName=
'pi+:generic', inputListNames=[
'pi+:generic_0'],
633 variable=
'particleSource', writeOut=
True)
634 path.add_module(
'ParticleSelector', decayString=
'pi+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
635 path.add_module(
'BestCandidateSelection', particleList=
'pi+:generic', variable=
'extraInfo(SignalProbability)',
636 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
638 path.add_module(
'MVAExpert', identifier=
'UNITTEST_K+:generic ==> K+:FSP', extraInfoName=
'SignalProbability',
639 listNames=[
'K+:generic_0'])
640 path.add_module(
'TagUniqueSignal', particleList=
'K+:generic_0', target=
'isPrimarySignal',
641 extraInfoName=
'uniqueSignal')
642 path.add_module(
'ParticleListManipulator', outputListName=
'K+:generic', inputListNames=[
'K+:generic_0'],
643 variable=
'particleSource', writeOut=
True)
644 path.add_module(
'ParticleSelector', decayString=
'K+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
645 path.add_module(
'BestCandidateSelection', particleList=
'K+:generic', variable=
'extraInfo(SignalProbability)',
646 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
648 path.add_module(
'MVAExpert', identifier=
'UNITTEST_D0:generic ==> K-:generic pi+:generic',
649 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_0'])
650 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_0', target=
'isSignal',
651 extraInfoName=
'uniqueSignal')
653 path.add_module(
'MVAExpert', identifier=
'UNITTEST_D0:generic ==> pi-:generic pi+:generic',
654 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_1'])
655 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_1', target=
'isSignal',
656 extraInfoName=
'uniqueSignal')
658 path.add_module(
'ParticleListManipulator', outputListName=
'D0:generic',
659 inputListNames=[
'D0:generic_0',
'D0:generic_1'], variable=
'particleSource',
661 path.add_module(
'ParticleSelector', decayString=
'D0:generic', cut=
'0.001 < extraInfo(SignalProbability)')
662 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic', variable=
'extraInfo(SignalProbability)',
663 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
665 print_path(path, x.reconstruct())
666 self.assertEqual(x.reconstruct(), path)
668 def test_without_monitoring_training_mode(self):
669 particles = get_small_unittest_channels()
670 config = fei.config.FeiConfiguration(monitor=
False, prefix=
'UNITTEST', training=
True)
671 x = fei.core.PostReconstruction(particles, config)
673 path = basf2.create_path()
675 path.add_module(
'MVAExpert', identifier=
'pi+:generic ==> pi+:FSP.xml', extraInfoName=
'SignalProbability',
676 listNames=[
'pi+:generic_0'])
677 path.add_module(
'TagUniqueSignal', particleList=
'pi+:generic_0', target=
'isPrimarySignal',
678 extraInfoName=
'uniqueSignal')
679 path.add_module(
'ParticleListManipulator', outputListName=
'pi+:generic', inputListNames=[
'pi+:generic_0'],
680 variable=
'particleSource', writeOut=
True)
681 path.add_module(
'ParticleSelector', decayString=
'pi+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
682 path.add_module(
'BestCandidateSelection', particleList=
'pi+:generic', variable=
'extraInfo(SignalProbability)',
683 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
685 path.add_module(
'MVAExpert', identifier=
'K+:generic ==> K+:FSP.xml', extraInfoName=
'SignalProbability',
686 listNames=[
'K+:generic_0'])
687 path.add_module(
'TagUniqueSignal', particleList=
'K+:generic_0', target=
'isPrimarySignal',
688 extraInfoName=
'uniqueSignal')
689 path.add_module(
'ParticleListManipulator', outputListName=
'K+:generic', inputListNames=[
'K+:generic_0'],
690 variable=
'particleSource', writeOut=
True)
691 path.add_module(
'ParticleSelector', decayString=
'K+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
692 path.add_module(
'BestCandidateSelection', particleList=
'K+:generic', variable=
'extraInfo(SignalProbability)',
693 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
695 path.add_module(
'MVAExpert', identifier=
'D0:generic ==> K-:generic pi+:generic.xml',
696 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_0'])
697 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_0', target=
'isSignal',
698 extraInfoName=
'uniqueSignal')
700 path.add_module(
'MVAExpert', identifier=
'D0:generic ==> pi-:generic pi+:generic.xml',
701 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_1'])
702 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_1', target=
'isSignal',
703 extraInfoName=
'uniqueSignal')
705 path.add_module(
'ParticleListManipulator', outputListName=
'D0:generic',
706 inputListNames=[
'D0:generic_0',
'D0:generic_1'], variable=
'particleSource',
708 path.add_module(
'ParticleSelector', decayString=
'D0:generic', cut=
'0.001 < extraInfo(SignalProbability)')
709 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic', variable=
'extraInfo(SignalProbability)',
710 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
712 print_path(path, x.reconstruct())
713 self.assertEqual(x.reconstruct(), path)
715 def test_with_monitoring(self):
716 particles = get_small_unittest_channels()
717 config = fei.config.FeiConfiguration(monitor=
True, prefix=
'UNITTEST')
718 x = fei.core.PostReconstruction(particles, config)
720 path = basf2.create_path()
722 path.add_module(
'MVAExpert', identifier=
'UNITTEST_pi+:generic ==> pi+:FSP', extraInfoName=
'SignalProbability',
723 listNames=[
'pi+:generic_0'])
724 path.add_module(
'TagUniqueSignal', particleList=
'pi+:generic_0', target=
'isPrimarySignal',
725 extraInfoName=
'uniqueSignal')
727 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic_0',
728 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
729 'extraInfo(SignalProbability)',
730 'isPrimarySignal',
'extraInfo(decayModeID)']),
731 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(SignalProbability)',
'isPrimarySignal'),
732 (
'extraInfo(SignalProbability)',
'mcErrors'),
733 (
'extraInfo(SignalProbability)',
'mcParticleStatus'),
734 (
'extraInfo(decayModeID)',
'isPrimarySignal'),
735 (
'extraInfo(decayModeID)',
'mcErrors'),
736 (
'extraInfo(decayModeID)',
'extraInfo(uniqueSignal)'),
737 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
738 fileName=
'Monitor_PostReconstruction_AfterMVA.root', directory=
'pi+:generic ==> pi+:FSP')
739 path.add_module(
'ParticleListManipulator', outputListName=
'pi+:generic', inputListNames=[
'pi+:generic_0'],
740 variable=
'particleSource', writeOut=
True)
741 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic',
742 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
743 'extraInfo(SignalProbability)',
744 'isPrimarySignal',
'extraInfo(decayModeID)']),
745 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
746 (
'extraInfo(decayModeID)',
'mcErrors'),
747 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
748 fileName=
'Monitor_PostReconstruction_BeforePostCut.root', directory=
'pi+:generic')
749 path.add_module(
'ParticleSelector', decayString=
'pi+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
750 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic',
751 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
752 'extraInfo(SignalProbability)',
753 'isPrimarySignal',
'extraInfo(decayModeID)']),
754 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
755 (
'extraInfo(decayModeID)',
'mcErrors'),
756 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
757 fileName=
'Monitor_PostReconstruction_BeforeRanking.root', directory=
'pi+:generic')
758 path.add_module(
'BestCandidateSelection', particleList=
'pi+:generic', variable=
'extraInfo(SignalProbability)',
759 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
760 path.add_module(
'VariablesToHistogram', particleList=
'pi+:generic',
761 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
762 'extraInfo(SignalProbability)',
'isPrimarySignal',
763 'extraInfo(decayModeID)',
'extraInfo(postCut_rank)']),
764 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
765 (
'extraInfo(decayModeID)',
'mcErrors'),
766 (
'extraInfo(decayModeID)',
'mcParticleStatus'),
767 (
'extraInfo(decayModeID)',
'extraInfo(postCut_rank)'),
768 (
'isPrimarySignal',
'extraInfo(postCut_rank)'),
769 (
'mcErrors',
'extraInfo(postCut_rank)'),
770 (
'mcParticleStatus',
'extraInfo(postCut_rank)')]),
771 fileName=
'Monitor_PostReconstruction_AfterRanking.root', directory=
'pi+:generic')
772 path.add_module(
'VariablesToNtuple', fileName=
'Monitor_Final.root', treeName=
'pi+:generic variables',
773 variables=[
'extraInfo(SignalProbability)',
'mcErrors',
'mcParticleStatus',
'isPrimarySignal',
774 'extraInfo(uniqueSignal)',
'extraInfo(decayModeID)'],
775 particleList=
'pi+:generic')
777 path.add_module(
'MVAExpert', identifier=
'UNITTEST_K+:generic ==> K+:FSP', extraInfoName=
'SignalProbability',
778 listNames=[
'K+:generic_0'])
779 path.add_module(
'TagUniqueSignal', particleList=
'K+:generic_0', target=
'isPrimarySignal',
780 extraInfoName=
'uniqueSignal')
781 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic_0',
782 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
783 'extraInfo(SignalProbability)',
784 'isPrimarySignal',
'extraInfo(decayModeID)']),
785 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(SignalProbability)',
'isPrimarySignal'),
786 (
'extraInfo(SignalProbability)',
'mcErrors'),
787 (
'extraInfo(SignalProbability)',
'mcParticleStatus'),
788 (
'extraInfo(decayModeID)',
'isPrimarySignal'),
789 (
'extraInfo(decayModeID)',
'mcErrors'),
790 (
'extraInfo(decayModeID)',
'extraInfo(uniqueSignal)'),
791 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
792 fileName=
'Monitor_PostReconstruction_AfterMVA.root', directory=
'K+:generic ==> K+:FSP')
793 path.add_module(
'ParticleListManipulator', outputListName=
'K+:generic', inputListNames=[
'K+:generic_0'],
794 variable=
'particleSource', writeOut=
True)
795 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic',
796 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
797 'extraInfo(SignalProbability)',
798 'isPrimarySignal',
'extraInfo(decayModeID)']),
799 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
800 (
'extraInfo(decayModeID)',
'mcErrors'),
801 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
802 fileName=
'Monitor_PostReconstruction_BeforePostCut.root', directory=
'K+:generic')
803 path.add_module(
'ParticleSelector', decayString=
'K+:generic', cut=
'0.01 < extraInfo(SignalProbability)')
804 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic',
805 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
806 'extraInfo(SignalProbability)',
807 'isPrimarySignal',
'extraInfo(decayModeID)']),
808 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
809 (
'extraInfo(decayModeID)',
'mcErrors'),
810 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
811 fileName=
'Monitor_PostReconstruction_BeforeRanking.root', directory=
'K+:generic')
812 path.add_module(
'BestCandidateSelection', particleList=
'K+:generic', variable=
'extraInfo(SignalProbability)',
813 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
814 path.add_module(
'VariablesToHistogram', particleList=
'K+:generic',
815 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
816 'extraInfo(SignalProbability)',
'isPrimarySignal',
817 'extraInfo(decayModeID)',
'extraInfo(postCut_rank)']),
818 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isPrimarySignal'),
819 (
'extraInfo(decayModeID)',
'mcErrors'),
820 (
'extraInfo(decayModeID)',
'mcParticleStatus'),
821 (
'extraInfo(decayModeID)',
'extraInfo(postCut_rank)'),
822 (
'isPrimarySignal',
'extraInfo(postCut_rank)'),
823 (
'mcErrors',
'extraInfo(postCut_rank)'),
824 (
'mcParticleStatus',
'extraInfo(postCut_rank)')]),
825 fileName=
'Monitor_PostReconstruction_AfterRanking.root', directory=
'K+:generic')
826 path.add_module(
'VariablesToNtuple', fileName=
'Monitor_Final.root', treeName=
'K+:generic variables',
827 variables=[
'extraInfo(SignalProbability)',
'mcErrors',
'mcParticleStatus',
'isPrimarySignal',
828 'extraInfo(uniqueSignal)',
'extraInfo(decayModeID)'],
829 particleList=
'K+:generic')
831 path.add_module(
'MVAExpert', identifier=
'UNITTEST_D0:generic ==> K-:generic pi+:generic',
832 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_0'])
833 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_0', target=
'isSignal',
834 extraInfoName=
'uniqueSignal')
835 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_0',
836 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
837 'extraInfo(SignalProbability)',
838 'isSignal',
'extraInfo(decayModeID)']),
839 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(SignalProbability)',
'isSignal'),
840 (
'extraInfo(SignalProbability)',
'mcErrors'),
841 (
'extraInfo(SignalProbability)',
'mcParticleStatus'),
842 (
'extraInfo(decayModeID)',
'isSignal'),
843 (
'extraInfo(decayModeID)',
'mcErrors'),
844 (
'extraInfo(decayModeID)',
'extraInfo(uniqueSignal)'),
845 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
846 fileName=
'Monitor_PostReconstruction_AfterMVA.root', directory=
'D0:generic ==> K-:generic pi+:generic')
848 path.add_module(
'MVAExpert', identifier=
'UNITTEST_D0:generic ==> pi-:generic pi+:generic',
849 extraInfoName=
'SignalProbability', listNames=[
'D0:generic_1'])
850 path.add_module(
'TagUniqueSignal', particleList=
'D0:generic_1', target=
'isSignal',
851 extraInfoName=
'uniqueSignal')
852 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic_1',
853 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
854 'extraInfo(SignalProbability)',
855 'isSignal',
'extraInfo(decayModeID)']),
856 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(SignalProbability)',
'isSignal'),
857 (
'extraInfo(SignalProbability)',
'mcErrors'),
858 (
'extraInfo(SignalProbability)',
'mcParticleStatus'),
859 (
'extraInfo(decayModeID)',
'isSignal'),
860 (
'extraInfo(decayModeID)',
'mcErrors'),
861 (
'extraInfo(decayModeID)',
'extraInfo(uniqueSignal)'),
862 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
863 fileName=
'Monitor_PostReconstruction_AfterMVA.root', directory=
'D0:generic ==> pi-:generic pi+:generic')
865 path.add_module(
'ParticleListManipulator', outputListName=
'D0:generic',
866 inputListNames=[
'D0:generic_0',
'D0:generic_1'], variable=
'particleSource',
868 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic',
869 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
870 'extraInfo(SignalProbability)',
871 'isSignal',
'extraInfo(decayModeID)']),
872 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isSignal'),
873 (
'extraInfo(decayModeID)',
'mcErrors'),
874 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
875 fileName=
'Monitor_PostReconstruction_BeforePostCut.root', directory=
'D0:generic')
876 path.add_module(
'ParticleSelector', decayString=
'D0:generic', cut=
'0.001 < extraInfo(SignalProbability)')
877 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic',
878 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
879 'extraInfo(SignalProbability)',
880 'isSignal',
'extraInfo(decayModeID)']),
881 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isSignal'),
882 (
'extraInfo(decayModeID)',
'mcErrors'),
883 (
'extraInfo(decayModeID)',
'mcParticleStatus')]),
884 fileName=
'Monitor_PostReconstruction_BeforeRanking.root', directory=
'D0:generic')
885 path.add_module(
'BestCandidateSelection', particleList=
'D0:generic', variable=
'extraInfo(SignalProbability)',
886 selectLowest=
False, numBest=10, outputVariable=
'postCut_rank')
887 path.add_module(
'VariablesToHistogram', particleList=
'D0:generic',
888 variables=fei.config.variables2binnings([
'mcErrors',
'mcParticleStatus',
'extraInfo(uniqueSignal)',
889 'extraInfo(SignalProbability)',
'isSignal',
890 'extraInfo(decayModeID)',
'extraInfo(postCut_rank)']),
891 variables_2d=fei.config.variables2binnings_2d([(
'extraInfo(decayModeID)',
'isSignal'),
892 (
'extraInfo(decayModeID)',
'mcErrors'),
893 (
'extraInfo(decayModeID)',
'mcParticleStatus'),
894 (
'extraInfo(decayModeID)',
'extraInfo(postCut_rank)'),
895 (
'isSignal',
'extraInfo(postCut_rank)'),
896 (
'mcErrors',
'extraInfo(postCut_rank)'),
897 (
'mcParticleStatus',
'extraInfo(postCut_rank)')]),
898 fileName=
'Monitor_PostReconstruction_AfterRanking.root', directory=
'D0:generic')
899 path.add_module(
'VariablesToNtuple', fileName=
'Monitor_Final.root', treeName=
'D0:generic variables',
900 variables=[
'extraInfo(SignalProbability)',
'mcErrors',
'mcParticleStatus',
'isSignal',
901 'extraInfo(uniqueSignal)',
'extraInfo(decayModeID)'],
902 particleList=
'D0:generic')
904 print_path(path, x.reconstruct())
905 self.assertEqual(x.reconstruct(), path)
908 class TestTeacher(unittest.TestCase):
910 fei.core.Teacher.MaximumNumberOfMVASamples = int(1e7)
911 fei.core.Teacher.MinimumNumberOfMVASamples = int(10)
913 f = ROOT.TFile(
'training_input.root',
'RECREATE')
915 tree = ROOT.TTree(
'pi+:generic ==> pi+:FSP variables',
'pi+:generic ==> pi+:FSP variables')
916 isSignal = np.zeros(1, dtype=float)
917 p = np.zeros(1, dtype=float)
918 pt = np.zeros(1, dtype=float)
919 tree.Branch(
'isPrimarySignal', isSignal,
'isPrimarySignal/D')
920 tree.Branch(
'p', p,
'p/D')
921 tree.Branch(
'dr', pt,
'dr/D')
922 for i
in range(1000):
927 tree.Write(
"", ROOT.TObject.kOverwrite)
931 tree = ROOT.TTree(
'D0:generic ==> K-:generic pi+:generic variables',
'D0:generic ==> K-:generic pi+:generic variables')
932 isSignal = np.zeros(1, dtype=float)
933 p = np.zeros(1, dtype=float)
934 pt = np.zeros(1, dtype=float)
935 tree.Branch(
'isSignal', isSignal,
'isSignal/D')
936 tree.Branch(
'M', p,
'M/D')
937 tree.Branch(
'p', pt,
'p/D')
944 tree.Write(
"", ROOT.TObject.kOverwrite)
946 tree = ROOT.TTree(
'D0:generic ==> pi-:generic pi+:generic variables',
'D0:generic ==> pi-:generic pi+:generic variables')
947 isSignal = np.zeros(1, dtype=float)
948 p = np.zeros(1, dtype=float)
949 pt = np.zeros(1, dtype=float)
950 tree.Branch(
'isSignal', isSignal,
'isSignal/D')
951 tree.Branch(
'M', p,
'M/D')
952 tree.Branch(
'p', pt,
'p/D')
953 for i
in range(1000):
958 tree.Write(
"", ROOT.TObject.kOverwrite)
961 if os.path.isfile(
'UNITTEST_TEACHER.xml'):
962 os.remove(
'UNITTEST_TEACHER.xml')
963 if os.path.isfile(
'UNITTEST_pi+:generic ==> pi+:FSP.xml'):
964 os.remove(
'UNITTEST_pi+:generic ==> pi+:FSP.xml')
965 if os.path.isfile(
'UNITTEST_K+:generic ==> K+:FSP.xml'):
966 os.remove(
'UNITTEST_K+:generic ==> K+:FSP.xml')
967 if os.path.isfile(
'UNITTEST_D0:generic ==> K-:generic pi+:generic.xml'):
968 os.remove(
'UNITTEST_D0:generic ==> K-:generic pi+:generic.xml')
969 if os.path.isfile(
'UNITTEST_D0:generic ==> pi-:generic pi+:generic.xml'):
970 os.remove(
'UNITTEST_D0:generic ==> pi-:generic pi+:generic.xml')
971 if os.path.isfile(
'training_input.root'):
972 os.remove(
'training_input.root')
974 def test_create_fake_weightfile(self):
975 self.assertEqual(os.path.isfile(
'UNITTEST_pi+:generic ==> pi+:FSP.xml'),
False)
976 self.assertEqual(basf2_mva.available(
'UNITTEST_pi+:generic ==> pi+:FSP.xml'),
False)
977 fei.core.Teacher.create_fake_weightfile(
'UNITTEST_pi+:generic ==> pi+:FSP')
978 self.assertEqual(os.path.isfile(
'UNITTEST_pi+:generic ==> pi+:FSP.xml'),
True)
979 self.assertEqual(basf2_mva.available(
'UNITTEST_pi+:generic ==> pi+:FSP.xml'),
True)
981 def test_upload(self):
982 particles = get_small_unittest_channels()
983 config = fei.config.FeiConfiguration(monitor=
False, prefix=
'UNITTEST', externTeacher=
'basf2_mva_teacher')
984 x = fei.core.Teacher(particles, config)
985 fei.core.Teacher.create_fake_weightfile(
'TEACHER')
986 self.assertEqual(basf2_mva.available(
'UNITTEST_TEACHER'),
False)
987 r = x.upload(
'TEACHER')
988 self.assertEqual(basf2_mva.available(
'UNITTEST_TEACHER'),
True)
989 self.assertEqual(r, (
'TEACHER.xml',
'UNITTEST_TEACHER'))
991 def test_without_monitoring(self):
992 particles = get_small_unittest_channels()
993 config = fei.config.FeiConfiguration(monitor=
False, prefix=
'UNITTEST', externTeacher=
'basf2_mva_teacher')
994 x = fei.core.Teacher(particles, config)
996 self.assertEqual(basf2_mva.available(
'UNITTEST_pi+:generic ==> pi+:FSP'),
False)
997 self.assertEqual(basf2_mva.available(
'UNITTEST_K+:generic ==> K+:FSP'),
False)
998 self.assertEqual(basf2_mva.available(
'UNITTEST_D0:generic ==> K-:generic pi+:generic'),
False)
999 self.assertEqual(basf2_mva.available(
'UNITTEST_D0:generic ==> pi-:generic pi+:generic'),
False)
1001 x.do_all_trainings()
1003 self.assertEqual(basf2_mva.available(
'UNITTEST_pi+:generic ==> pi+:FSP'),
True)
1004 self.assertEqual(basf2_mva.available(
'UNITTEST_K+:generic ==> K+:FSP'),
False)
1005 self.assertEqual(basf2_mva.available(
'UNITTEST_D0:generic ==> K-:generic pi+:generic'),
True)
1006 self.assertEqual(basf2_mva.available(
'UNITTEST_D0:generic ==> pi-:generic pi+:generic'),
True)
1010 class TestConvertLegacyTraining(unittest.TestCase):
1015 class TestGetPath(unittest.TestCase):
1018 particles = fei.get_unittest_channels()
1020 f = ROOT.TFile(
'mcParticlesCount.root',
'RECREATE')
1023 for pdgnumber
in set([abs(
pdg.from_name(particle.name))
for particle
in particles]):
1024 hist = ROOT.TH1F(f
"NumberOfMCParticlesInEvent__bo{pdgnumber}__bc",
1025 f
"NumberOfMCParticlesInEvent__bo{pdgnumber}__bc", 11, -0.5, 10.5)
1028 f.Write(f
"NumberOfMCParticlesInEvent__bo{pdgnumber}__bc")
1031 if os.path.isfile(
'mcParticlesCount.root'):
1032 os.remove(
'mcParticlesCount.root')
1033 if os.path.isfile(
'Summary.pickle'):
1034 os.remove(
'Summary.pickle')
1036 def test_get_path_default_cache(self):
1037 particles = fei.get_unittest_channels()
1038 config = fei.config.FeiConfiguration(training=
True)
1039 x = fei.core.Teacher(particles, config)
1043 feistate = fei.core.get_path(particles, config)
1044 self.assertEqual(feistate.stage, 0)
1048 config = fei.config.FeiConfiguration(training=
True)
1049 feistate = fei.core.get_path(particles, config)
1050 self.assertEqual(feistate.stage, 1)
1054 config = fei.config.FeiConfiguration(training=
True)
1055 feistate = fei.core.get_path(particles, config)
1056 self.assertEqual(feistate.stage, 1)
1059 fei.core.Teacher.create_fake_weightfile(
'pi+:generic ==> pi+:FSP')
1060 fei.core.Teacher.create_fake_weightfile(
'K+:generic ==> K+:FSP')
1061 fei.core.Teacher.create_fake_weightfile(
'mu+:generic ==> mu+:FSP')
1062 fei.core.Teacher.create_fake_weightfile(
'gamma:generic ==> gamma:FSP')
1063 fei.core.Teacher.create_fake_weightfile(
'gamma:generic ==> gamma:V0')
1067 config = fei.config.FeiConfiguration(training=
True)
1068 feistate = fei.core.get_path(particles, config)
1069 self.assertEqual(feistate.stage, 2)
1073 config = fei.config.FeiConfiguration(training=
True)
1074 feistate = fei.core.get_path(particles, config)
1075 self.assertEqual(feistate.stage, 2)
1078 fei.core.Teacher.create_fake_weightfile(
'pi0:generic ==> gamma:generic gamma:generic')
1082 config = fei.config.FeiConfiguration(training=
True)
1083 feistate = fei.core.get_path(particles, config)
1084 self.assertEqual(feistate.stage, 4)
1087 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> K-:generic pi+:generic')
1088 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> K-:generic pi+:generic pi0:generic')
1089 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> pi-:generic pi+:generic')
1090 fei.core.Teacher.create_fake_weightfile(
'D0:semileptonic ==> K-:generic mu+:generic')
1091 fei.core.Teacher.create_fake_weightfile(
'D0:semileptonic ==> K-:generic pi0:generic mu+:generic')
1095 config = fei.config.FeiConfiguration(training=
True)
1096 feistate = fei.core.get_path(particles, config)
1097 self.assertEqual(feistate.stage, 7)
1101 config = fei.config.FeiConfiguration(cache=0, training=
True)
1102 feistate = fei.core.get_path(particles, config)
1103 self.assertEqual(feistate.stage, 7)
1107 os.remove(
'pi+:generic ==> pi+:FSP.xml')
1108 os.remove(
'K+:generic ==> K+:FSP.xml')
1109 os.remove(
'mu+:generic ==> mu+:FSP.xml')
1110 os.remove(
'gamma:generic ==> gamma:FSP.xml')
1111 os.remove(
'gamma:generic ==> gamma:V0.xml')
1112 os.remove(
'pi0:generic ==> gamma:generic gamma:generic.xml')
1113 os.remove(
'D0:generic ==> K-:generic pi+:generic.xml')
1114 os.remove(
'D0:generic ==> K-:generic pi+:generic pi0:generic.xml')
1115 os.remove(
'D0:generic ==> pi-:generic pi+:generic.xml')
1116 os.remove(
'D0:semileptonic ==> K-:generic mu+:generic.xml')
1117 os.remove(
'D0:semileptonic ==> K-:generic pi0:generic mu+:generic.xml')
1119 config = fei.config.FeiConfiguration(cache=0, training=
False)
1120 feistate = fei.core.get_path(particles, config)
1121 self.assertEqual(feistate.stage, 7)
1123 def test_get_path(self):
1124 particles = fei.get_unittest_channels()
1125 config = fei.config.FeiConfiguration(cache=-1, training=
True)
1126 x = fei.core.Teacher(particles, config)
1130 feistate = fei.core.get_path(particles, config)
1131 self.assertEqual(feistate.stage, 0)
1135 config = fei.config.FeiConfiguration(cache=0, training=
True)
1136 feistate = fei.core.get_path(particles, config)
1137 self.assertEqual(feistate.stage, 1)
1141 config = fei.config.FeiConfiguration(cache=1, training=
True)
1142 feistate = fei.core.get_path(particles, config)
1143 self.assertEqual(feistate.stage, 1)
1146 fei.core.Teacher.create_fake_weightfile(
'pi+:generic ==> pi+:FSP')
1147 fei.core.Teacher.create_fake_weightfile(
'K+:generic ==> K+:FSP')
1148 fei.core.Teacher.create_fake_weightfile(
'mu+:generic ==> mu+:FSP')
1149 fei.core.Teacher.create_fake_weightfile(
'gamma:generic ==> gamma:FSP')
1150 fei.core.Teacher.create_fake_weightfile(
'gamma:generic ==> gamma:V0')
1154 config = fei.config.FeiConfiguration(cache=1, training=
True)
1155 feistate = fei.core.get_path(particles, config)
1156 self.assertEqual(feistate.stage, 2)
1160 config = fei.config.FeiConfiguration(cache=2, training=
True)
1161 feistate = fei.core.get_path(particles, config)
1162 self.assertEqual(feistate.stage, 2)
1167 config = fei.config.FeiConfiguration(cache=4, training=
True)
1168 feistate = fei.core.get_path(particles, config)
1169 self.assertEqual(feistate.stage, 2)
1172 fei.core.Teacher.create_fake_weightfile(
'pi0:generic ==> gamma:generic gamma:generic')
1176 config = fei.config.FeiConfiguration(cache=2, training=
True)
1177 feistate = fei.core.get_path(particles, config)
1178 self.assertEqual(feistate.stage, 4)
1181 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> K-:generic pi+:generic')
1182 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> K-:generic pi+:generic pi0:generic')
1183 fei.core.Teacher.create_fake_weightfile(
'D0:generic ==> pi-:generic pi+:generic')
1184 fei.core.Teacher.create_fake_weightfile(
'D0:semileptonic ==> K-:generic mu+:generic')
1185 fei.core.Teacher.create_fake_weightfile(
'D0:semileptonic ==> K-:generic pi0:generic mu+:generic')
1189 config = fei.config.FeiConfiguration(cache=4, training=
True)
1190 feistate = fei.core.get_path(particles, config)
1191 self.assertEqual(feistate.stage, 7)
1195 config = fei.config.FeiConfiguration(cache=0, training=
True)
1196 feistate = fei.core.get_path(particles, config)
1197 self.assertEqual(feistate.stage, 7)
1201 os.remove(
'pi+:generic ==> pi+:FSP.xml')
1202 os.remove(
'K+:generic ==> K+:FSP.xml')
1203 os.remove(
'mu+:generic ==> mu+:FSP.xml')
1204 os.remove(
'gamma:generic ==> gamma:FSP.xml')
1205 os.remove(
'gamma:generic ==> gamma:V0.xml')
1206 os.remove(
'pi0:generic ==> gamma:generic gamma:generic.xml')
1207 os.remove(
'D0:generic ==> K-:generic pi+:generic.xml')
1208 os.remove(
'D0:generic ==> K-:generic pi+:generic pi0:generic.xml')
1209 os.remove(
'D0:generic ==> pi-:generic pi+:generic.xml')
1210 os.remove(
'D0:semileptonic ==> K-:generic mu+:generic.xml')
1211 os.remove(
'D0:semileptonic ==> K-:generic pi0:generic mu+:generic.xml')
1213 config = fei.config.FeiConfiguration(cache=0, training=
False)
1214 feistate = fei.core.get_path(particles, config)
1215 self.assertEqual(feistate.stage, 7)
1218 if __name__ ==
'__main__':
1221 basf2_mva.loadRootDictionary()
1222 tempdir = tempfile.mkdtemp()
1224 basf2.conditions.testing_payloads = [
'localdb/database.txt']
1226 atexit.register(shutil.rmtree, tempdir)