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