Belle II Software  light-2212-foldex
treeFit_beam_momentum_constrain.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 
11 import unittest
12 import tempfile
13 import basf2
14 import b2test_utils
15 import modularAnalysis as ma
16 from variables import variables as vm
17 from ROOT import TFile
18 
19 
20 basf2.set_random_seed('aSeed')
21 
22 
23 class TestTreeFits(unittest.TestCase):
24  """The unit test case for TreeFitter"""
25 
26  def testFit(self):
27  """Run the test fit"""
28 
29  testFile = tempfile.NamedTemporaryFile()
30 
31  main = basf2.create_path()
32 
33  ma.inputMdst(b2test_utils.require_file('analysis/tests/150_noBKG_DtoPiNuNu.root'), path=main)
34  ma.fillParticleList('pi+:a', 'pionID > 0.5', path=main)
35  ma.fillParticleList('K+:a', 'kaonID > 0.5', path=main)
36 
37  ma.reconstructDecay(
38  "D-:tag -> K+:a pi-:a pi-:a",
39  cut='1.859 < M < 1.879 and useCMSFrame(p)>2.0',
40  path=main
41  )
42 
43  ma.reconstructDecay(
44  "D+:sig -> pi+:a",
45  '',
46  path=main
47  )
48 
49  ma.reconstructDecay('Z0:rec -> D+:sig D-:tag pi-:a pi+:a', '', path=main)
50  ma.matchMCTruth('Z0:rec', path=main)
51 
52  ma.setBeamConstrainedMomentum(
53  'Z0:rec',
54  '^Z0:rec -> D+:sig D-:tag pi-:a pi+:a',
55  'Z0:rec -> D+:sig D-:tag pi-:a pi+:a',
56  path=main
57  )
58 
59  ma.setBeamConstrainedMomentum(
60  'Z0:rec',
61  'Z0:rec -> ^D+:sig D-:tag pi-:a pi+:a',
62  'Z0:rec -> D+:sig ^D-:tag ^pi-:a ^pi+:a',
63  path=main
64  )
65 
66  conf = 0
67  main.add_module('TreeFitter',
68  particleList='Z0:rec',
69  confidenceLevel=conf,
70  massConstraintList=[],
71  massConstraintListParticlename=[],
72  expertBeamConstraintPDG=23,
73  treatAsInvisible='Z0:rec -> ^D+:sig D-:tag pi-:a pi+:a',
74  ipConstraint=True,
75  updateAllDaughters=True)
76 
77  ma.applyCuts('Z0:rec',
78  "1.6<daughter(0,M)<2.2",
79  path=main
80  )
81 
82  ma.rankByHighest("Z0:rec",
83  "chiProb",
84  numBest=1,
85  path=main)
86 
87  vm.addAlias("signalD", "daughter(0,isSignalAcceptMissingNeutrino)")
88 
89  ntupler = basf2.register_module('VariablesToNtuple')
90  ntupler.param('fileName', testFile.name)
91  ntupler.param('variables', ['chiProb', 'M', 'signalD'])
92  ntupler.param('particleList', 'Z0:rec')
93  main.add_module(ntupler)
94 
95  basf2.process(main)
96 
97  ntuplefile = TFile(testFile.name)
98  ntuple = ntuplefile.Get('ntuple')
99 
100  self.assertFalse(ntuple.GetEntries() == 0, "Ntuple is empty.")
101 
102  allBkg = ntuple.GetEntries("signalD == 0")
103  allSig = ntuple.GetEntries("signalD > 0")
104 
105  truePositives = ntuple.GetEntries("(chiProb > 0) && (signalD > 0)")
106  falsePositives = ntuple.GetEntries("(chiProb > 0) && (signalD == 0)")
107 
108  mustBeZero = ntuple.GetEntries(f"(chiProb < {conf})")
109 
110  print(f"True fit survivors: {truePositives} out of {allSig} true candidates")
111  print(f"False fit survivors: {falsePositives} out of {allBkg} false candidates")
112 
113  self.assertFalse(truePositives == 0, "No signal survived the fit.")
114 
115  self.assertTrue(falsePositives < 1, "Background rejection too small.")
116 
117  self.assertTrue(truePositives > 8, "Signal rejection too high")
118  self.assertFalse(mustBeZero, f"We should have dropped all candidates with confidence level less than {conf}.")
119 
120  print("Test passed, cleaning up.")
121 
122 
123 if __name__ == '__main__':
125  unittest.main()
def require_file(filename, data_type="", py_case=None)
Definition: __init__.py:54
def clean_working_directory()
Definition: __init__.py:185