ATLAS Offline Software
Loading...
Searching...
No Matches
MadGraphUtilsHelpers.py
Go to the documentation of this file.
1# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2
3import os,glob
4#The Import line is temporary for backwards compatibility of clients.
5from AthenaCommon import Logging
6mglog = Logging.logging.getLogger('MadGraphUtils')
7
8# Magic name of gridpack directory
9MADGRAPH_GRIDPACK_LOCATION='madevent'
10# For error handling
11MADGRAPH_CATCH_ERRORS=True
12MADGRAPH_COMMAND_STACK = []
13
14
15
16def settingIsTrue(setting):
17 if setting.replace("'",'').replace('"','').replace('.','').lower() in ['t','true']:
18 return True
19 return False
20
22 """Return MadGraph version string (e.g. '3.5.1')
23
24 Used to include MG version in gridpack names for better traceability.
25 Reads version from $MADPATH/VERSION file.
26 """
27 with open(os.environ['MADPATH']+'/VERSION','r') as version_file:
28 for line in version_file:
29 if 'version' in line:
30 return line.split('=')[1].strip()
31 raise RuntimeError('Failed to find MadGraph/MadGraph5_aMC@NLO version')
32
34 # also need to find out the version (copied from generate)
35 import os
36 version=None
37 version_file = open(os.environ['MADPATH']+'/VERSION','r')
38
39 for line in version_file:
40 if 'version' in line:
41 version=line.split('=')[1].strip()
42 version_file.close()
43
44 if not version:
45 raise RuntimeError('Failed to find MadGraph/MadGraph5_aMC@NLO version in '+version_file)
46
47 vs=[int(v) for v in version.split('.')]
48
49 # this is lazy, let's hope there wont be a subversion > 100...
50 y=int(100**max(len(vs),len(args)))
51 testnumber=0
52 for x in args:
53 testnumber+=x*y
54 y/=100
55
56 y=int(100**max(len(vs),len(args)))
57 versionnumber=0
58 for x in vs:
59 versionnumber+=x*y
60 y/=100
61 return versionnumber>=testnumber
62
63def isNLO_from_run_card(run_card):
64 f = open(run_card,'r')
65 if "parton_shower" in f.read().lower():
66 f.close()
67 return True
68 else:
69 f.close()
70 return False
71
72def error_check(errors_a, return_code):
73 if not MADGRAPH_CATCH_ERRORS:
74 return
75 if errors_a is None:
76 # stderr is not always captured (e.g. catch_errors=False).
77 # Still fail on non-zero return code.
78 if return_code != 0:
79 mglog.error(f'Detected a bad return code: {return_code}')
81 raise RuntimeError('Error detected in MadGraphControl process')
82 return
83 unmasked_error = False
84 my_debug_file = None
85 bad_variables = []
86 # Make sure we are getting a string and not a byte string (python3 ftw)
87 errors = errors_a
88 if type(errors)==bytes:
89 errors = errors.decode('utf-8')
90 if len(errors):
91 mglog.info('Some errors detected by MadGraphControl - checking for serious errors')
92 for err in errors.split('\n'):
93 if len(err.strip())==0:
94 continue
95 # Errors to do with I/O... not clear on their origin yet
96 if 'Inappropriate ioctl for device' in err:
97 mglog.info(err)
98 continue
99 if 'stty: standard input: Invalid argument' in err:
100 mglog.info(err)
101 continue
102 # Errors for PDF sets that should be fixed in MG5_aMC 2.7
103 if 'PDF already installed' in err:
104 mglog.info(err)
105 continue
106 if 'Read-only file system' in err:
107 mglog.info(err)
108 continue
109 if 'HTML' in err:
110 # https://bugs.launchpad.net/mg5amcnlo/+bug/1870217
111 mglog.info(err)
112 continue
113 if 'impossible to set default multiparticles' in err:
114 # https://answers.launchpad.net/mg5amcnlo/+question/690004
115 mglog.info(err)
116 continue
117 if 'More information is found in' in err:
118 my_debug_file = err.split("'")[1]
119 if err.startswith('tar'):
120 mglog.info(err)
121 continue
122 if 'python2 support will be removed' in err:
123 mglog.info(err)
124 continue
125 if 'python3.12 support is still experimental' in err:
126 mglog.info(err)
127 continue
128 # Another new python 3.12 message in MG5_aMC 3.6
129 if 'python3.12+ support: For reweighting feature, please use 3.6.X release.' in err:
130 mglog.info(err)
131 continue
132 # silly ghostscript issue in 21.6.46 nightly
133 if 'required by /lib64/libfontconfig.so' in err or\
134 'required by /lib64/libgs.so' in err:
135 mglog.info(err)
136 continue
137 if 'Error: Symbol' in err and 'has no IMPLICIT type' in err:
138 bad_variables += [ err.split('Symbol ')[1].split(' at ')[0] ]
139 # error output from tqdm (progress bar)
140 if 'it/s' in err:
141 mglog.info(err)
142 continue
143 mglog.error(err)
144 unmasked_error = True
145 # This is a bit clunky, but needed because we could be several places when we get here
146 if my_debug_file is None:
147 debug_files = glob.glob('*debug.log')+glob.glob('*/*debug.log')
148 for debug_file in debug_files:
149 # This protects against somebody piping their output to my_debug.log and it being caught here
150 has_subproc = os.access(os.path.join(os.path.dirname(debug_file),'SubProcesses'),os.R_OK)
151 if has_subproc:
152 my_debug_file = debug_file
153 break
154
155 if my_debug_file is not None:
156 if not unmasked_error:
157 mglog.warning('Found a debug file at '+my_debug_file+' but no apparent error. Will terminate.')
158 mglog.error('MadGraph5_aMC@NLO appears to have crashed. Debug file output follows.')
159 with open(my_debug_file,'r') as error_output:
160 for l in error_output:
161 mglog.error(l.replace('\n',''))
162 mglog.error('End of debug file output')
163
164 if bad_variables:
165 mglog.warning('Appeared to detect variables in your run card that MadGraph did not understand:')
166 mglog.warning(' Check your run card / JO settings for %s',bad_variables)
167
168 # Check the return code
169 if return_code!=0:
170 mglog.error(f'Detected a bad return code: {return_code}')
171 unmasked_error = True
172
173 # Now raise an error if we were in either of the error states
174 if unmasked_error or my_debug_file is not None:
176 raise RuntimeError('Error detected in MadGraphControl process')
177 return
178
179
180# Write a short test script for standalone debugging
182 mglog.info('Will write a stand-alone debugging script.')
183 mglog.info('This is an attempt to provide you commands that you can use')
184 mglog.info('to reproduce the error locally. If you make additional')
185 mglog.info('modifications by hand (not using MadGraphControl) in your JO,')
186 mglog.info('make sure that you check and modify the script as needed.\n\n')
187 mglog.info('# Script start; trim off columns left of the "#"')
188 # Write offline stand-alone reproduction script
189 with open('standalone_script.sh','w') as standalone_script:
190 for command in MADGRAPH_COMMAND_STACK:
191 for line in command.split('\n'):
192 mglog.info(line)
193 standalone_script.write(line+'\n')
194 mglog.info('# Script end')
195 mglog.info('Script also written to %s/standalone_script.sh',os.getcwd())
196
197
198def find_key_and_update(akey,dictionary):
199 """ Helper function when looking at param cards
200 In some cases it's tricky to match keys - they may differ
201 only in white space. This tries to sort out when we have
202 a match, and then uses the one in blockParams afterwards.
203 In the case of no match, it returns the original key.
204 """
205 test_key = ' '.join(akey.strip().replace('\t',' ').split())
206 for key in dictionary:
207 mod_key = ' '.join(key.strip().replace('\t',' ').split())
208 if mod_key==test_key:
209 return key
210 return akey
#define max(a, b)
Definition cfImp.cxx:41
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition hcg.cxx:312
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:179
error_check(errors_a, return_code)