Belle II Software development
minimal.py
1#!/usr/bin/env python3
2
3
10
11
12import basf2
13
14from tracking.run import utilities
15
16import argparse
17import logging
18from ROOT import Belle2
19
20
21def get_logger():
22 return logging.getLogger(__name__)
23
24# Provides a commandline interface to specify some parameters to an associated basf2 path execution
25
26
28 """Configure for a bare-bones basf2 job"""
29
30 # Declarative section which can be redefined in a subclass
31
32
33 description = "Empty execution of basf2"
34
35 def __init__(self, **kwds):
36 """Constructor"""
37 if kwds:
38 raise ValueError("Received_unknown unknown argument")
39
40 @property
41 def name(self):
42 """provide name of this object"""
43 return self.__class__.__name__
44
46 """Configure basf2 job script from command-line arguments then run it"""
48 self.execute()
49
50 def execute(self):
51 """Create the basf2 path then run the job"""
52 # Create path and run #
53
54 path = self.create_path()
55 self.adjust_path(path)
56 self.run(path)
57
58 def run(self, path):
59 """Process the basf2 path"""
60 # Run basf2 module path #
61
62 get_logger().info('Start processing')
63 basf2.print_path(path)
64 basf2.process(path)
65 get_logger().info("\n%s", str(basf2.statistics))
66
68 """Convert the command-line arguments to a basf2 job script"""
69 argument_parser = self.create_argument_parser()
70 arguments = argument_parser.parse_args()
71 self.configure(arguments)
72
73 def configure(self, arguments):
74 """Save the command-line arguments as key-value pairs"""
75 # Simply translate the arguments that have
76 # the same name as valid instance arguments
77 for (key, value) in list(vars(arguments).items()):
78 if value is None:
79 continue
80 if hasattr(self, key):
81 get_logger().info("Setting %s to %s", key, value)
82 setattr(self, key, value)
83
84 def create_argument_parser(self, **kwds):
85 """Parse the command-line arguments to a basf2 job script"""
86 argument_parser = utilities.ArgumentParser(description=self.description, **kwds)
87 return argument_parser
88
89 def create_path(self):
90 """Create a new basf2 path"""
91 path = basf2.create_path()
92 return path
93
94 def adjust_path(self, path):
95 """Hook that gives the opportunity to check the path for consistency before processing it"""
96
97# Minimal run stub defining some general parameters
98
99
100class MinimalRun(EmptyRun):
101 """Configure for a minimal basf2 job"""
102
103
104 description = "Minimally populated execution of basf2"
105
106 # Declarative section which can be redefined in a subclass
107
108
109 allow_input = True
110
111 n_events = 10000
112
113 root_input_file = None
114
115 random_seed = None
116
117 n_processes = 0
118
119 n_events_to_skip = 0
120
121 def create_argument_parser(self, **kwds):
122 """Convert command-line arguments to basf2 argument list"""
123 argument_parser = super().create_argument_parser(**kwds)
124 master_argument_group = argument_parser.add_argument_group("Master arguments")
125
126 if self.allow_input:
127 master_argument_group.add_argument(
128 '-i',
129 '--input',
130 default=argparse.SUPPRESS,
131 dest='root_input_file',
132 help='File path to the ROOT file from which the simulated events shall be loaded.'
133 )
134
135 master_argument_group.add_argument(
136 '-n',
137 '--events',
138 dest='n_events',
139 default=self.n_events,
140 type=int,
141 help='Number of events to be generated',
142 )
143
144 master_argument_group.add_argument(
145 '-r',
146 '--random-seed',
147 dest='random_seed',
148 default=argparse.SUPPRESS,
149 type=str,
150 help='The random number generator seed to be set before the processing starts.',
151 )
152
153 master_argument_group.add_argument(
154 '-p',
155 '--processes',
156 dest='n_processes',
157 default=argparse.SUPPRESS,
158 type=int,
159 help='The number of parallel processes to be used for processing.',
160 )
161
162 master_argument_group.add_argument(
163 '--n-events-to-skip',
164 dest='n_events_to_skip',
165 default=argparse.SUPPRESS,
166 type=int,
167 help='The number of events to skip',
168 )
169
170 return argument_parser
171
172 def create_path(self):
173 """Create and configure the basf2 path"""
174 path = super().create_path()
175
176 if self.random_seed is not None:
177 basf2.set_random_seed(self.random_seed)
178
179 environment = Belle2.Environment.Instance()
180 environment.setNumberEventsOverride(self.n_events)
181
182 # If there is no input file is the EventInfoSetter as master module
183 if not self.root_input_file:
184 # Master module: EventInfoSetter
185 path.add_module('EventInfoSetter',
186 evtNumList=[self.n_events],
187 runList=[1],
188 expList=[0],
189 skipNEvents=self.n_events_to_skip
190 )
191
192 else:
193 # Master module: RootInput
194 path.add_module('RootInput',
195 inputFileName=self.root_input_file,
196 skipNEvents=self.n_events_to_skip)
197
198 # Progress module
199 path.add_module('Progress')
200
201 if self.n_processes:
202 environment = Belle2.Environment.Instance()
203 environment.setNumberProcessesOverride(self.n_processes)
204
205 return path
static Environment & Instance()
Static method to get a reference to the Environment instance.
Definition: Environment.cc:28
def create_argument_parser(self, **kwds)
Definition: minimal.py:84
def run(self, path)
Definition: minimal.py:58
def configure(self, arguments)
Definition: minimal.py:73
def configure_from_commandline(self)
Definition: minimal.py:67
def __init__(self, **kwds)
Definition: minimal.py:35
str description
Description of the run setup to be displayed on command line.
Definition: minimal.py:33
def configure_and_execute_from_commandline(self)
Definition: minimal.py:45
def adjust_path(self, path)
Definition: minimal.py:94
def create_argument_parser(self, **kwds)
Definition: minimal.py:121
int n_events
By default, process 10000 events.
Definition: minimal.py:111
None random_seed
By default, the random-number seed is unassigned.
Definition: minimal.py:115
int n_events_to_skip
By default, do not skip any events at the start of the input ROOT TFile.
Definition: minimal.py:119
int n_processes
By default, no parallel processing.
Definition: minimal.py:117
bool allow_input
By default, this basf2 job can read events from an input ROOT TFile.
Definition: minimal.py:109
None root_input_file
By default, there is no input ROOT TFile.
Definition: minimal.py:113