Belle II Software development
Path Class Reference

Implements a path consisting of Module and/or Path objects. More...

#include <Path.h>

Inheritance diagram for Path:
PathElement

Public Member Functions

 Path ()
 Constructor.
 
 ~Path ()
 Destructor.
 
void addModule (const std::shared_ptr< Module > &module)
 Adds a module to the path.
 
bool isEmpty () const
 Returns true if this Path doesn't contain any elements.
 
std::list< std::shared_ptr< Module > > getModules () const override
 Returns a list of the modules in this path.
 
std::list< std::shared_ptr< Module > > buildModulePathList (bool unique=true) const
 Builds a list of all modules which could be executed during the data processing.
 
void putModules (const std::list< std::shared_ptr< Module > > &mlist)
 Replaces all Modules and sub-Paths with the specified Module list.
 
bool contains (const std::string &moduleType) const
 Does this Path contain a module of the given type?
 
std::shared_ptr< PathElementclone () const override
 Create an independent copy of this path, recreating all contained modules with the same parameters.
 
void addPath (const PathPtr &path)
 See 'pydoc3 basf2.Path'.
 
void forEach (const std::string &loopObjectName, const std::string &arrayName, PathPtr path)
 See 'pydoc3 basf2.Path'.
 
void doWhile (PathPtr path, const std::string &condition, unsigned int maxIterations)
 See 'pydoc3 basf2.Path'.
 
void addIndependentPath (const PathPtr &independent_path, std::string ds_ID, const boost::python::list &merge_back)
 See 'pydoc3 basf2.Path'.
 
void addIndependentMergePath (const PathPtr &independent_path, std::string ds_ID, const boost::python::list &merge_back, std::string consistency_check, bool event_mixing, bool mergeSameFile)
 See 'pydoc3 basf2.Path'.
 
std::string getPathString () const override
 return a string of the form [module a -> module b -> [another path]]
 

Static Public Member Functions

static void exposePythonAPI ()
 Exposes methods of the Path class to Python.
 

Private Attributes

std::list< std::shared_ptr< PathElement > > m_elements
 The list of path elements (Modules and sub-Paths)
 

Friends

class PathIterator
 

Detailed Description

Implements a path consisting of Module and/or Path objects.

The modules are arranged in a linear order.

Definition at line 38 of file Path.h.

Member Function Documentation

◆ addIndependentMergePath()

void addIndependentMergePath ( const PathPtr independent_path,
std::string  ds_ID,
const boost::python::list &  merge_back,
std::string  consistency_check,
bool  event_mixing,
bool  mergeSameFile 
)

See 'pydoc3 basf2.Path'.

Definition at line 135 of file Path.cc.

