Belle II Software development
test_b2file-mix.py
1
8
9'''
10Test the tool b2file-mix and make sure it works.
11'''
12
13import contextlib
14import subprocess
15
16import basf2 as b2
17import b2test_utils as b2tu
18
19
20class PopulateEvents(b2.Module):
21 '''Class for populating the events with some random numbers.'''
22
23 def initialize(self):
24 '''Initialize.'''
25 import ROOT
26
27 self.evt = ROOT.Belle2.PyStoreObj('EventMetaData')
28 self.evt.isRequired()
29
30 def event(self):
31 '''Event.'''
32 import ROOT
33 # Let's store a random number in the slot for the generator weight
34 self.evt.setGeneratedWeight(ROOT.gRandom.Rndm())
35
36
37def path_for_test_file(events, output_name, seed):
38 b2.set_random_seed(seed)
39 main = b2.Path()
40 main.add_module('EventInfoSetter', expList=0, runList=0, evtNumList=events)
41 main.add_module(PopulateEvents())
42 main.add_module('RootOutput', outputFileName=output_name)
43 b2.process(main)
44
45
46@contextlib.contextmanager
47def open_root(filename, mode='READ'):
48 # Context manager for handling root files
49 import ROOT
50 f = ROOT.TFile.Open(filename, mode)
51 try:
52 yield f
53 finally:
54 if f:
55 f.Close()
56
57
58if __name__ == '__main__':
59
60 with b2tu.clean_working_directory():
61
62 events = 1000
63 file_name_a = 'test_a.root'
64 file_name_b = 'test_b.root'
65 file_name_ab = 'test_ab.root'
66
67 # Create a test file in the current directory
68 b2tu.run_in_subprocess(target=path_for_test_file, events=events, output_name=file_name_a, seed='aaa')
69 b2tu.run_in_subprocess(target=path_for_test_file, events=events, output_name=file_name_b, seed='bbb')
70 subprocess.check_call(['b2file-merge', file_name_ab, file_name_a, file_name_b])
71
72 # Now mix the file and run a simple check
73 subprocess.check_call(['b2file-mix', file_name_a, '-o', 'test1.root'])
74 metadata = b2.get_file_metadata('test1.root')
75 assert (metadata.getNEvents() == events)
76
77 # Mix again the file, but keeping less events
78 subprocess.check_call(['b2file-mix', file_name_a, '-o', 'test2.root', '-n', '100'])
79 metadata = b2.get_file_metadata('test2.root')
80 assert (metadata.getNEvents() == 100)
81
82 # Mix again the file, but changing the exp. number
83 subprocess.check_call(['b2file-mix', file_name_a, '-o', 'test3.root', '--exp', '114'])
84 metadata = b2.get_file_metadata('test3.root')
85 assert (metadata.getExperimentLow() == 114)
86
87 # Mix two files, this time passing the seed. Few times: twice with the same seed and once with a different one.
88 subprocess.check_call(['b2file-mix', file_name_a, file_name_b, '-o', 'test4.root', '--seed', 'abc'])
89 metadata = b2.get_file_metadata('test4.root')
90 assert (metadata.getRandomSeed() == 'abc')
91 subprocess.check_call(['b2file-mix', file_name_a, file_name_b, '-o', 'test5.root', '--seed', 'abc'])
92 subprocess.check_call(['b2file-mix', file_name_a, file_name_b, '-o', 'test6.root', '--seed', 'def'])
93
94 # Compare the content of test4, test5 and test6 and make sure it's different from test_ab.
95 # Then, test4 and test5 must be identical, while test6 must be different thant test4 and test5.
96 # Since b2file-mix keep the relative ordering between the events in a file: For checking test6
97 # is different, let's count how many times the entries differ and ask this number is large enough.
98 # Because of the same reason, let's skip the first and last few events.
99 counts = 0
100 with open_root(file_name_ab) as fileab:
101 treeab = fileab.Get('tree')
102 with open_root('test4.root') as file4:
103 tree4 = file4.Get('tree')
104 with open_root('test5.root') as file5:
105 tree5 = file5.Get('tree')
106 with open_root('test6.root') as file6:
107 tree6 = file6.Get('tree')
108 for i, (eventab, event4, event5, event6) in enumerate(zip(treeab, tree4, tree5, tree6)):
109 if i < 10 or i > 1990:
110 continue
111 weightab = eventab.EventMetaData.getGeneratedWeight()
112 weight4 = event4.EventMetaData.getGeneratedWeight()
113 weight5 = event5.EventMetaData.getGeneratedWeight()
114 weight6 = event6.EventMetaData.getGeneratedWeight()
115 assert (weightab != weight4)
116 assert (weightab != weight6)
117 assert (weight4 == weight5)
118 counts += (weight4 != weight6)
119 # It should be above 1900: let's be generous here.
120 assert (counts > 1800)