3 from AnaAlgorithm.AlgSequence
import AlgSequence
4 from AnaAlgorithm.PythonConfig
import PrivateToolConfig
5 from AthenaCommon.Logging
import logging
11 alg_file = 'alg_sequence.json', output_file = 'my_analysis_config.json'):
13 Parse a tool configuration text file and merge it with an algorithm sequence JSON file.
16 combine_dictionaries (bool): Whether to load and merge with existing alg_file
17 text_file (str): Path to the tool configuration text file
18 alg_file (str): Path to the algorithm sequence JSON file
19 output_file (str): Path where the merged configuration will be saved
22 dict: The resulting configuration, which is a merge of the tool configuration
23 and algorithm sequence JSON data.
25 log = logging.getLogger(
"SaveConfigUtils")
26 log.info(
"Calling COMBINE_JSON_FILES with the following arguments:")
27 log.info(f
" - tool configuration = {text_file}")
28 log.info(f
" - algorithm sequence = {alg_file}")
29 log.info(f
" - full output config = {output_file}")
31 if not os.path.exists(text_file):
32 raise FileNotFoundError(f
"The tool configuration file {text_file} was not found.")
33 if not os.path.exists(alg_file):
34 raise FileNotFoundError(f
"The algorithm sequence file {alg_file} was not found.")
38 if combine_dictionaries:
39 with open(alg_file,
'r', encoding=
'utf-8')
as f:
42 except json.JSONDecodeError
as e:
43 raise ValueError(f
"Error parsing JSON in {alg_file}: {e}")
46 current_tool_path =
None
47 current_tool_id =
None
48 current_tool_properties = {}
50 with open(text_file,
'r')
as f:
53 if not line
or '=' not in line:
56 path, value = map(str.strip, line.split(
'=', 1))
57 parts = path.split(
'.')
62 if len(value.split(
"/")) == 2
and "'" not in value
and current_tool_path != parts:
65 _register_settings(config, current_tool_path, current_tool_id, current_tool_properties)
67 tool_path = parts[:-1]
69 tool_name = value.split(
"/")[1]
72 current_tool_path = tool_path
73 current_tool_id = tool_id
74 current_tool_properties = {}
77 property_name = parts[-1]
78 current_tool_properties[property_name] = value
81 if current_tool_properties
and current_tool_id:
82 _register_settings(config, current_tool_path, current_tool_id, current_tool_properties)
85 with open(output_file,
'w', encoding=
'utf-8')
as f:
86 json.dump(config, f, indent=4)
92 if not settings
or path
is None:
return
97 if key
not in current_dict:
98 raise ValueError(f
"Couldn't find key {key} in dictionary of algorithms and tools, this should not happen!")
99 current_dict = current_dict[key][
"Properties"][
"Tools"]
101 for key,value
in settings.items():
106 current_dict = config
110 if key
not in current_dict:
112 current_dict[key] = {
"Properties": {
"Tools": {}},
"Type":
""}
115 if "Properties" not in current_dict[key].
keys():
116 current_dict[key][
"Properties"] = {
"Tools": {}}
117 if "Tools" not in current_dict[key][
"Properties"].
keys():
118 current_dict[key][
"Properties"][
"Tools"] = {}
119 current_dict = current_dict[key][
"Properties"][
"Tools"]
122 if tool_id
not in current_dict:
123 current_dict[tool_id] = {
"Properties": {}}
126 if "Properties" not in current_dict[tool_id]:
127 current_dict[tool_id][
"Properties"] = {}
128 current_dict[tool_id][
"Properties"][
"Name"] = name
133 Save the algorithms in the sequence without the sequence structure.
134 Does not save the tools. You need to get them with PrintToolConfigAlg.
137 sequence (AnaAlgorithm.AlgSequence: the algorithm sequence to parse
138 output_dict (dict): the dictionary to populate
141 if not isinstance(output_dict, dict):
142 raise ValueError(
"output_dict must be a dictionary")
145 if isinstance(sequence, AlgSequence):
149 output_dict[alg.name()] = nested_dict
156 """ Helper function to save individual algorithm properties """
157 output_dict[
'Type'] = sequence.type()
158 output_dict[
'Properties'] = {
'Tools': {}}
160 for key, value
in sorted(sequence._props.items()):
161 if isinstance(value, str):
162 output_dict[
'Properties'][key] = value
163 elif isinstance(value, PrivateToolConfig):
170 """ Handle tool configurations inside algorithms """
171 log = logging.getLogger(
"SaveConfigUtils")
172 if tool_config._prefix
in output_dict[
'Properties'][
'Tools']:
173 log.warning(f
"Already have this tool in the dict, prefix: {tool_config._prefix}. You need to ID the name somehow.")
175 output_dict[
'Properties'][
'Tools'][tool_config._prefix] = {
'Type': tool_config._type}
179 """ Safely adds properties to the output_dict with error handling """
180 log = logging.getLogger(
"SaveConfigUtils")
182 output_dict[
'Properties'][key] = value
183 except Exception
as e:
184 log.warning(f
"Couldn't add property '{key}' to dict. Value: {value}. Error: {e}")