137{
138 if (ds_ID.empty()) {
139 static int dscount = 1;
140 ds_ID = "DS " + std::to_string(dscount++);
141 }
142 auto mergeBack = PyObjConvUtils::convertPythonObject(merge_back, std::vector<std::string>());
143 ModulePtr switchStart = ModuleManager::Instance().registerModule("MergeDataStore");
144 static_cast<MergeDataStoreModule&>(*switchStart).init(ds_ID, true, mergeBack);
145 ModulePtr switchEnd = ModuleManager::Instance().registerModule("MergeDataStore");
146 static_cast<MergeDataStoreModule&>(*switchEnd).init("", false, mergeBack);
147 switchStart->setName("MergeDataStore ('' -> '" + ds_ID + "')");
148 switchEnd->setName("MergeDataStore ('' <- '" + ds_ID + "')");
149
150 ModulePtr fillConsistencyInfo = ModuleManager::Instance().registerModule("CreateConsistencyInfo");
151 static_cast<CreateConsistencyInfoModule&>(*fillConsistencyInfo).init(consistency_check, event_mixing);
152
153 ModulePtr steerInput = ModuleManager::Instance().registerModule("SteerRootInput");
154 static_cast<SteerRootInputModule&>(*steerInput).init(event_mixing, merge_same_file);
155
156 //set c_ParallelProcessingCertified flag if _all_ modules have it set
159 switchStart->setPropertyFlags(flag);
160 switchEnd->setPropertyFlags(flag);
161 }
162
163 // switch to the second (empty) data store
164 addModule(switchStart);
165 // execute independent path
166 addPath(independent_path);
167 // do the merging
168 addModule(switchEnd);
169 // check events to be merged is consistent (typically charge)
170 addModule(fillConsistencyInfo);
171 // decide which events have to be processed next
172 addModule(steerInput);
173 // the current combination of events might not be sensible or unphysical
174 // in this case end path and try next combination
175 steerInput->if_value("==0", std::make_shared<Path>());
176}
If you want to merge two events with the 'MergeDataStoreModule', it might be necessary to make sure t...
void init(const std::string &option, bool eventMixing)
setter for Path.
Internal module used by Path.add_independent_merge_path().
void init(const std::string &to, bool doCopy, const std::vector< std::string > &mergeBack)
setter for Path.
std::shared_ptr< Module > registerModule(const std::string &moduleName, std::string sharedLibPath="") noexcept(false)
Creates an instance of a module and registers it to the ModuleManager.
static ModuleManager & Instance()
Exception is thrown if the requested module could not be created by the ModuleManager.
static bool allModulesHaveFlag(const std::list< std::shared_ptr< Module > > &list, unsigned int flag)
Returns true if and only if all modules in list have the given flag (or list is empty).
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
std::list< std::shared_ptr< Module > > buildModulePathList(bool unique=true) const
Builds a list of all modules which could be executed during the data processing.
Definition: Path.cc:67
void addPath(const PathPtr &path)
See 'pydoc3 basf2.Path'.
Definition: Path.cc:37
void addModule(const std::shared_ptr< Module > &module)
Adds a module to the path.
Definition: Path.cc:32
Internal module used by Path.add_independent_merge_path().
void init(bool eventMixing, bool mergeSameFile)
setter for Path.
std::shared_ptr< Module > ModulePtr
Defines a pointer to a module object as a boost shared pointer.
Definition: Module.h:43
Scalar convertPythonObject(const boost::python::object &pyObject, Scalar)
Convert from Python to given type.

◆ addIndependentPath()

void addIndependentPath ( const PathPtr independent_path,
std::string  ds_ID,
const boost::python::list &  merge_back 
)

See 'pydoc3 basf2.Path'.

Definition at line 109 of file Path.cc.

110{
111 if (ds_ID.empty()) {
112 static int dscount = 1;
113 ds_ID = "DS " + std::to_string(dscount++);
114 }
115 auto mergeBack = PyObjConvUtils::convertPythonObject(merge_back, std::vector<std::string>());
116 ModulePtr switchStart = ModuleManager::Instance().registerModule("SwitchDataStore");
117 static_cast<SwitchDataStoreModule&>(*switchStart).init(ds_ID, true, mergeBack);
118 ModulePtr switchEnd = ModuleManager::Instance().registerModule("SwitchDataStore");
119 static_cast<SwitchDataStoreModule&>(*switchEnd).init("", false, mergeBack);
120 switchStart->setName("SwitchDataStore ('' -> '" + ds_ID + "')");
121 switchEnd->setName("SwitchDataStore ('' <- '" + ds_ID + "')");
122
123 //set c_ParallelProcessingCertified flag if _all_ modules have it set
126 switchStart->setPropertyFlags(flag);
127 switchEnd->setPropertyFlags(flag);
128 }
129
130 addModule(switchStart);
131 addPath(independent_path);
132 addModule(switchEnd);
133}
Internal module used by Path.add_independent_path().
void init(const std::string &to, bool doCopy, const std::vector< std::string > &mergeBack)
setter for Path.

◆ addModule()

void addModule ( const std::shared_ptr< Module > &  module)

Adds a module to the path.

The module is added to the path by inserting it to the end of the list of modules.

See 'pydoc3 basf2.Path' for the complete documentation.

Parameters
moduleModule that should be added to the path.

Definition at line 32 of file Path.cc.

33{
34 m_elements.push_back(module);
35}
std::list< std::shared_ptr< PathElement > > m_elements
The list of path elements (Modules and sub-Paths)
Definition: Path.h:137

