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