Belle II Software  release-05-01-25
root_input.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 import os
5 import basf2
6 from ROOT import Belle2
7 from b2test_utils import safe_process, clean_working_directory
8 
9 basf2.conditions.disable_globaltag_replay()
10 basf2.set_random_seed("something important")
11 # make sure FATAL messages don't have the function signature as this makes
12 # problems with clang printing namespaces differently
13 basf2.logging.set_info(basf2.LogLevel.FATAL, basf2.logging.get_info(basf2.LogLevel.ERROR))
14 basf2.logging.enable_summary(False)
15 
16 
17 class NoopModule(basf2.Module):
18  """Doesn't do anything."""
19 
20 
21 with clean_working_directory():
22  for filename in ["root_input.root", "chaintest_empty.root", "chaintest_1.root", "chaintest_2.root"]:
23  os.symlink(basf2.find_file(f'framework/tests/{filename}'), filename)
24 
25  main = basf2.Path()
26  # not used for anything, just checking wether the master module
27  # can be found if it's not the first module in the path.
28  main.add_module(NoopModule())
29  # load all branches, minus PXDClusters (relations with PXDClusters are automatically excluded)
30  # (yes, we also added PXDClusters in branchNames, to check if it's overridden by excludeBranchNames)
31  input_module = main.add_module("RootInput", inputFileName="root_input.root",
32  branchNames=['EventMetaData', 'PXDDigits', 'PXDTrueHits', 'PXDClusters'],
33  excludeBranchNames=['PXDClusters'], skipNEvents=1, logLevel=basf2.LogLevel.WARNING)
34  # print event information and datastore contents
35  main.add_module("EventInfoPrinter")
36  main.add_module("PrintCollections", printForEvent=0)
37 
38  # Process events
39  assert safe_process(main) == 0
40 
41  # Test restricting the number of events per file
42  # This issues a warning because a part of the events is out of range
43  input_module.param('entrySequences', ["0,3:10,23"])
44  assert safe_process(main) == 0
45 
46  # Test starting directly with a given event. There will be a fatal error if the
47  # event is not found in the file so let's call process() in a child process to
48  # not be aborted
49  for evtNo in range(1, 6):
50  main = basf2.Path()
51  main.add_module("RootInput", inputFileName='root_input.root',
52  branchNames=["EventMetaData"], skipToEvent=[0, 1, evtNo], logLevel=basf2.LogLevel.WARNING)
53  main.add_module("EventInfoPrinter")
54  safe_process(main)
55 
56  # Test eventSequences in detail
57  main = basf2.Path()
58  input_module = main.add_module('RootInput', inputFileNames=['chaintest_1.root', 'chaintest_2.root'],
59  logLevel=basf2.LogLevel.WARNING)
60  # The first file contains the following event numbers (in this order)
61  # 2, 6, 5, 9, 10, 11, 8, 12, 0, 13, 15, 16
62  # We select more event than the file contains, to check if it works anyway
63  # The second file contains the following event numbers (in this order)
64  # 7, 6, 3, 8, 9, 12, 4, 11, 10, 16, 13, 17, 18, 14, 15
65  input_module.param('entrySequences', ['0,3:4,10:100', '1:2,4,12:13'])
66 
67  expected_event_numbers = [2, 9, 10, 15, 16, 6, 3, 9, 18, 14]
68  processed_event_numbers = []
69 
70  class TestingModule(basf2.Module):
71  """
72  Test module which writes out the processed event numbers
73  into the global processed_event_numbers list
74  """
75 
76  def event(self):
77  """
78  Called for each event
79  """
80  global processed_event_numbers
81  emd = Belle2.PyStoreObj('EventMetaData')
82  processed_event_numbers.append(emd.obj().getEvent())
83 
84  def terminate(self):
85  """
86  perform check
87  """
88  # We only want to do the check if we actually execute the process() but
89  # since this script is called from basf2_args with --dry-run this is not
90  # always the case
91  assert expected_event_numbers == processed_event_numbers
92 
93  main.add_module(TestingModule())
94  assert safe_process(main) == 0
95 
96  basf2.set_random_seed("something important")
97  # make sure FATAL messages don't have the function signature as this makes
98  # problems with clang printing namespaces differently
99  basf2.logging.set_info(basf2.LogLevel.FATAL, basf2.logging.get_info(basf2.LogLevel.ERROR))
100 
101  # Test eventSequences parameter ':' in detail
102  main = basf2.Path()
103  input_module = main.add_module('RootInput', inputFileNames=['chaintest_1.root', 'chaintest_2.root'],
104  logLevel=basf2.LogLevel.WARNING)
105  # The first file contains the following event numbers (in this order)
106  # 2, 6, 5, 9, 10, 11, 8, 12, 0, 13, 15, 16
107  # We select the complete first file.
108  # The second file contains the following event numbers (in this order)
109  # 7, 6, 3, 8, 9, 12, 4, 11, 10, 16, 13, 17, 18, 14, 15
110  input_module.param('entrySequences', [':', '1:2,4,12:13'])
111 
112  expected_event_numbers = [2, 6, 5, 9, 10, 11, 8, 12, 0, 13, 15, 16, 6, 3, 9, 18, 14]
113  processed_event_numbers = []
114 
115  main.add_module(TestingModule())
116 
117  assert safe_process(main) == 0
118 
119  full_list = ["chaintest_empty.root", "chaintest_1.root", "chaintest_2.root", "chaintest_1.root"]
120  for i in range(len(full_list)):
121  main = basf2.Path()
122  main.add_module('RootInput', inputFileNames=full_list[:i + 1])
123  main.add_module("EventInfoPrinter")
124  safe_process(main)
root_input.TestingModule.event
def event(self)
Definition: root_input.py:76
Belle2::PyStoreObj
a (simplified) python wrapper for StoreObjPtr.
Definition: PyStoreObj.h:69
root_input.TestingModule
Definition: root_input.py:70
root_input.TestingModule.terminate
def terminate(self)
Definition: root_input.py:84
root_input.NoopModule
Definition: root_input.py:17