◆ addPath()

void addPath ( const PathPtr path)

See 'pydoc3 basf2.Path'.

Definition at line 37 of file Path.cc.

38{
39 if (path.get() == this) {
40 B2FATAL("Attempting to add a path to itself!");
41 }
42 m_elements.push_back(path);
43}

◆ buildModulePathList()

ModulePtrList buildModulePathList ( bool  unique = true) const

Builds a list of all modules which could be executed during the data processing.

The method starts with the current path, iterates over the modules in the path and follows recursively module conditions to make sure the final list contains all modules which could be executed while preserving their correct order.

Parameters
uniqueIf true, the list will be unique.
Returns
A list containing all modules which could be executed during the data processing.

Definition at line 67 of file Path.cc.

68{
69 ModulePtrList modList;
70 for (const ModulePtr& module : getModules()) {
71 if (!unique or find(modList.begin(), modList.end(), module) == modList.end()) {
72 modList.push_back(module);
73
74 //If the module has a condition, call the method recursively
75 if (module->hasCondition()) {
76 for (const auto& conditionPath : module->getAllConditionPaths()) {
77 // Avoid loops in path conditions
78 if (conditionPath.get() == this) B2FATAL("Found recursion in conditional path");
79 const std::list<ModulePtr>& modulesInElem = conditionPath->buildModulePathList(unique);
80 modList.insert(modList.end(), modulesInElem.begin(), modulesInElem.end());
81 }
82 }
83 }
84 }
85
86 return modList;
87}
std::list< std::shared_ptr< Module > > getModules() const override
Returns a list of the modules in this path.
Definition: Path.cc:50
std::list< ModulePtr > ModulePtrList
Defines a std::list of shared module pointers.
Definition: Module.h:584

◆ clone()

std::shared_ptr< PathElement > clone ( ) const
overridevirtual

Create an independent copy of this path, recreating all contained modules with the same parameters.

Note that parameters are shared, so changing them on a module in the cloned path will also affect the module in the original path.

Implements PathElement.

Definition at line 186 of file Path.cc.

187{
188 PathPtr path(new Path);
189 for (const auto& elem : m_elements) {
190 const auto* m = dynamic_cast<const Module*>(elem.get());
191 if (m and m->getType() == "PyModule") {
192 //B2WARNING("Python module " << m->getName() << " encountered, please make sure it correctly reinitialises itself to ensure multiple process() calls work.");
193 path->addModule(std::static_pointer_cast<Module>(elem));
194 } else {
195 path->m_elements.push_back(elem->clone());
196 }
197 }
198 return path;
199}
Base class for Modules.
Definition: Module.h:72
Implements a path consisting of Module and/or Path objects.
Definition: Path.h:38
std::shared_ptr< Path > PathPtr
Defines a pointer to a path object as a boost shared pointer.
Definition: Path.h:35

◆ contains()

bool contains ( const std::string &  moduleType) const

Does this Path contain a module of the given type?

Useable in Python via '"ModuleType" in path' syntax.

Definition at line 178 of file Path.cc.

179{
180 const std::list<ModulePtr>& modules = getModules();
181
182 auto sameTypeFunc = [moduleType](const ModulePtr & m) -> bool { return m->getType() == moduleType; };
183 return std::find_if(modules.begin(), modules.end(), sameTypeFunc) != modules.end();
184}

◆ doWhile()

void doWhile ( PathPtr  path,
const std::string &  condition,
unsigned int  maxIterations 
)

See 'pydoc3 basf2.Path'.

Definition at line 102 of file Path.cc.

103{
104 ModulePtr module = ModuleManager::Instance().registerModule("SubEvent");
105 static_cast<SubEventModule&>(*module).initSubLoop(std::move(path), condition, maxIterations);
106 addModule(module);
107}
Framework-internal module that implements the functionality of Path::forEach() as well as Path::doWhi...
void initSubLoop(std::shared_ptr< Path > path, const std::string &condition, unsigned int maxIterations)
ised by Path::doWhile() to actually set parameters

◆ exposePythonAPI()

void exposePythonAPI ( )
static

Exposes methods of the Path class to Python.

