ATLAS Offline Software
Loading...
Searching...
No Matches
python.MGC.MGControl Class Reference
Collaboration diagram for python.MGC.MGControl:

Public Member Functions

 __init__ (self, process='generate p p > t t~\noutput -f', plugin=None, keepJpegs=False, usePMGSettings=False, pdf_setting=None, devices=None, catch_errors=MADGRAPH_CATCH_ERRORS)
 setup_path_protection (self)
 getRunCardDict (self, lowercase=False)
 get_config_cardloc (self)
 getConfigFromPath (self, card_loc, lowercase=False)
 get_runArgs_info (self, runArgs)
 get_flags_info (self, flags)
 add_runArgs (self, runArgs=None)
 add_flags (self, flags=None)
 write_runCard (self, runArgs=None, flags=None)
 write_configCard (self)
 compare_runCardCasing (self)
 run_card_consistency_check (self)
 base_fragment_setup_check (self, the_base_fragment, extras, isNLO)
 getCA (self, flags=None)

Public Attributes

 mglog = Logging.logging.getLogger('MadGraphUtils')
 process = process
 plugin = plugin
 keepJpegs = keepJpegs
 usePMGSettings = usePMGSettings
 pdf_setting = MADGRAPH_PDFSETTING if pdf_setting is None else pdf_setting
 devices = MADGRAPH_DEVICES if devices is None else devices
 catch_errors = MADGRAPH_CATCH_ERRORS if catch_errors is None else catch_errors
list run_card_params = []
int beamEnergy = 0
 is_gen_from_gridpack = os.access(MADGRAPH_GRIDPACK_LOCATION,os.R_OK)
 process_dir = MADGRAPH_GRIDPACK_LOCATION
list MADGRAPH_COMMAND_STACK = []
 config_path
bool isNLO
dict runCardDict = {}
dict configCardDict = {}
 random_seed = runArgs.randomSeed

Protected Member Functions

 _add_seed_and_beam_settings (self)

Detailed Description

Definition at line 37 of file MGC.py.

Constructor & Destructor Documentation

◆ __init__()

python.MGC.MGControl.__init__ ( self,
process = 'generate p p > t t~\noutput -f',
plugin = None,
keepJpegs = False,
usePMGSettings = False,
pdf_setting = None,
devices = None,
catch_errors = MADGRAPH_CATCH_ERRORS )
 Generate a new process in madgraph.
Pass a process string.
Optionally request JPEGs to be kept and request for PMG settings to be used in the param card
Return the name of the process directory.

Definition at line 38 of file MGC.py.

