ATLAS Offline Software
Loading...
Searching...
No Matches
Herwig7JOChecker.py
Go to the documentation of this file.
1# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2# Author: Lukas Kretschmann (lukas.kretschmann@cern.ch)
3
4# import modules
5import os
6import subprocess
7
8# import Athena modules
9from AthenaCommon import Logging
10athMsgLog = Logging.logging.getLogger('Herwig7JOChecker')
11
12# Helper function to get the current Herwig version
14 herwig7_bin_path = os.path.join(os.environ['HERWIG7_PATH'],'bin')
15 herwig7_binary = os.path.join(herwig7_bin_path,'Herwig')
16 versions = subprocess.check_output([herwig7_binary,'--version']).splitlines()
17 return(' '.join([x.decode('UTF8') for x in versions[0].split()[1:]]))
18
19# Helper function to remove the command prefixes from the line
20def clean_string(list,string,replace="",strip=False):
21 for command in range(len(list)):
22 list[command] = list[command].replace(string,replace)
23 if strip:
24 list[command] = list[command].strip()
25 # return the cleaned list
26 return list
27
28# Helper functions to print the commands
30 for command in list:
31 athMsgLog.debug(command)
32
33# Helper function to split command lines into command and value
35 for command in range(len(list)):
36 # Search for whitespaces, since the part before the whitespace gives the parameter which is set
37 # the part after the whitespace gives the value which is set
38 whitespace_idx = list[command].index(" ")
39 # Now split the commands into the command and value set
40 list[command] = [list[command][0:whitespace_idx],list[command][whitespace_idx+1:]]
41 # return the new list
42 return list
43
44# Helper function to check for duplicate commands
45def check_for_overwrites(list,file):
46 found_duplicate = False
47 existing_commands = {}
48 for command in list:
49 temp_com = command[0]
50 temp_val = command[1]
51 # Check if the same command is already present with another value
52 if temp_com in existing_commands and existing_commands[temp_com] != temp_val:
53 found_duplicate = True
54 str1 = "\nFound option that is used twice"
55 str2 = "The option %s is first set to %s" % (temp_com,existing_commands[temp_com])
56 str3 = "And then the option %s ist set to %s" % (command[0],command[1])
57 athMsgLog.info(str1+"\n"+str2+"\n"+str3)
58 file.write(str1+"\n"+str2+"\n"+str3)
59 else:
60 existing_commands[temp_com] = temp_val
61 # return the status
62 return found_duplicate
63
64# Helper function to write commands to file
65def write_to_file(list,file):
66 for command in list:
67 file.write(command[0]+" "+command[1]+"\n")
68
69# Helper function to sort the commands into the lists
70def sort_commands(line,cd_in_line,cd_command,set_commands,read_commands,create_commands,insert_commands):
71 # If the snippets cd's into a dir, we need to append the path to the other commands
72 # To be able to compare to the settings from the master .in file
73 if "cd" in line:
74 cd_command = line.replace("cd ","")
75 cd_command = cd_command.strip()
76 cd_in_line = True
77 # Get all the "set" commands and ignore lines that are commented out
78 elif "set" in line:
79 if cd_in_line and not line.startswith("/Herwig/"):
80 set_commands.append(cd_command+"/"+line)
81 else:
82 set_commands.append(line)
83 # Get all the "create" commands where an object is created
84 elif "create" in line:
85 if cd_in_line and not line.startswith("/Herwig/"):
86 create_commands.append(cd_command+"/"+line)
87 else:
88 create_commands.append(line)
89 # Get all the "insert" commands where an object is inserted
90 elif "insert" in line:
91 if cd_in_line and not line.startswith("/Herwig/"):
92 insert_commands.append(cd_command+"/"+line)
93 else:
94 insert_commands.append(line)
95 # Get all the "read" commands where a config snippet is read in
96 elif "read" in line:
97 read_commands.append(line)
98
99 # return the cd status
100 return cd_in_line,cd_command,set_commands,read_commands,create_commands,insert_commands
101
102# Main function to check the Herwig config file
104 # Hello from the config checker
105 athMsgLog.info("Hello from the config-checker!")
106 # Check the Herwig version
107 h_version = herwig_version()
108 version = h_version[0]
109 subversion = h_version[2]
110 subsubversion = h_version[4]
111 athMsgLog.info("The current Herwig version is "+version+"."+subversion+"."+subsubversion)
112
113 # Get the name of ther Herwig7 in-file
114 files = [f for f in os.listdir('.') if os.path.isfile(f)]
115 HerwigINFile = []
116 for file in files:
117 if ".in" in file:
118 HerwigINFile.append(file)
119
120 # Check if there is only one files, as it should be
121 run_name = HerwigINFile[0]
122 athMsgLog.info("The Herwig7 *.in file is "+run_name)
123
124 # Now get the settings from the .in file
125 set_commands = [] # all commands where a setting is set
126 read_commands = [] # all commands where a file is read in
127 create_commands = [] # all commands where an object is created
128 insert_commands = [] # all commands where an object is inserted
129
130 f = open(run_name, "r")
131 cd_in_line = False
132 cd_command = ""
133 for line in f:
134 if not line.startswith("#"):
135 cd,cd_cmd,set_commands,read_commands,create_commands,insert_commands = sort_commands(line,
136 cd_in_line,cd_command,set_commands,
137 read_commands,create_commands,insert_commands)
138 cd_in_line,cd_command = cd,cd_cmd
139 else:
140 continue
141
142 # remove the "set", "create" and "read" parts as well as the snippet prefix
143 set_commands = clean_string(set_commands,"set ","")
144 create_commands = clean_string(create_commands,"create ","")
145 read_commands = clean_string(read_commands,"read ","")
146 read_commands = clean_string(read_commands,"snippets/","")
147
148 # Now recursiveley read in the config snippets from the read commands
149 include_path = os.environ['HERWIG7_PATH']+"/share/Herwig/"
150 snippet_path = os.environ['HERWIG7_PATH']+"/share/Herwig/snippets/"
151
152 include_files = [f for f in os.listdir(include_path)]
153 snippet_files = [f for f in os.listdir(snippet_path)]
154
155 # Files that we need to read in, since they are read in in the original config
156 read_files = []
157 for file in include_files:
158 for command in read_commands:
159 if file in command:
160 read_files.append(include_path+file)
161 for file in snippet_files:
162 for command in read_commands:
163 if file in command:
164 read_files.append(snippet_path+file)
165
166 # Now loop over the snippets
167 for file in read_files:
168 if ".in" not in file:
169 athMsgLog.info("Skipping file " + file + " since it does not contain any in-file")
170 athMsgLog.info("It is just a directory, can be ignored.")
171 continue
172 else:
173 f = open(file, "r")
174 cd_in_line = False
175 cd_command = ""
176 for line in f:
177 if not line.startswith("#"):
178 cd,cd_cmd,set_commands,read_commands,create_commands,insert_commands = sort_commands(line,cd_in_line,cd_command,set_commands,read_commands,create_commands,insert_commands)
179 cd_in_line,cd_command = cd,cd_cmd
180 else:
181 continue
182 f.close()
183
184 # remove the "set", "create" and "read" parts as well as the snippet prefix
185 set_commands = clean_string(set_commands,"set ","")
186 create_commands = clean_string(create_commands,"create ","")
187 read_commands = clean_string(read_commands,"read ","")
188 read_commands = clean_string(read_commands,"snippets/","")
189
190 # Remove "//" and remove line breaks
191 clean_string(set_commands,"//","/",True)
192 clean_string(create_commands,"//","/",True)
193 clean_string(insert_commands,"//","/",True)
194
195 # Print the commands
196 athMsgLog.debug("\n These are the commands found by the Herwig7JOChecker:\n")
197 print_commands(set_commands)
198 print_commands(create_commands)
199 print_commands(insert_commands)
200 athMsgLog.debug("\n")
201
202 # Now check if there are commands executed twice
203 # It can happen that there are commands set by the user but some config snippet from Herwig sets these commands again
204 # In this case a warning needs to be displayed, this should be checked by the user
205 set_commands = split_commands(set_commands)
206 create_commands = split_commands(create_commands)
207 insert_commands = split_commands(insert_commands)
208
209 # Now we need to check of commands are executed twice
210 with open("HerwigCommandDuplicates.txt","w") as file:
211 found_duplicate1 = check_for_overwrites(set_commands,file)
212 found_duplicate2 = check_for_overwrites(create_commands,file)
213 found_duplicate3 = check_for_overwrites(insert_commands,file)
214
215 # Now save all the commands to an file
216 # This file will be used by JEM/PAVER for the technical validation of generator changes
217 # The files from refrence sample will be checked against the new one to spot config changes
218 with open("HerwigCommands.txt","w") as file:
219 write_to_file(set_commands,file)
220 write_to_file(create_commands,file)
221 write_to_file(insert_commands,file)
222
223 # If there was an error, raise an exception
224 if found_duplicate1 or found_duplicate2 or found_duplicate3:
225 athMsgLog.warn("There were some settings which are overwritten, please check the log-file HerwigCommandDuplicates.txt")
226
227 # Godbye from the config checker
228 athMsgLog.info("Commands have been written to HerwigCommands.txt")
229 athMsgLog.info("Duplicates have been written to HerwigCommandsDuplicates.txt")
230 athMsgLog.info("Godybe from the config-checker!")
231
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition hcg.cxx:310
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177
check_for_overwrites(list, file)
write_to_file(list, file)
clean_string(list, string, replace="", strip=False)
sort_commands(line, cd_in_line, cd_command, set_commands, read_commands, create_commands, insert_commands)
Definition index.py:1