Definition at line 238 of file Path.cc.

239{
240 docstring_options options(true, false, false); //userdef, py sigs, c++ sigs
241 using bparg = boost::python::arg;
242
243 class_<Path>("Path",
244 R"(Implements a path consisting of Module and/or Path objects (arranged in a linear order).
245
246.. seealso:: :func:`basf2.process`)")
247 .def("__str__", &Path::getPathString)
248 .def("_add_module_object", &Path::addModule) // actual add_module() is found in basf2.py
249 .def("add_path", &Path::addPath, args("path"), R"(add_path(path)
250
251Insert another path at the end of this one.
252For example,
253
254 >>> path.add_module('A')
255 >>> path.add_path(otherPath)
256 >>> path.add_module('B')
257
258would create a path [ A -> [ contents of otherPath ] -> B ].)
259
260Parameters:
261 path (Path): path to add to this path)")
262 .def("modules", &_getModulesPython, R"(modules()
263
264Returns an ordered list of all modules in this path.)")
265 .def("for_each", &Path::forEach, R"(for_each(loop_object_name, array_name, path)
266
267Similar to `add_path()`, this will
268execute the given ``path`` at the current position, but in each event it will
269execute it once for each object in the given StoreArray ``arrayName``. It will
270create a StoreObject named ``loop_object_name`` of same type as array which will
271point to each element in turn for each execution.
272
273This has the effect of calling the ``event()`` methods of modules in ``path``
274for each entry in ``arrayName``.
275
276The main use case is to use it after using the `RestOfEventBuilder` on a
277``ParticeList``, where you can use this feature to perform actions on only a part
278of the event for a given list of candidates:
279
280 >>> path.for_each('RestOfEvent', 'RestOfEvents', roe_path)
281
282You can read this as
283
284 "for each ``RestOfEvent`` in the array of "RestOfEvents", execute ``roe_path``"
285
286For example, if 'RestOfEvents' contains two elements then ``roe_path`` will be
287executed twice and during the execution a StoreObjectPtr 'RestOfEvent' will be
288available, which will point to the first element in the first execution, and
289the second element in the second execution.
290
291.. seealso::
292 A working example of this `for_each` RestOfEvent is to build a veto against
293 photons from :math:`\pi^0\to\gamma\gamma`. It is described in `HowToVeto`.
294
295.. note:: This feature is used by both the `FlavorTagger` and :ref:`FullEventInterpretation` algorithms.
296
297Changes to existing arrays / objects will be available to all modules after the
298`for_each()`, including those made to the loop object itself (it will simply modify
299the i'th item in the array looped over.)
300
301StoreArrays / StoreObjects (of event durability) *created* inside the loop will
302be removed at the end of each iteration. So if you create a new particle list
303inside a `for_each()` path execution the particle list will not exist for the
304next iteration or after the `for_each()` is complete.
305
306Parameters:
307 loop_object_name (str): The name of the object in the datastore during each execution
308 array_name (str): The name of the StoreArray to loop over where the i-th
309 element will be available as ``loop_object_name`` during the i-th execution
310 of ``path``
311 path (basf2.Path): The path to execute for each element in ``array_name``)",
312 args("loop_object_name", "array_name", "path"))
313 .def("do_while", &Path::doWhile, R"(do_while(path, condition='<1', max_iterations=10000)
314
315Similar to `add_path()` this will execute a path at the current position but it
316will repeat execution of this path as long as the return value of the last
317module in the path fulfills the given ``condition``.
318
319This is useful for event generation with special cuts like inclusive particle generation.
320
321See Also:
322 `Module.if_value` for an explanation of the condition expression.
323
324Parameters:
325 path (basf2.Path): sub path to execute repeatedly
326 condition (str): condition on the return value of the last module in ``path``.
327 The execution will be repeated as long as this condition is fulfilled.
328 max_iterations (int): Maximum number of iterations per event. If this number is exceeded
329 the execution is aborted.
330 )", (bparg("path"), bparg("condition") = "<1", bparg("max_iterations") = 10000))
331 .def("_add_independent_path", &Path::addIndependentPath)
332 .def("_add_independent_merge_path", &Path::addIndependentMergePath)
333 .def("__contains__", &Path::contains, R"(Does this Path contain a module of the given type?
334
335 >>> path = basf2.Path()
336 >>> 'RootInput' in path
337 False
338 >>> path.add_module('RootInput')
339 >>> 'RootInput' in path
340 True)", args("moduleType"))
341 ;
342
void addIndependentMergePath(const PathPtr &independent_path, std::string ds_ID, const boost::python::list &merge_back, std::string consistency_check, bool event_mixing, bool mergeSameFile)
See 'pydoc3 basf2.Path'.
Definition: Path.cc:135
void forEach(const std::string &loopObjectName, const std::string &arrayName, PathPtr path)
See 'pydoc3 basf2.Path'.
Definition: Path.cc:95
void doWhile(PathPtr path, const std::string &condition, unsigned int maxIterations)
See 'pydoc3 basf2.Path'.
Definition: Path.cc:102
void addIndependentPath(const PathPtr &independent_path, std::string ds_ID, const boost::python::list &merge_back)
See 'pydoc3 basf2.Path'.
Definition: Path.cc:109
bool contains(const std::string &moduleType) const
Does this Path contain a module of the given type?
Definition: Path.cc:178
std::string getPathString() const override
return a string of the form [module a -> module b -> [another path]]
Definition: Path.cc:206