38 def __init__(self, process='generate p p > t t~\noutput -f', plugin=None, keepJpegs=False, usePMGSettings=False, pdf_setting=None, devices=None, catch_errors=MADGRAPH_CATCH_ERRORS):
39 """ Generate a new process in madgraph.
40 Pass a process string.
41 Optionally request JPEGs to be kept and request for PMG settings to be used in the param card
42 Return the name of the process directory.
43 """
44 self.mglog = Logging.logging.getLogger('MadGraphUtils')
45 self.process = process
46 self.plugin = plugin
47 self.keepJpegs = keepJpegs
48 self.usePMGSettings = usePMGSettings
49 self.pdf_setting = MADGRAPH_PDFSETTING if pdf_setting is None else pdf_setting
50 self.devices = MADGRAPH_DEVICES if devices is None else devices
51 self.catch_errors = MADGRAPH_CATCH_ERRORS if catch_errors is None else catch_errors
52 self.run_card_params = []
53 self.beamEnergy = 0
54 #is_gen_from gridpack
55 self.is_gen_from_gridpack = os.access(MADGRAPH_GRIDPACK_LOCATION,os.R_OK)
56 # Don't run if generating events from gridpack
57 if self.is_gen_from_gridpack:
58 self.process_dir = MADGRAPH_GRIDPACK_LOCATION
59 return
60 # Actually just sent the process card contents - let's make a card
61 card_loc = 'proc_card_mg5.dat'
62 mglog.info('Writing process card to '+card_loc)
63 a_card = open( card_loc , 'w' )
64 for l in process.split('\n'):
65 if 'output' not in l:
66 a_card.write(l+'\n')
67 else:
68 # Special handling for output line
69 outline = l.strip()
70 if '-nojpeg' not in l and not keepJpegs:
71 # We need to add -nojpeg somehow
72 if '#' in l:
73 outline = outline.split('#')[0]+' -nojpeg #'+outline.split('#')[1]
74 else:
75 outline = outline + ' -nojpeg'
76 # Special handling for devises
77 if self.devices is not None:
78 if self.devices.lower() in ['madevent_simd','madevent_gpu']:
79 outline = 'output '+self.devices.lower()+' '+outline.split('output')[1]
80 elif self.devices.lower() == 'max':
81 self.mglog.warning('Not fully implemented yet; setting avx')
82 outline = 'output madevent_simd '+outline.split('output')[1]
83 a_card.write(outline+'\n')
84 a_card.close()
85
86 madpath = os.environ['MADPATH']
87 self.MADGRAPH_COMMAND_STACK = []
88 # Just in case
89 self.setup_path_protection()
90
91 # Check if we have a special output directory
92 process_dir = ''
93 for l in process.split('\n'):
94 # Look for an output line
95 if 'output' not in l.split('#')[0].split():
96 continue
97 # Check how many things before the options start
98 tmplist = l.split('#')[0].split(' -')[0]
99 # if two things, second is the directory
100 if len(tmplist.split())==2:
101 process_dir = tmplist.split()[1]
102 # if three things, third is the directory (second is the format)
103 elif len(tmplist.split())==3:
104 process_dir = tmplist.split()[2]
105 # See if we got a directory
106 if ''!=process_dir:
107 mglog.info('Saw that you asked for a special output directory: '+str(process_dir))
108 break
109
110 mglog.info('Started process generation at '+str(time.asctime()))
111
112 plugin_cmd = '--mode='+plugin if plugin is not None else ''
113
114 # Note special handling here to explicitly print the process
115 self.MADGRAPH_COMMAND_STACK += ['# All jobs should start in a clean directory']
116 self.MADGRAPH_COMMAND_STACK += ['mkdir standalone_test; cd standalone_test']
117 self.MADGRAPH_COMMAND_STACK += [' '.join([python,madpath+'/bin/mg5_aMC '+plugin_cmd+' << EOF\n'+process+'\nEOF\n'])]
118 generate = subprocess.Popen([python,madpath+'/bin/mg5_aMC',plugin_cmd,card_loc],stdin=subprocess.PIPE,stderr=subprocess.PIPE if self.catch_errors else None)
119 (out,err) = generate.communicate()
120 error_check(err,generate.returncode)
121
122 mglog.info('Finished process generation at '+str(time.asctime()))
123
124 # at this point process_dir is for sure defined - it's equal to '' in the worst case
125 if process_dir == '': # no user-defined value, need to find the directory created by MadGraph5
126 for adir in sorted(glob.glob( os.getcwd()+'/*PROC*' ),reverse=True):
127 if os.access('%s/SubProcesses/subproc.mg'%adir,os.R_OK):
128 if process_dir=='':
129 process_dir = adir
130 else:
131 mglog.warning('Additional possible process directory, '+adir+' found. Had '+process_dir)
132 mglog.warning('Likely this is because you did not run from a clean directory, and this may cause errors later.')
133 else: # user-defined directory
134 if not os.access('%s/SubProcesses/subproc.mg'%process_dir,os.R_OK):
135 raise RuntimeError('No diagrams for this process in user-define dir='+str(process_dir))
136 if process_dir=='':
137 raise RuntimeError('No diagrams for this process from list: '+str(sorted(glob.glob(os.getcwd()+'/*PROC*'),reverse=True)))
138
139 self.process_dir = process_dir
140 self.get_config_cardloc()
141 self.getConfigFromPath(self.config_path)
142
143 #load up the run card dictionary
144 self.getRunCardDict()
145
146 # If requested, apply PMG default settings
147 if usePMGSettings:
148 do_PMG_updates(self.process_dir)
149
150 if not self.isNLO:
151 mglog.info('Setting default sde_strategy to old default (1)')
152 self.runCardDict['sde_strategy'] = 1
153
154 #tell MadGraph not to bother trying to create popup windows since this is running in a CLI, this will save ~50 seconds every time MadGraph is called.
155 self.configCardDict.update({'notification_center':'False'})
156
157 # Add some custom settings based on the device requests
158 if self.devices is not None:
159 if self.devices.lower()=='madevent_simd':
160 self.runCardDict['cudacpp_backend'] = 'cppauto'
161 elif self.devices.lower()=='madevent_gpu':
162 self.runCardDict['cudacpp_backend'] = 'cuda'
163 # In case we have "too new" a gcc version for the nvcc version on the node, which should be ok
164 # This patch should be temporary, but is fine while we are validating things at least
165 os.environ['ALLOW_UNSUPPORTED_COMPILER_IN_CUDA'] = 'Y'
166 elif self.devices.lower() == 'max':
167 self.mglog.warning('Not fully implemented yet; setting avx')
168 self.runCardDict['cudacpp_backend'] = 'cppauto'
169
170 # Make sure we store the resultant directory
171 self.MADGRAPH_COMMAND_STACK += ['export MGaMC_PROCESS_DIR='+os.path.basename(self.process_dir)]
172
173
174
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:179

Member Function Documentation

◆ _add_seed_and_beam_settings()

python.MGC.MGControl._add_seed_and_beam_settings ( self)
protected
Add seed and beam settings to runCardDict.

Definition at line 306 of file MGC.py.

306 def _add_seed_and_beam_settings(self):
307 """Add seed and beam settings to runCardDict."""
308 # Check if the run arguments are already implemented.
309 if 'iseed' not in self.runCardDict: #if there is no setting in self.runCardDict for iseed
310 self.runCardDict['iseed'] = self.random_seed
311 if not self.isNLO and 'python_seed' not in self.runCardDict: #If the process is LO and there is no 'python_seed' setting in self.runCardDict
312 self.runCardDict['python_seed'] = self.random_seed
313 if 'beamenergy' in self.runCardDict: #if the beam energy is defined in self.runCardDict
314 raise RuntimeError('Do not set beamenergy in the run card. Use flags (or runArgs during migration) instead.')
315
316 if 'ebeam1' not in self.runCardDict or self.beamEnergy != self.runCardDict['ebeam1']: # if there is no setting 'ebeam1' in self.runCardDict
317 self.runCardDict['ebeam1'] = self.beamEnergy
318 if 'ebeam2' not in self.runCardDict or self.beamEnergy != self.runCardDict['ebeam2']: #if there is no setting 'ebeam2' in self.runCardDict
319 self.runCardDict['ebeam2'] = self.beamEnergy
320
321

◆ add_flags()

python.MGC.MGControl.add_flags ( self,
flags = None )
This function adds flag-derived seed and beam settings to self.runCardDict.

Definition at line 332 of file MGC.py.

332 def add_flags(self, flags=None):
333 """This function adds flag-derived seed and beam settings to self.runCardDict."""
334 if flags is not None:
335 self.get_flags_info(flags)
336
337 self._add_seed_and_beam_settings()
338
339

◆ add_runArgs()

python.MGC.MGControl.add_runArgs ( self,
runArgs = None )
This function adds run arguments to the self.runCardDict.
If the runArgs argument is left blank, the function will get the runArgs information before adding to the dictionary

Definition at line 322 of file MGC.py.

322 def add_runArgs(self, runArgs=None):
323 """This function adds run arguments to the self.runCardDict.
324 If the runArgs argument is left blank, the function will get the runArgs information before adding to the dictionary
325 """
326 if runArgs is not None:
327 self.get_runArgs_info(runArgs) # Use get_runArgs_info function to retrieve runArgs
328
329 self._add_seed_and_beam_settings()
330
331

◆ base_fragment_setup_check()

python.MGC.MGControl.base_fragment_setup_check ( self,
the_base_fragment,
extras,
isNLO )

Definition at line 648 of file MGC.py.

648 def base_fragment_setup_check(self,the_base_fragment,extras,isNLO):
649 # no include: allow it (with warning), as long as lhapdf is used
650 # if not (e.g. because no choice was made and the internal pdf ise used): error
651 if the_base_fragment is None:
652 mglog.warning('!!! No pdf base fragment was included in your job options. PDFs should be set with an include file. You might be unable to follow the PDF4LHC uncertainty prescription. Let\'s hope you know what you doing !!!')
653 if not extras.get('pdlabel', None) == 'lhapdf' or 'lhaid' not in extras:
654 mglog.warning('!!! No pdf base fragment was included in your job options and you did not specify a LHAPDF yourself -- in the future, this will cause an error !!!')
655 #TODO: in the future this should be an error
656 #raise RuntimeError('No pdf base fragment was included in your job options and you did not specify a LHAPDF yourself')
657 return True
658 else:
659 # if setting is already exactly as it should be -- great!
660 correct_settings=get_pdf_and_systematic_settings(the_base_fragment,isNLO)
661
662 allgood=True
663 for s in correct_settings:
664 if s is None and s in extras:
665 allgood=False
666 break
667 if s not in extras or extras[s]!=correct_settings[s]:
668 allgood=False
669 break
670 if allgood:
671 return True
672 # no error but also nothing set
673 return False
674
675

◆ compare_runCardCasing()

python.MGC.MGControl.compare_runCardCasing ( self)
This function checks that the casing in the run card dictionary is the same as the default run card.
It checks if the default setting appears, with the correct casing, in the updated card
If it isn't in the run card, if then checks if the default setting (in lower case) appears in the lowered (updated) card
Assuming that any inconsistencies have just lowered the casing of the setting, the function then attempts to resolve the inconsistency

Definition at line 457 of file MGC.py.

457 def compare_runCardCasing(self):
458 """This function checks that the casing in the run card dictionary is the same as the default run card.
459 It checks if the default setting appears, with the correct casing, in the updated card
460 If it isn't in the run card, if then checks if the default setting (in lower case) appears in the lowered (updated) card
461 Assuming that any inconsistencies have just lowered the casing of the setting, the function then attempts to resolve the inconsistency
462 """
463 # Put the run card aside for the moment
464 temp_run_card = self.runCardDict
465 # Make a list with all lower case settings
466 lower_card = [key.lower() for key in self.runCardDict]
467
468 # Get the default run card to compare to
469 self.getRunCardDict()
470
471 #check for all the default settings in the default run card
472 for default_setting in self.runCardDict:
473 #if the default setting appears in the updated run card (with the same casing), we skip
474 if default_setting in temp_run_card:
475 continue
476 elif default_setting.lower() in lower_card: # If the default setting isn't in the updated run card but is in the lower case dictionary
477 mglog.warning(f"The casing in the run card seems to be wrong for {default_setting}. We will try fix this now.")
478
479 try: #want to try fixing this so we will assume that the settings has accidently been made lower-case
480 temp_run_card[default_setting] = temp_run_card[default_setting.lower()]
481 temp_run_card.pop(default_setting.lower())
482 except KeyError: #if that doesn't work we raise an error
483 self.runCardDict = temp_run_card #(just to make it easier to find the updated run card
484 raise RuntimeError("Run Card Dictionary casing is inconsistent")
485 else:
486 continue
487 # finally, lets put the run card back
488 self.runCardDict = temp_run_card
489 mglog.info('Run card casing looks good!')
490

◆ get_config_cardloc()

python.MGC.MGControl.get_config_cardloc ( self)
Gets the config card location and determines if the process is LO or NLO
This function takes in the process diectory as an input and uses it to find the configuration.
Using the path to the config path, we can determine if the process will require a LO or NLO configuration.

Definition at line 223 of file MGC.py.

223 def get_config_cardloc(self):
224 """Gets the config card location and determines if the process is LO or NLO
225 This function takes in the process diectory as an input and uses it to find the configuration.
226 Using the path to the config path, we can determine if the process will require a LO or NLO configuration.
227 """
228 self.isNLO = None
229 #Defining the possible config paths
230 lo_config_card = self.process_dir+'/Cards/me5_configuration.txt'
231 nlo_config_card = self.process_dir+'/Cards/amcatnlo_configuration.txt'
232
233 if os.access(lo_config_card,os.R_OK) and not os.access(nlo_config_card,os.R_OK): #Process is LO
234 self.config_path = lo_config_card
235 self.isNLO = False
236 elif os.access(nlo_config_card,os.R_OK) and not os.access(lo_config_card,os.R_OK): #Process is NLO
237 self.config_path = nlo_config_card
238 self.isNLO = True
239 elif os.access(nlo_config_card,os.R_OK) and os.access(lo_config_card,os.R_OK): #Process has two config cards
240 mglog.error('Found both types of config card in '+str(self.process_dir))
241 raise RuntimeError('Unable to locate configuration card')
242 else: # No config Card
243 mglog.error('No config card in '+str(self.process_dir))
244 raise RuntimeError('Unable to locate configuration card')
245
246

◆ get_flags_info()

python.MGC.MGControl.get_flags_info ( self,
flags )
This function gets the beam energy and random seed from the configuration flags.

Definition at line 289 of file MGC.py.

289 def get_flags_info(self, flags):
290 """This function gets the beam energy and random seed from the configuration flags."""
291 if flags is None:
292 raise RuntimeError('flags must be provided!')
293
294 # Beam energy is stored in Athena units (MeV). Convert back to GeV for MadGraph run cards.
295 try:
296 self.beamEnergy = float(flags.Beam.Energy) / GeV
297 except AttributeError as e:
298 raise RuntimeError("No beam energy found in flags (expected flags.Beam.Energy).") from e
299
300 try:
301 self.random_seed = flags.Random.SeedOffset
302 except AttributeError as e:
303 raise RuntimeError("No random seed found in flags (expected flags.Random.SeedOffset).") from e
304
305

◆ get_runArgs_info()

python.MGC.MGControl.get_runArgs_info ( self,
runArgs )
This function gets the beam energy and random seed from the runArguments 

Definition at line 271 of file MGC.py.

271 def get_runArgs_info(self,runArgs):
272 """This function gets the beam energy and random seed from the runArguments
273 """
274
275 if runArgs is None:
276 raise RuntimeError('runArgs must be provided!')
277 #Get Beam Energy
278 if hasattr(runArgs,'ecmEnergy'):
279 self.beamEnergy = runArgs.ecmEnergy / 2.
280 else:
281 raise RuntimeError("No center of mass energy found in runArgs.")
282 #Get random seed
283 if hasattr(runArgs,'randomSeed'):
284 self.random_seed = runArgs.randomSeed
285 else:
286 raise RuntimeError("No random seed found in runArgs.")
287
288

◆ getCA()

python.MGC.MGControl.getCA ( self,
flags = None )
Boilerplate code that returns a bare CA fragment.
To be used in MadGraphConfig.py

Definition at line 676 of file MGC.py.

676 def getCA(self, flags=None):
677 """Boilerplate code that returns a bare CA fragment.
678 To be used in MadGraphConfig.py"""
679 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
680 from GeneratorConfig.Sequences import EvgenSequence, EvgenSequenceFactory
681
682 ca = ComponentAccumulator(EvgenSequenceFactory(EvgenSequence.Generator))
683
684 return ca

◆ getConfigFromPath()

python.MGC.MGControl.getConfigFromPath ( self,
card_loc,
lowercase = False )
Builds a dictionary from the config card.
This function creates a dictionary object configCardDict from the config card.
Using the config card location, we copy over th settings to the dictionary.
Note: This function is works in the same way as self.getRunCardDict() however with small changes based on how the card is written.

Definition at line 247 of file MGC.py.

247 def getConfigFromPath(self, card_loc, lowercase=False):
248 """Builds a dictionary from the config card.
249 This function creates a dictionary object configCardDict from the config card.
250 Using the config card location, we copy over th settings to the dictionary.
251 Note: This function is works in the same way as self.getRunCardDict() however with small changes based on how the card is written.
252 """
253 card = open(card_loc)
254 #define the configCardDict object
255 self.configCardDict = {}
256 for line in iter(card):
257 if not line.strip().startswith('#'): # Ignore lines that are commented out
258 command = line.split('!', 1)[0]
259 if '=' in command:
260 # Here is where we differ from self.getRunCardDict(), the config card has the setting to the left of the '=' and value to the right
261 value = command.split('=')[-1].strip()
262 setting = '='.join(command.split('=')[:-1]).strip()
263
264 if lowercase:
265 value = value.lower()
266 setting = setting.lower()
267 self.configCardDict[setting] = value # adds setting to the configCardDict
268 card.close()
269
270

◆ getRunCardDict()

python.MGC.MGControl.getRunCardDict ( self,
lowercase = False )
Builds a dictionary from the run card.
This function takes in the card location and saves the contents as a dictionary object in the MGControl class.

Definition at line 193 of file MGC.py.

193 def getRunCardDict(self,lowercase=False):
194 """Builds a dictionary from the run card.
195 This function takes in the card location and saves the contents as a dictionary object in the MGControl class.
196 """
197 run_card = self.process_dir + '/Cards/run_card.dat'
198
199 if os.access(run_card,os.R_OK):
200 mglog.info('Copying default run_card.dat from '+str(run_card))
201 else:
202 run_card = self.process_dir+'/Cards/run_card_default.dat'
203 if os.access(run_card,os.R_OK):
204 mglog.info('Copying default run_card.dat from '+str(run_card))
205 else:
206 raise RuntimeError('Cannot find default run_card.dat or run_card_default.dat! I was looking here: %s'%run_card)
207
208 card = open(run_card)
209 self.runCardDict = {} # Define the dictionary object
210 for line in iter(card):
211 if not line.strip().startswith('#'): # Ignores line commented out
212 command = line.split('!', 1)[0]
213 if '=' in command:
214 setting = command.split('=')[-1].strip() #saves the setting
215 value = '='.join(command.split('=')[:-1]).strip() #saves the value associated with the setting
216 if lowercase:
217 value = value.lower()
218 setting = setting.lower()
219 self.runCardDict[setting] = value #adds setting and value to the dictionary
220 card.close()
221
222

◆ run_card_consistency_check()

python.MGC.MGControl.run_card_consistency_check ( self)
Checks the consistency of runCardDict.
This function should be called before writing runCardDict to disk to ensure that the run card is consistent and has appropriate settings.

Definition at line 491 of file MGC.py.

491 def run_card_consistency_check(self):
492 """Checks the consistency of runCardDict.
493 This function should be called before writing runCardDict to disk to ensure that the run card is consistent and has appropriate settings.
494 """
495 self.compare_runCardCasing()
496
497 # We should always use event_norm = average [AGENE-1725] otherwise Pythia cross sections are wrong
498 # Modification: average or bias is ok; sum is incorrect. Change the test to set sum to average
499 if self.runCardDict.get('event_norm',None) =='sum':
500 self.runCardDict['event_norm'] = 'average'
501 mglog.warning("setting event_norm to average, there is basically no use case where event_norm=sum is a good idea")
502
503 if not self.isNLO:
504 #Check CKKW-L setting
505 if 'ktdurham' in self.runCardDict and float(self.runCardDict['ktdurham']) > 0 and int(self.runCardDict['ickkw']) != 0:
506 log='Bad combination of settings for CKKW-L merging! ktdurham=%s and ickkw=%s.'%(self.runCardDict['ktdurham'],self.runCardDict['ickkw'])
507 mglog.error(log)
508 raise RuntimeError(log)
509
510 # Check if user is trying to use deprecated syscalc arguments with the other systematics script
511 if 'systematics_program' not in self.runCardDict or self.runCardDict['systematics_program']=='systematics': #if systematics are not set
512 syscalc_settings = ['sys_pdf', 'sys_scalefact', 'sys_alpsfact', 'sys_matchscale']
513 found_syscalc_setting = False
514 for s in syscalc_settings:
515 if s in self.runCardDict: #searches for the systematic setting in the runCard
516 mglog.warning('Using syscalc setting '+s+' with new systematics script. Systematics script is default from 2.6.2 and steered differently (https://cp3.irmp.ucl.ac.be/projects/madgraph/wiki/Systematics#Systematicspythonmodule)')
517 found_syscalc_setting = True
518 if found_syscalc_setting: #if a systematic setting was found
519 syst_arguments = convertSysCalcArguments(self.runCardDict)
520 mglog.info('Converted syscalc arguments to systematics arguments: '+syst_arguments)
521 syst_settings_update = {'systematics_arguments':syst_arguments} # save the system arguments to a dictionary
522 for s in syscalc_settings:
523 syst_settings_update[s] = None
524 self.runCardDict.update(syst_settings_update) #update the systematic settings
525
526 # Check pdf and systematics
527 mglog.info('Checking PDF and systematics settings')
528 if not self.base_fragment_setup_check(self.pdf_setting,self.runCardDict,self.isNLO): #if the base fragment has not been setup
529 # still need to set pdf and systematics
530 syst_settings = get_pdf_and_systematic_settings(self.pdf_setting,self.isNLO) # get the pdf and systemetatic settings as a dictionary
531 self.runCardDict.update(syst_settings) # update the settings in self.runCardDict
532
533 if 'systematics_arguments' in self.runCardDict:# if there are systematics set in the dictionary
534 systematics_arguments = parse_systematics_arguments(self.runCardDict['systematics_arguments'])
535 if 'weight_info' not in systematics_arguments: #if there is no event weighting information in the system arguments
536 mglog.info('Enforcing systematic weight name convention')
537 dyn = None
538 if '--dyn' in systematics_arguments or ' dyn' in systematics_arguments: #check if dynamics are set in the system arguments and sets dyn to that value.
539 if '--dyn' in systematics_arguments:
540 dyn = systematics_arguments.split('--dyn')[1]
541 if ' dyn' in systematics_arguments:
542 dyn = systematics_arguments.split(' dyn')[1]
543 dyn = dyn.replace('\'',' ').replace('=',' ').split()[0]
544 if dyn is not None and len(dyn.split(','))>1: #if there are dynamics defined, set event weights to acordingly
545 systematics_arguments['weight_info'] = SYSTEMATICS_WEIGHT_INFO_ALTDYNSCALES
546 else:
547 systematics_arguments['weight_info'] = SYSTEMATICS_WEIGHT_INFO
548 self.runCardDict['systematics_arguments'] = write_systematics_arguments(systematics_arguments)
549 # If the rocess is LO, we want to set a 'python_seed' in self.runCarDict
550 if not self.isNLO:
551 if 'python_seed' not in self.runCardDict:
552 mglog.warning('No python seed set in run_card -- adding one with same value as iseed')
553 self.runCardDict['python_seed'] = self.runCardDict['iseed'] # if there is no python_seed defined, set it to the same value as 'iseed'
554
555
556 # consistency check of 4/5 flavour shceme settings
557 FS_updates={}
558 proton_5flav = False
559 jet_5flav = False
560 with open(self.process_dir+'/Cards/proc_card_mg5.dat', 'r') as file: # This will be updated at a later point when we have added a proc_card_mg5.dat dictionary
561 content = file.readlines()
562 #we want to read int he proc_card to determine if it is a 4 or 5 flavour scheme
563 for rawline in content:
564 line = rawline.split('#')[0] #ignore commented lines
565 if line.startswith("define p"): # if we define the quarks in a proton
566 if ('b' in line.split() and 'b~' in line.split()) or ('5' in line.split() and '-5' in line.split()):
567 #if there a b and anti b-quarks defined with p we set proton 5flavour scheme to be true
568 proton_5flav = True
569 if 'j' in line.split() and jet_5flav: #if jet is defined in the proton, set proton 5 flavour to be true
570 proton_5flav = True
571 if line.startswith("define j"): # if we are defining jets
572 if ('b' in line.split() and 'b~' in line.split()) or ('5' in line.split() and '-5' in line.split()):
573 # if b and anti b-quarks are defined in jets, set jet 5 flavour scheme to be true.
574 jet_5flav = True
575 if 'p' in line.split() and proton_5flav: # if p is defined in jets and proton has been set to 5 flavour scheme then jet_5flav = True
576 jet_5flav = True
577 if proton_5flav or jet_5flav: #If either of the proton or jet have been set to the 5 flavour scheme, set asrwgtflavour dictionary entry to 5
578 FS_updates['asrwgtflavor'] = 5
579 # Before continuing, we must ensure that both proton and jet have the same colour scheme. If they are inconsistent, we assume 5 flavour scheme.
580 if not proton_5flav:
581 mglog.warning('Found 5-flavour jets but 4-flavour proton. This is inconsistent - please pick one.')
582 mglog.warning('Will proceed assuming 5-flavour scheme.')
583 if not jet_5flav:
584 mglog.warning('Found 5-flavour protons but 4-flavour jets. This is inconsistent - please pick one.')
585 mglog.warning('Will proceed assuming 5-flavour scheme.')
586 else: # otherwise set to 4 flavour scheme
587 FS_updates['asrwgtflavor'] = 4
588
589 if len(FS_updates)==0: #if we cannot determine the flavour scheme
590 mglog.warning(f'Could not identify 4- or 5-flavor scheme from process card {self.process_dir}/Cards/proc_card_mg5.dat')
591
592 #check if there is a setting in self.runCardDict for flavour scheme
593 if 'asrwgtflavor' in self.runCardDict or 'maxjetflavor' in self.runCardDict or 'pdgs_for_merging_cut' in self.runCardDict:
594 if FS_updates['asrwgtflavor'] == 5:
595 # Process card says we are in the five-flavor scheme
596 if ('asrwgtflavor' in self.runCardDict and int(self.runCardDict['asrwgtflavor']) != 5) or ('maxjetflavor' in self.runCardDict and int(self.runCardDict['maxjetflavor']) != 5) or ('pdgs_for_merging_cut' in self.runCardDict and '5' not in self.runCardDict['pdgs_for_merging_cut']):
597 # Inconsistent setting detected; warn the users and correct the settings
598 mglog.warning('b and b~ included in p and j for 5-flavor scheme but run card settings are inconsistent; adjusting run card')
599 run_card_updates = {'asrwgtflavor': 5, 'maxjetflavor': 5, 'pdgs_for_merging_cut': '1, 2, 3, 4, 5, 21'}
600 #If there is an inconsistency, update to be consistent with Process card
601 self.runCardDict.update( run_card_updates )
602 modify_param_card(process_dir=self.process_dir, params={'MASS': {'5': '0.000000e+00'}})
603 else:
604 mglog.debug('Consistent 5-flavor scheme setup detected.')
605
606 if FS_updates['asrwgtflavor'] == 4:
607 # Process card says we are in the four-flavor scheme
608 if ('asrwgtflavor' in self.runCardDict and int(self.runCardDict['asrwgtflavor']) != 4) or ('maxjetflavor' in self.runCardDict and int(self.runCardDict['maxjetflavor']) != 4) or ('pdgs_for_merging_cut' in self.runCardDict and '5' in self.runCardDict['pdgs_for_merging_cut']):
609 # Inconsistent setting detected; warn the users and correct the settings
610 mglog.warning('b and b~ not included in p and j (4-flavor scheme) but run card settings are inconsistent; adjusting run card')
611 run_card_updates = {'asrwgtflavor': 4, 'maxjetflavor': 4, 'pdgs_for_merging_cut': '1, 2, 3, 4, 21'}
612 #update cards to be consistent with Process Card
613 self.runCardDict.update( run_card_updates )
614 modify_param_card(process_dir=self.process_dir, params={'MASS': {'5': '4.700000e+00'}})
615 else:
616 mglog.debug('Consistent 4-flavor scheme setup detected.')
617 else:
618 # Flavor scheme setup is missing, adding by hand
619 if FS_updates['asrwgtflavor'] == 4:
620 # Warn the users and add the settings according to process card
621 mglog.warning('Flavor scheme setup is missing, adding by hand according to process card - b and b~ not included in p and j, 4-flavor scheme setup will be used; adjusting run card.')
622 run_card_updates = {'asrwgtflavor': 4, 'maxjetflavor': 4, 'pdgs_for_merging_cut': '1, 2, 3, 4, 21'}
623 self.runCardDict.update( run_card_updates )
624 modify_param_card(process_dir=self.process_dir, params={'MASS': {'5': '4.700000e+00'}})
625 elif FS_updates['asrwgtflavor'] == 5:
626 mglog.warning('Flavor scheme setup is missing, adding by hand according to process card - b and b~ included in p and j, 5-flavor scheme setup will be used; adjusting run card.')
627 run_card_updates = {'asrwgtflavor': 5, 'maxjetflavor': 5, 'pdgs_for_merging_cut': '1, 2, 3, 4, 5, 21'}
628 self.runCardDict.update( run_card_updates )
629 modify_param_card(process_dir=self.process_dir, params={'MASS': {'5': '0.000000e+00'}})
630
631 # Check scale consistency
632 if '91.188' not in self.runCardDict.get('scale','91.188') and self.runCardDict.get('fixed_ren_scale','f').lower() in ['f','false']:
633 mglog.error('Seems you set "scale" in the run card without setting "fixed_ren_scale" to True. Not sure what to do here, throwing an error.')
634 raise ValueError("Renormalization scale setting incorrect")
635 if ('91.188' not in self.runCardDict.get('dsqrt_q2fact1','91.188') or '91.188' not in self.runCardDict.get('dsqrt_q2fact2','91.188')) \
636 and self.runCardDict.get('fixed_fac_scale','f').lower() in ['f','false']:
637 mglog.error('Seems you set "dsqrt_q2fact1" or "dsqrt_q2fact2" in the run card without setting "fixed_fac_scale" to True. Not sure what to do here, throwing an error.')
638 raise ValueError("Factorization scale setting incorrect")
639
640 mglog.info('Finished checking run card - All OK!')
641
642
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition hcg.cxx:312
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:132

◆ setup_path_protection()

python.MGC.MGControl.setup_path_protection ( self)

Definition at line 175 of file MGC.py.

175 def setup_path_protection(self):
176 # Addition for models directory
177
178 if 'PYTHONPATH' in os.environ:
179 if not any( [('Generators/madgraph/models' in x) for x in os.environ['PYTHONPATH'].split(':') ]):
180 os.environ['PYTHONPATH'] += ':/cvmfs/atlas.cern.ch/repo/sw/Generators/madgraph/models/latest'
181 self.MADGRAPH_COMMAND_STACK += ['export PYTHONPATH=${PYTHONPATH}:/cvmfs/atlas.cern.ch/repo/sw/Generators/madgraph/models/latest']
182 # Make sure that gfortran doesn't write to somewhere it shouldn't
183 if 'GFORTRAN_TMPDIR' in os.environ:
184 return
185 if 'TMPDIR' in os.environ:
186 os.environ['GFORTRAN_TMPDIR']=os.environ['TMPDIR']
187 self.MADGRAPH_COMMAND_STACK += ['export GFORTRAN_TMPDIR=${TMPDIR}']
188 return
189 if 'TMP' in os.environ:
190 os.environ['GFORTRAN_TMPDIR']=os.environ['TMP']
191 self.MADGRAPH_COMMAND_STACK += ['export GFORTRAN_TMPDIR=${TMP}']
192

◆ write_configCard()

python.MGC.MGControl.write_configCard ( self)
Build a new configuration from a config card dictionary.
This function can get a fresh runcard from the configCardDict object.
This function behaves similaraly to self.write_runCard()

Definition at line 429 of file MGC.py.

429 def write_configCard(self):
430 """Build a new configuration from a config card dictionary.
431 This function can get a fresh runcard from the configCardDict object.
432 This function behaves similaraly to self.write_runCard()
433 """
434 mglog.info('Writing config card in '+self.process_dir)
435
436 #change name of old config card to avoid writing over
437 config_pathOLD = self.config_path+'.old_to_be_deleted'
438 os.rename(self.config_path, config_pathOLD) # change name of original card
439
440 # create new config card
441 newCard = open(self.config_path, 'w')
442 for setting in self.configCardDict:
443 if self.configCardDict[setting] is None: # ignore empty settings
444 continue
445 mglog.info('Writing option '+setting+' to the config card. Adding a setting to '+str(self.configCardDict[setting]))
446 newCard.write(' '+str(setting)+' = '+str(self.configCardDict[setting])+'\n') #writing config card in the format setting = value
447
448 # close file
449 newCard.close()
450
451 mglog.info('Finished writing to config card.')
452
453 os.unlink(config_pathOLD) # delete old file
454
455
456

◆ write_runCard()

python.MGC.MGControl.write_runCard ( self,
runArgs = None,
flags = None )
Build a new run_card.dat from a run card dictionary.
This function can get a fresh run card from the runCardDict object.
Before writing the dictionary to the run card, we require to check a few things first

Definition at line 340 of file MGC.py.

340 def write_runCard(self, runArgs=None, flags=None):
341 """Build a new run_card.dat from a run card dictionary.
342 This function can get a fresh run card from the runCardDict object.
343 Before writing the dictionary to the run card, we require to check a few things first
344 """
345
346 # Get seed and beam information from either runArgs or flags.
347 if flags is not None:
348 if runArgs is not None:
349 mglog.warning('Both runArgs and flags were provided to write_runCard. Using flags.')
350 self.add_flags(flags)
351 else:
352 self.add_runArgs(runArgs)
353
354 # Make sure that nevents is integer
355 if 'nevents' in self.runCardDict:
356 self.runCardDict['nevents'] = int(self.runCardDict['nevents'])
357
358 # Normalise custom_fcts early so the rewritten run_card uses the full path
359 if 'custom_fcts' in self.runCardDict and self.runCardDict['custom_fcts']:
360 raw_name = str(self.runCardDict['custom_fcts']).split()[0]
361 # Determine jobConfig directory
362 cfgdir = None
363 if flags is not None and hasattr(flags, 'Generator') and hasattr(flags.Generator, 'jobConfig') and flags.Generator.jobConfig:
364 cfgdir = flags.Generator.jobConfig[0] if isinstance(flags.Generator.jobConfig, (list, tuple)) else flags.Generator.jobConfig
365 elif runArgs is not None and hasattr(runArgs, 'jobConfig'):
366 cfgdir = runArgs.jobConfig[0] if isinstance(runArgs.jobConfig, (list, tuple)) else runArgs.jobConfig
367 elif flags is not None and 'JOBOPTSEARCHPATH' in os.environ:
368 cfgdir = os.environ['JOBOPTSEARCHPATH'].split(':')[0]
369
370 if cfgdir:
371 # Build full path and make absolute
372 full_path = os.path.join(cfgdir, raw_name)
373 self.runCardDict['custom_fcts'] = os.path.abspath(full_path)
374 mglog.info(f"Using custom function(s), specified in custom_fcts with path: {self.runCardDict['custom_fcts']}")
375 else:
376 # For internal tests, where jobConfig is not set
377 self.runCardDict['custom_fcts'] = os.path.abspath(raw_name)
378
379 # to avoid writing over the old run card, we rename the old card
380 runCard_old = self.process_dir+'/Cards/run_card.dat.old_to_be_deleted'
381 os.rename(self.process_dir+'/Cards/run_card.dat', runCard_old)
382
383 listSettings = []
384
385 # Read in old run card, we want to copy over the comments
386 # Then create a new run card in the same location as the old card
387 with open(runCard_old) as oldCard, open(self.process_dir+'/Cards/run_card.dat', 'w') as newCard:
388 for line in iter(oldCard):
389 #if the line starts with a '#' (ie. is a comment) copy it straight over
390 if line.strip().startswith('#'):
391 newCard.write(line)
392 else: #if not we want to grab the comment after the '!' as well as the associated command (before '!')
393 command= line.split('!',1)[0]
394 if len(line.split('!',1)) > 1:
395 comment= line.split('!',1)[1]
396 else:
397 comment = '\n'
398 if '=' in command:
399 setting = command.split('=')[-1].strip()
400 # Check if the setting is in the dictionary and then print with the comment and the updated value
401 if setting in self.runCardDict:
402 newCard.write( ' '+str(self.runCardDict[setting])+' = '+str(setting)+' ! '+ comment)
403 listSettings.append(str(setting))
404 else:
405 raise RuntimeError('Could not find '+str(setting)+' in the Run Card Dictionary!')
406 else:
407 newCard.write(line)
408 # Add a commented region
409 newCard.write("""#***********************************************************************
410# Any Additional settings can be added here *
411#***********************************************************************
412""")
413
414 #check that all settings have been writen
415 for setting in self.runCardDict:
416 if setting not in listSettings:
417 newCard.write( ' '+str(self.runCardDict[setting])+' = '+str(setting)+'\n')
418
419 # Check whether mcatnlo_delta is applied to setup pythia8 path
420 if 'mcatnlo_delta' in self.runCardDict:
421 if self.runCardDict['mcatnlo_delta'] == 'True':
422 self.configCardDict['pythia8_path'] = os.getenv("PY8PATH")
423 # TODO: this will require our writing out the config card again
424
425 # Tidy up after ourselves
426 mglog.info('Finished writing to run card.')
427 os.unlink(runCard_old) # delete old backup
428

Member Data Documentation

◆ beamEnergy

int python.MGC.MGControl.beamEnergy = 0

Definition at line 53 of file MGC.py.

◆ catch_errors

python.MGC.MGControl.catch_errors = MADGRAPH_CATCH_ERRORS if catch_errors is None else catch_errors

Definition at line 51 of file MGC.py.

◆ config_path

python.MGC.MGControl.config_path

Definition at line 141 of file MGC.py.

◆ configCardDict

dict python.MGC.MGControl.configCardDict = {}

Definition at line 255 of file MGC.py.

◆ devices

python.MGC.MGControl.devices = MADGRAPH_DEVICES if devices is None else devices

Definition at line 50 of file MGC.py.

◆ is_gen_from_gridpack

python.MGC.MGControl.is_gen_from_gridpack = os.access(MADGRAPH_GRIDPACK_LOCATION,os.R_OK)

Definition at line 55 of file MGC.py.

◆ isNLO

python.MGC.MGControl.isNLO

Definition at line 150 of file MGC.py.

◆ keepJpegs

python.MGC.MGControl.keepJpegs = keepJpegs

Definition at line 47 of file MGC.py.

◆ MADGRAPH_COMMAND_STACK

list python.MGC.MGControl.MADGRAPH_COMMAND_STACK = []

Definition at line 87 of file MGC.py.

◆ mglog

python.MGC.MGControl.mglog = Logging.logging.getLogger('MadGraphUtils')

Definition at line 44 of file MGC.py.

◆ pdf_setting

python.MGC.MGControl.pdf_setting = MADGRAPH_PDFSETTING if pdf_setting is None else pdf_setting

Definition at line 49 of file MGC.py.

◆ plugin

python.MGC.MGControl.plugin = plugin

Definition at line 46 of file MGC.py.

◆ process

python.MGC.MGControl.process = process

Definition at line 45 of file MGC.py.

◆ process_dir

python.MGC.MGControl.process_dir = MADGRAPH_GRIDPACK_LOCATION

Definition at line 58 of file MGC.py.

◆ random_seed

python.MGC.MGControl.random_seed = runArgs.randomSeed

Definition at line 284 of file MGC.py.

◆ run_card_params

list python.MGC.MGControl.run_card_params = []

Definition at line 52 of file MGC.py.

◆ runCardDict

python.MGC.MGControl.runCardDict = {}

Definition at line 209 of file MGC.py.

◆ usePMGSettings

python.MGC.MGControl.usePMGSettings = usePMGSettings

Definition at line 48 of file MGC.py.


The documentation for this class was generated from the following file: