LDMX Software
Classes | Typedefs | Functions | Variables
framework Namespace Reference

All classes in the ldmx-sw project use this namespace. More...

Classes

class  AbortEventException
 Specific exception used to abort an event. More...
 
class  Analyzer
 Base class for a module which does not produce a data product. More...
 
class  Bus
 A map of bus passengers. More...
 
class  Conditions
 Container and cache for conditions and conditions providers. More...
 
class  ConditionsIOV
 Class which defines the run/event/type range for which a given condition is valid, including for all time. More...
 
class  ConditionsObject
 Base class for all conditions objects, very simple. More...
 
class  ConditionsObjectProvider
 Base class for all providers of conditions objects. More...
 
class  ConfigurePython
 Utility class which reads/executes a python script and creates a Process object based on the input. More...
 
class  Event
 Implements an event buffer system for storing event data. More...
 
class  EventFile
 This class manages all ROOT file input/output operations. More...
 
class  EventProcessor
 Base class for all event processing components. More...
 
class  HistogramHelper
 Interface class between an EventProcessor and the HistogramPool. More...
 
class  HistogramPool
 Singleton class used to create and pool histograms. More...
 
class  NtupleManager
 Singleton class used to manage the creation and pooling of ntuples. More...
 
class  PluginFactory
 Singleton module factory that creates EventProcessor objects. More...
 
class  Process
 Class which represents the process under execution. More...
 
class  Producer
 Base class for a module which produces a data product. More...
 
class  ProductTag
 Defines the identity of a product and can be used for searches. More...
 
class  RandomNumberSeedService
 System for consistent seeding of random number generators. More...
 
class  StorageControl
 Class which encapsulates storage control functionality, used by the Process class. More...
 

Typedefs

typedef ConditionsObjectProviderConditionsObjectProviderMaker(const std::string &objname, const std::string &tagname, const framework::config::Parameters &params, Process &process)
 Typedef for PluginFactory use.
 
typedef EventProcessorEventProcessorMaker(const std::string &name, Process &process)
 Typedef for EventProcessorFactory use.
 
typedef std::unique_ptr< ProcessProcessHandle
 A handle to the current process Used to pass a process from ConfigurePython to fire.cxx.
 

Functions

static std::string getPyString (PyObject *pyObj)
 Turn the input python string object into a C++ string.
 
std::string repr (PyObject *obj)
 Get a C++ string representation of the input python object.
 
PyObject * extractDictionary (PyObject *obj)
 extract the dictionary of attributes from the input python object
 
static std::map< std::string, std::any > getMembers (PyObject *object)
 Extract members from a python object.
 
static regex_t construct_regex (const std::string &pattern, bool full_string_match)
 Construct an actual regex from the pass pattern (and full-string flag)
 

Variables

constexpr StorageControl::Hint hint_shouldKeep
 storage control hint alias for backwards compatibility
 
constexpr StorageControl::Hint hint_shouldDrop
 storage control hint alias for backwards compatibility
 
static const int SEED_EXTERNAL = 2
 
static const int SEED_RUN = 3
 
static const int SEED_TIME = 4
 

Detailed Description

All classes in the ldmx-sw project use this namespace.

Typedef Documentation

◆ ConditionsObjectProviderMaker

typedef ConditionsObjectProvider * framework::ConditionsObjectProviderMaker(const std::string &objname, const std::string &tagname, const framework::config::Parameters &params, Process &process)

Typedef for PluginFactory use.

Definition at line 40 of file ConditionsObjectProvider.h.

◆ EventProcessorMaker

typedef EventProcessor * framework::EventProcessorMaker(const std::string &name, Process &process)

Typedef for EventProcessorFactory use.

Definition at line 38 of file EventProcessor.h.

◆ ProcessHandle

typedef std::unique_ptr<Process> framework::ProcessHandle

A handle to the current process Used to pass a process from ConfigurePython to fire.cxx.

Definition at line 248 of file Process.h.

Function Documentation

◆ construct_regex()

static regex_t framework::construct_regex ( const std::string &  pattern,
bool  full_string_match 
)
static

Construct an actual regex from the pass pattern (and full-string flag)

If the pattern is the empty string, then we generate the match-all regex .*.

If the pattern is not empty and we want to match on full-strings, then we prepend the pattern with ^ and append the pattern with $ to inform regex that the pattern should match the entire string.

Parameters
[in]patterna regex pattern string
[in]full_string_matchflag if we want full-string matches only (true) or if we can include sub-strings (false)
Returns
generated regex structure, expecting user to call regfree on it when done

Definition at line 47 of file Event.cxx.

48 {
49 std::string pattern_regex{pattern};
50 if (pattern_regex.empty())
51 pattern_regex = ".*";
52 else if (full_string_match)
53 pattern_regex = "^" + pattern_regex + "$";
54
55 regex_t reg;
56 if (regcomp(&reg, pattern_regex.c_str(),
57 REG_EXTENDED | REG_ICASE | REG_NOSUB)) {
58 // use input value in exception since we expect our code above evolving
59 // the regex to be accurate
60 EXCEPTION_RAISE("InvalidRegex", "The passed regex '" + pattern +
61 "' is not a valid regular expression.");
62 }
63 return reg;
64}

Referenced by framework::Event::searchProducts().

◆ extractDictionary()

PyObject * framework::extractDictionary ( PyObject *  obj)

extract the dictionary of attributes from the input python object

This is separated into its own function to isolate the code that depends on the python version. Since memory-saving measures were integrated into Python between 3.6.9 and 3.10.6, we need to alter how we were using the C API to access an objects dict attribute. We are now using a "hidden" Python C API function which has only been added to the public C API documentation in Python 3.11. It has been manually tested for the two different Python versions we use by running the tests (some of which test the ConfigurePython) and running a basic simulation.

Exceptions
Exceptionif object does not have a dict and isn't a dict
Parameters
objpointer to python object to extract from
Returns
pointer to python dictionary for its members

Definition at line 74 of file ConfigurePython.cxx.

74 {
75#if PY_MAJOR_VERSION != 3
76#error("Framework requires compiling with Python3")
77#else
78#if PY_MINOR_VERSION != 10 && PY_MINOR_VERSION != 6
79#warning("Unrecognized Python3 minor version. Unsure if accessing C API properly for configuration.")
80#endif
92 PyObject** p_dictionary{_PyObject_GetDictPtr(obj)};
93 if (p_dictionary == NULL) {
94 if (PyDict_Check(obj)) {
95 return obj;
96 } else {
97 EXCEPTION_RAISE("ObjFail",
98 "Python Object '" + repr(obj) +
99 "' does not have __dict__ member and is not a dict.");
100 }
101 }
102 return *p_dictionary;
103#endif
104}
std::string repr(PyObject *obj)
Get a C++ string representation of the input python object.

References repr().

Referenced by getMembers().

◆ getMembers()

static std::map< std::string, std::any > framework::getMembers ( PyObject *  object)
static

Extract members from a python object.

Iterates through the object's dictionary and translates the objects inside of it into the type-specified C++ equivalents, then puts these objects into a STL map that can be passed to the Parameters class.

This function is recursive. If a non-base type is encountered, we pass it back along to this function to translate it's own dictionary.

We rely completely on python being awesome. For all higher level class objects, python keeps track of all of its member variables in the member dictionary dict.

No Py_DECREF calls are made because all of the members of an object are borrowed references, meaning that when we destory that object, it handles the other members. We destroy the one parent object pProcess at the end of ConfigurePython::ConfigurePython.

Note
Not sure if this is not leaking memory, kinda just trusting the Python / C API docs on this one.
Empty lists are NOT read in because there is no way for us to know what type should be inside the list. This means list parameters that can be empty need to put in a default empty list value: {}.
Parameters
objectPython object to get members from
Returns
Mapping between member name and value.

Definition at line 136 of file ConfigurePython.cxx.

136 {
137 PyObject* dictionary{extractDictionary(object)};
138 PyObject *key(0), *value(0);
139 Py_ssize_t pos = 0;
140
141 std::map<std::string, std::any> params;
142
143 while (PyDict_Next(dictionary, &pos, &key, &value)) {
144 std::string skey{getPyString(key)};
145 if (PyLong_Check(value)) {
146 if (PyBool_Check(value)) {
147 params[skey] = bool(PyLong_AsLong(value));
148 } else {
149 params[skey] = int(PyLong_AsLong(value));
150 }
151 } else if (PyFloat_Check(value)) {
152 params[skey] = PyFloat_AsDouble(value);
153 } else if (PyUnicode_Check(value)) {
154 params[skey] = getPyString(value);
155 } else if (PyList_Check(value)) {
156 // assume everything is same value as first value
157 if (PyList_Size(value) > 0) {
158 auto vec0{PyList_GetItem(value, 0)};
159
160 if (PyLong_Check(vec0)) {
161 std::vector<int> vals;
162
163 for (auto j{0}; j < PyList_Size(value); j++)
164 vals.push_back(PyLong_AsLong(PyList_GetItem(value, j)));
165
166 params[skey] = vals;
167
168 } else if (PyFloat_Check(vec0)) {
169 std::vector<double> vals;
170
171 for (auto j{0}; j < PyList_Size(value); j++)
172 vals.push_back(PyFloat_AsDouble(PyList_GetItem(value, j)));
173
174 params[skey] = vals;
175
176 } else if (PyUnicode_Check(vec0)) {
177 std::vector<std::string> vals;
178 for (Py_ssize_t j = 0; j < PyList_Size(value); j++) {
179 PyObject* elem = PyList_GetItem(value, j);
180 vals.push_back(getPyString(elem));
181 }
182
183 params[skey] = vals;
184 } else if (PyList_Check(vec0)) {
185 // a list in a list ??? oof-dah
186 if (PyList_Size(vec0) > 0) {
187 auto vecvec0{PyList_GetItem(vec0, 0)};
188 if (PyLong_Check(vecvec0)) {
189 std::vector<std::vector<int>> vals;
190 for (auto j{0}; j < PyList_Size(value); j++) {
191 auto subvec{PyList_GetItem(value, j)};
192 std::vector<int> subvals;
193 for (auto k{0}; k < PyList_Size(subvec); k++) {
194 subvals.push_back(PyLong_AsLong(PyList_GetItem(subvec, k)));
195 }
196 vals.push_back(subvals);
197 }
198 params[skey] = vals;
199 } else if (PyFloat_Check(vecvec0)) {
200 std::vector<std::vector<double>> vals;
201 for (auto j{0}; j < PyList_Size(value); j++) {
202 auto subvec{PyList_GetItem(value, j)};
203 std::vector<double> subvals;
204 for (auto k{0}; k < PyList_Size(subvec); k++) {
205 subvals.push_back(
206 PyFloat_AsDouble(PyList_GetItem(subvec, k)));
207 }
208 vals.push_back(subvals);
209 }
210 params[skey] = vals;
211 } else if (PyUnicode_Check(vecvec0)) {
212 std::vector<std::vector<std::string>> vals;
213 for (auto j{0}; j < PyList_Size(value); j++) {
214 auto subvec{PyList_GetItem(value, j)};
215 std::vector<std::string> subvals;
216 for (auto k{0}; k < PyList_Size(subvec); k++) {
217 subvals.push_back(getPyString(PyList_GetItem(subvec, k)));
218 }
219 vals.push_back(subvals);
220 }
221 params[skey] = vals;
222 } else if (PyList_Check(vecvec0)) {
223 EXCEPTION_RAISE("BadConf",
224 "A python list with dimension greater than 2 is "
225 "not supported.");
226 } else {
227 // RECURSION zoinks!
228 std::vector<std::vector<framework::config::Parameters>> vals;
229 for (auto j{0}; j < PyList_Size(value); j++) {
230 auto subvec{PyList_GetItem(value, j)};
231 std::vector<framework::config::Parameters> subvals;
232 for (auto k{0}; k < PyList_Size(subvec); k++) {
233 subvals.emplace_back();
234 subvals.back().setParameters(
235 getMembers(PyList_GetItem(subvec, k)));
236 }
237 vals.push_back(subvals);
238 }
239 params[skey] = vals;
240 }
241 } // non-zero size
242 } else {
243 // RECURSION zoinks!
244 // If the objects stored in the list doesn't
245 // satisfy any of the above conditions, just
246 // create a vector of parameters objects
247 std::vector<framework::config::Parameters> vals;
248 for (auto j{0}; j < PyList_Size(value); ++j) {
249 auto elem{PyList_GetItem(value, j)};
250 vals.emplace_back();
251 vals.back().setParameters(getMembers(elem));
252 }
253 params[skey] = vals;
254 } // type of object in python list
255 } // python list has non-zero size
256 } else {
257 // object got here, so we assume
258 // it is a higher level object
259 //(same logic as last option for a list)
260
261 // RECURSION zoinks!
263 val.setParameters(getMembers(value));
264
265 params[skey] = val;
266
267 } // python object type
268 } // loop through python dictionary
269
270 return params;
271}
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:27
void setParameters(std::map< std::string, std::any > parameters)
Set the mapping of parameter names to value.
Definition Parameters.h:41
PyObject * extractDictionary(PyObject *obj)
extract the dictionary of attributes from the input python object
static std::map< std::string, std::any > getMembers(PyObject *object)
Extract members from a python object.
static std::string getPyString(PyObject *pyObj)
Turn the input python string object into a C++ string.

References extractDictionary(), getMembers(), getPyString(), and framework::config::Parameters::setParameters().

Referenced by framework::ConfigurePython::ConfigurePython(), and getMembers().

◆ getPyString()

static std::string framework::getPyString ( PyObject *  pyObj)
static

Turn the input python string object into a C++ string.

Helpful to condense down the multi-line nature of the python3 code.

Parameters
[in]pythonobject assumed to be a string python object
Returns
the value stored in it

Definition at line 33 of file ConfigurePython.cxx.

33 {
34 std::string retval;
35 PyObject* pyStr = PyUnicode_AsEncodedString(pyObj, "utf-8", "Error ~");
36 retval = PyBytes_AS_STRING(pyStr);
37 Py_XDECREF(pyStr);
38 return retval;
39}

Referenced by getMembers(), and repr().

◆ repr()

std::string framework::repr ( PyObject *  obj)

Get a C++ string representation of the input python object.

This is replicating the repr(obj) syntax of Python.

Parameters
[in]objpython object to get repr for
Returns
std::string form of repr

Definition at line 49 of file ConfigurePython.cxx.

49 {
50 PyObject* py_repr = PyObject_Repr(obj);
51 if (py_repr == nullptr) return "";
52 std::string str = getPyString(py_repr);
53 Py_XDECREF(py_repr);
54 return str;
55}

References getPyString().

Referenced by extractDictionary().

Variable Documentation

◆ hint_shouldDrop

constexpr StorageControl::Hint framework::hint_shouldDrop
constexpr

◆ hint_shouldKeep

constexpr StorageControl::Hint framework::hint_shouldKeep
constexpr

◆ SEED_EXTERNAL

const int framework::SEED_EXTERNAL = 2
static

Definition at line 14 of file RandomNumberSeedService.cxx.

◆ SEED_RUN

const int framework::SEED_RUN = 3
static

Definition at line 15 of file RandomNumberSeedService.cxx.

◆ SEED_TIME

const int framework::SEED_TIME = 4
static

Definition at line 16 of file RandomNumberSeedService.cxx.