◆ forEach()

void forEach ( const std::string &  loopObjectName,
const std::string &  arrayName,
PathPtr  path 
)

See 'pydoc3 basf2.Path'.

Definition at line 95 of file Path.cc.

96{
98 static_cast<SubEventModule&>(*module).initSubEvent(loopObjectName, arrayName, std::move(path));
99 addModule(module);
100}
void initSubEvent(const std::string &objectName, const std::string &loopOver, std::shared_ptr< Path > path)
used by Path::forEach() to actually set parameters.

◆ getModules()

std::list< ModulePtr > getModules ( ) const
overridevirtual

Returns a list of the modules in this path.

(Recursively searches sub-paths)

Implements PathElement.

Definition at line 50 of file Path.cc.

51{
52 std::list<ModulePtr> modules;
53 for (const std::shared_ptr<PathElement>& elem : m_elements) {
54 if (dynamic_cast<Module*>(elem.get()) != nullptr) {
55 //this path element is a Module, create a ModulePtr that shares ownership with 'elem'
56 modules.push_back(std::static_pointer_cast<Module>(elem));
57 } else {
58 //some PathElement with submodules
59 const std::list<ModulePtr>& modulesInElem = elem->getModules();
60 modules.insert(modules.end(), modulesInElem.begin(), modulesInElem.end());
61 }
62 }
63 return modules;
64}

◆ getPathString()

std::string getPathString ( ) const
overridevirtual

return a string of the form [module a -> module b -> [another path]]

can be used to 'print' a path in a steering file.

Implements PathElement.

Definition at line 206 of file Path.cc.

207{
208 std::string out("");
209 bool firstElem = true;
210 for (const std::shared_ptr<PathElement>& elem : m_elements) {
211 if (!firstElem) {
212 out += " -> ";
213 } else {
214 firstElem = false;
215 }
216
217 out += elem->getPathString();
218 }
219 return "[" + out + "]";
220}

◆ isEmpty()

bool isEmpty ( ) const

Returns true if this Path doesn't contain any elements.

Definition at line 45 of file Path.cc.

46{
47 return m_elements.empty();
48}

◆ putModules()

void putModules ( const std::list< std::shared_ptr< Module > > &  mlist)

Replaces all Modules and sub-Paths with the specified Module list.

Definition at line 89 of file Path.cc.

90{
91 m_elements.assign(mlist.begin(), mlist.end());
92}

Friends And Related Function Documentation

◆ PathIterator

friend class PathIterator
friend

Definition at line 139 of file Path.h.

Member Data Documentation

◆ m_elements

std::list<std::shared_ptr<PathElement> > m_elements
private

The list of path elements (Modules and sub-Paths)

Definition at line 137 of file Path.h.


The documentation for this class was generated from the following files: