5 basf2.pickle_path - Functions necessary to pickle and unpickle a Path
6 =====================================================================
8 This module contains all the functiones necessary to serialize and deserialize
9 a full path with all modules, parameters, sub paths, conditions and so on. This
10 can be used in conjunction with ``basf2 --dump-path`` and ``basf2
11 --execute-path`` to save a full configuration to file and execute it later.
15 import pickle
as _pickle
20 def serialize_value(module, parameter):
21 if parameter.name ==
'path' and module.type() ==
'SubEvent':
22 return serialize_path(parameter.values)
24 return parameter.values
27 def deserialize_value(module, parameter_state):
28 if parameter_state[
'name'] ==
'path' and module.type() ==
'SubEvent':
29 return deserialize_path(parameter_state[
'values'])
31 return parameter_state[
'values']
34 def serialize_conditions(module):
37 for condition
in module.get_all_conditions():
38 condition_list.append({
'value': condition.get_value(),
39 'operator': int(condition.get_operator()),
40 'path': serialize_path(condition.get_path()),
41 'option': int(condition.get_after_path())})
46 def deserialize_conditions(module, module_state):
47 conditions = module_state[
'condition']
48 for cond
in conditions:
49 module.if_value(str(pybasf2.ConditionOperator.values[cond[
'operator']]) + str(cond[
'value']),
50 deserialize_path(cond[
'path']), pybasf2.AfterConditionPath.values[cond[
'option']])
53 def serialize_module(module):
54 if module.type() ==
'' or module.type() ==
'PyModule':
55 raise RuntimeError(
"Module '%s' doesn't have a type or is a Python module! Note that --dump-path cannot work"
56 "properly with basf2 modules written in Python." % (module.name()))
58 'name': module.name(),
59 'type': module.type(),
60 'flag': module.has_properties(pybasf2.ModulePropFlags.PARALLELPROCESSINGCERTIFIED),
61 'parameters': [{
'name': parameter.name,
'values': serialize_value(module, parameter)}
62 for parameter
in module.available_params()
63 if parameter.setInSteering
or module.type() ==
'SubEvent'],
64 'condition': serialize_conditions(module)
if module.has_condition()
else None}
67 def deserialize_module(module_state):
68 module = pybasf2._register_module(module_state[
'type'])
69 module.set_name(module_state[
'name'])
70 if 'condition' in module_state
and module_state[
'condition']
is not None:
71 deserialize_conditions(module, module_state)
72 if 'flag' in module_state
and module_state[
'flag']:
74 module.set_property_flags(pybasf2.ModulePropFlags.PARALLELPROCESSINGCERTIFIED)
75 for parameter_state
in module_state[
'parameters']:
76 module.param(parameter_state[
'name'],
77 deserialize_value(module, parameter_state))
81 def serialize_path(path):
82 return {
'modules': [serialize_module(module)
for module
in path.modules()]}
85 def deserialize_path(path_state):
87 for module_state
in path_state[
'modules']:
88 module = deserialize_module(module_state)
89 path.add_module(module)
93 def get_path_from_file(path_filename):
94 """Read a path from a given pickle file"""
95 with open(path_filename,
'br')
as f:
96 return deserialize_path(_pickle.load(f))
99 def write_path_to_file(path, filename):
100 """Write a path to a given pickle file"""
101 with open(filename,
'bw')
as f:
102 _pickle.dump(serialize_path(path), f)
105 def check_pickle_path(path):
106 """Check if the path to be executed should be pickled or unpickled.
107 This function is used by basf2.process to handle the ``--dump-path`` and
108 ``--execute-path`` arguments to ``basf2``
111 pickle_filename = pybasf2.get_pickle_path()
112 if pickle_filename ==
'':
116 if _os.path.isfile(pickle_filename)
and path
is None:
117 path = get_path_from_file(pickle_filename)
118 with open(pickle_filename,
"br")
as f:
119 loaded = _pickle.load(f)
120 if 'state' in loaded:
121 pybasf2.B2INFO(
"Pickled path contains a state object. Activating pickled state.")
122 for name, args, kwargs
in loaded[
'state']:
123 getattr(_sys.modules[__name__], name)(*args, **kwargs)
127 elif path
is not None:
128 write_path_to_file(path, pickle_filename)
131 pybasf2.B2FATAL(
"Couldn't open path-file '" + pickle_filename +
"' and no steering file provided.")
134 def make_code_pickable(code):
136 Sometimes it is necessary to execute code which won't be pickled if a user dumps the basf2 path
137 and wants to execute it later. Using the pickable_basf2 module all calls to basf2 functions
138 are recorded. Now if a user has to execute code outside of basf2, e.g. modifying objects in the ROOT namespace,
139 this won't be pickled. By wrapping the code in this function it is technically a call to a basf2 function
140 and will be pickled again. Problem solved.
142 exec(code, globals())