11import os,time,subprocess,glob
12from AthenaCommon
import Logging
13from AthenaCommon.SystemOfUnits
import GeV
14from MadGraphControl.MadGraphUtilsHelpers
import error_check
15from MadGraphControl.MGClassParamHelpers
import do_PMG_updates
16from MadGraphControl.MadGraphSystematicsUtils
import convertSysCalcArguments,get_pdf_and_systematic_settings,parse_systematics_arguments,SYSTEMATICS_WEIGHT_INFO_ALTDYNSCALES,SYSTEMATICS_WEIGHT_INFO,write_systematics_arguments
19mglog = Logging.logging.getLogger(
'MadGraphUtils')
24MADGRAPH_GRIDPACK_LOCATION =
'madevent'
26MADGRAPH_RUN_NAME =
'run_01'
28MADGRAPH_CATCH_ERRORS =
True
30MADGRAPH_PDFSETTING =
None
36MADGRAPH_DEVICES =
None
40 def __init__(self, process=None, plugin=None, keepJpegs=False, usePMGSettings=False, pdf_setting=None, devices=None, catch_errors=MADGRAPH_CATCH_ERRORS):
42 """ Generate a new process in madgraph.
43 Pass a process string.
44 Optionally request JPEGs to be kept and request for PMG settings to be used in the param card
45 Return the name of the process directory.
47 self.
mglog = Logging.logging.getLogger(
'MadGraphUtils')
52 self.
pdf_setting = MADGRAPH_PDFSETTING
if pdf_setting
is None else pdf_setting
53 self.
devices = MADGRAPH_DEVICES
if devices
is None else devices
54 self.
catch_errors = MADGRAPH_CATCH_ERRORS
if catch_errors
is None else catch_errors
79 card_loc =
'proc_card_mg5.dat'
80 mglog.info(
'Writing process card to '+card_loc)
81 a_card = open( card_loc ,
'w' )
82 for l
in process.split(
'\n'):
88 if '-nojpeg' not in l
and not keepJpegs:
91 outline = outline.split(
'#')[0]+
' -nojpeg #'+outline.split(
'#')[1]
93 outline = outline +
' -nojpeg'
96 if self.
devices.lower()
in [
'madevent_simd',
'madevent_gpu']:
97 outline =
'output '+self.
devices.lower()+
' '+outline.split(
'output')[1]
98 elif self.
devices.lower() ==
'max':
99 self.
mglog.warning(
'Not fully implemented yet; setting avx')
100 outline =
'output madevent_simd '+outline.split(
'output')[1]
101 a_card.write(outline+
'\n')
104 madpath = os.environ[
'MADPATH']
108 for l
in process.split(
'\n'):
110 if 'output' not in l.split(
'#')[0].
split():
113 tmplist = l.split(
'#')[0].
split(
' -')[0]
115 if len(tmplist.split())==2:
116 process_dir = tmplist.split()[1]
118 elif len(tmplist.split())==3:
119 process_dir = tmplist.split()[2]
122 mglog.info(
'Saw that you asked for a special output directory: '+str(process_dir))
125 mglog.info(
'Started process generation at '+str(time.asctime()))
127 plugin_cmd =
'--mode='+plugin
if plugin
is not None else ''
133 self.
MADGRAPH_COMMAND_STACK += [
' '.join([python,madpath+
'/bin/mg5_aMC '+plugin_cmd+
' << EOF\n'+process+
'\nEOF\n'])]
134 generate = subprocess.Popen([python,madpath+
'/bin/mg5_aMC',plugin_cmd,card_loc],stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
135 (out,err) = generate.communicate()
136 error_check(err,generate.returncode)
138 mglog.info(
'Finished process generation at '+str(time.asctime()))
141 if process_dir ==
'':
142 for adir
in sorted(glob.glob( os.getcwd()+
'/*PROC*' ),reverse=
True):
143 if os.access(
'%s/SubProcesses/subproc.mg'%adir,os.R_OK):
147 mglog.warning(
'Additional possible process directory, '+adir+
' found. Had '+process_dir)
148 mglog.warning(
'Likely this is because you did not run from a clean directory, and this may cause errors later.')
150 if not os.access(
'%s/SubProcesses/subproc.mg'%process_dir,os.R_OK):
151 raise RuntimeError(
'No diagrams for this process in user-define dir='+str(process_dir))
153 raise RuntimeError(
'No diagrams for this process from list: '+str(sorted(glob.glob(os.getcwd()+
'/*PROC*'),reverse=
True)))
170 mglog.info(
'Setting default sde_strategy to old default (1)')
178 if self.
devices.lower()==
'madevent_simd':
180 elif self.
devices.lower()==
'madevent_gpu':
184 os.environ[
'ALLOW_UNSUPPORTED_COMPILER_IN_CUDA'] =
'Y'
185 elif self.
devices.lower() ==
'max':
186 self.
mglog.warning(
'Not fully implemented yet; setting avx')
197 if 'PYTHONPATH' in os.environ:
198 if not any( [(
'Generators/madgraph/models' in x)
for x
in os.environ[
'PYTHONPATH'].
split(
':') ]):
199 os.environ[
'PYTHONPATH'] +=
':/cvmfs/atlas.cern.ch/repo/sw/Generators/madgraph/models/latest'
200 self.
MADGRAPH_COMMAND_STACK += [
'export PYTHONPATH=${PYTHONPATH}:/cvmfs/atlas.cern.ch/repo/sw/Generators/madgraph/models/latest']
202 if 'GFORTRAN_TMPDIR' in os.environ:
204 if 'TMPDIR' in os.environ:
205 os.environ[
'GFORTRAN_TMPDIR']=os.environ[
'TMPDIR']
208 if 'TMP' in os.environ:
209 os.environ[
'GFORTRAN_TMPDIR']=os.environ[
'TMP']
213 """Builds a dictionary from the run card.
214 This function takes in the card location and saves the contents as a dictionary object in the MGControl class.
216 run_card = self.
process_dir +
'/Cards/run_card.dat'
218 if os.access(run_card,os.R_OK):
219 mglog.info(
'Copying default run_card.dat from '+str(run_card))
221 run_card = self.
process_dir+
'/Cards/run_card_default.dat'
222 if os.access(run_card,os.R_OK):
223 mglog.info(
'Copying default run_card.dat from '+str(run_card))
225 raise RuntimeError(
'Cannot find default run_card.dat or run_card_default.dat! I was looking here: %s'%run_card)
227 card = open(run_card)
229 for line
in iter(card):
230 if not line.strip().startswith(
'#'):
231 command = line.split(
'!', 1)[0]
233 setting = command.split(
'=')[-1].
strip()
234 value =
'='.join(command.split(
'=')[:-1]).
strip()
236 value = value.lower()
237 setting = setting.lower()
243 """Gets the config card location and determines if the process is LO or NLO
244 This function takes in the process diectory as an input and uses it to find the configuration.
245 Using the path to the config path, we can determine if the process will require a LO or NLO configuration.
249 lo_config_card = self.
process_dir+
'/Cards/me5_configuration.txt'
250 nlo_config_card = self.
process_dir+
'/Cards/amcatnlo_configuration.txt'
252 if os.access(lo_config_card,os.R_OK)
and not os.access(nlo_config_card,os.R_OK):
255 elif os.access(nlo_config_card,os.R_OK)
and not os.access(lo_config_card,os.R_OK):
258 elif os.access(nlo_config_card,os.R_OK)
and os.access(lo_config_card,os.R_OK):
259 mglog.error(
'Found both types of config card in '+str(self.
process_dir))
260 raise RuntimeError(
'Unable to locate configuration card')
262 mglog.error(
'No config card in '+str(self.
process_dir))
263 raise RuntimeError(
'Unable to locate configuration card')
267 """Builds a dictionary from the config card.
268 This function creates a dictionary object configCardDict from the config card.
269 Using the config card location, we copy over th settings to the dictionary.
270 Note: This function is works in the same way as self.getRunCardDict() however with small changes based on how the card is written.
272 card = open(card_loc)
275 for line
in iter(card):
276 if not line.strip().startswith(
'#'):
277 command = line.split(
'!', 1)[0]
280 value = command.split(
'=')[-1].
strip()
281 setting =
'='.join(command.split(
'=')[:-1]).
strip()
284 value = value.lower()
285 setting = setting.lower()
291 """This function gets the beam energy and random seed from the runArguments
295 raise RuntimeError(
'runArgs must be provided!')
297 if hasattr(runArgs,
'ecmEnergy'):
300 raise RuntimeError(
"No center of mass energy found in runArgs.")
302 if hasattr(runArgs,
'randomSeed'):
305 raise RuntimeError(
"No random seed found in runArgs.")
309 """This function gets the beam energy and random seed from the configuration flags."""
311 raise RuntimeError(
'flags must be provided!')
315 self.
beamEnergy = float(flags.Beam.Energy) / GeV
316 except AttributeError
as e:
317 raise RuntimeError(
"No beam energy found in flags (expected flags.Beam.Energy).")
from e
321 except AttributeError
as e:
322 raise RuntimeError(
"No random seed found in flags (expected flags.Random.SeedOffset).")
from e
326 """Add seed and beam settings to runCardDict."""
332 raise RuntimeError(
'Do not set beamenergy in the run card. Use flags (or runArgs during migration) instead.')
341 """This function adds run arguments to the self.runCardDict.
342 If the runArgs argument is left blank, the function will get the runArgs information before adding to the dictionary
344 if runArgs
is not None:
351 """This function adds flag-derived seed and beam settings to self.runCardDict."""
352 if flags
is not None:
359 """Build a new run_card.dat from a run card dictionary.
360 This function can get a fresh run card from the runCardDict object.
361 Before writing the dictionary to the run card, we require to check a few things first
365 if flags
is not None:
366 if runArgs
is not None:
367 mglog.warning(
'Both runArgs and flags were provided to write_runCard. Using flags.')
381 if flags
is not None and hasattr(flags,
'Generator')
and hasattr(flags.Generator,
'jobConfig')
and flags.Generator.jobConfig:
382 cfgdir = flags.Generator.jobConfig[0]
if isinstance(flags.Generator.jobConfig, (list, tuple))
else flags.Generator.jobConfig
383 elif runArgs
is not None and hasattr(runArgs,
'jobConfig'):
384 cfgdir = runArgs.jobConfig[0]
if isinstance(runArgs.jobConfig, (list, tuple))
else runArgs.jobConfig
385 elif flags
is not None and 'JOBOPTSEARCHPATH' in os.environ:
386 cfgdir = os.environ[
'JOBOPTSEARCHPATH'].
split(
':')[0]
390 full_path = os.path.join(cfgdir, raw_name)
391 self.
runCardDict[
'custom_fcts'] = os.path.abspath(full_path)
392 mglog.info(f
"Using custom function(s), specified in custom_fcts with path: {self.runCardDict['custom_fcts']}")
395 self.
runCardDict[
'custom_fcts'] = os.path.abspath(raw_name)
398 runCard_old = self.
process_dir+
'/Cards/run_card.dat.old_to_be_deleted'
399 os.rename(self.
process_dir+
'/Cards/run_card.dat', runCard_old)
405 with open(runCard_old)
as oldCard, open(self.
process_dir+
'/Cards/run_card.dat',
'w')
as newCard:
406 for line
in iter(oldCard):
408 if line.strip().startswith(
'#'):
411 command= line.split(
'!',1)[0]
412 if len(line.split(
'!',1)) > 1:
413 comment= line.split(
'!',1)[1]
417 setting = command.split(
'=')[-1].
strip()
420 newCard.write(
' '+str(self.
runCardDict[setting])+
' = '+str(setting)+
' ! '+ comment)
421 listSettings.append(str(setting))
423 raise RuntimeError(
'Could not find '+str(setting)+
' in the Run Card Dictionary!')
427 newCard.write(
"""#***********************************************************************
428# Any Additional settings can be added here *
429#***********************************************************************
434 if setting
not in listSettings:
435 newCard.write(
' '+str(self.
runCardDict[setting])+
' = '+str(setting)+
'\n')
444 mglog.info(
'Finished writing to run card.')
445 os.unlink(runCard_old)
448 """Build a new configuration from a config card dictionary.
449 This function can get a fresh runcard from the configCardDict object.
450 This function behaves similaraly to self.write_runCard()
452 mglog.info(
'Writing config card in '+self.
process_dir)
455 config_pathOLD = self.
config_path+
'.old_to_be_deleted'
463 mglog.info(
'Writing option '+setting+
' to the config card. Adding a setting to '+str(self.
configCardDict[setting]))
464 newCard.write(
' '+str(setting)+
' = '+str(self.
configCardDict[setting])+
'\n')
469 mglog.info(
'Finished writing to config card.')
471 os.unlink(config_pathOLD)
476 """This function checks that the casing in the run card dictionary is the same as the default run card.
477 It checks if the default setting appears, with the correct casing, in the updated card
478 If it isn't in the run card, if then checks if the default setting (in lower case) appears in the lowered (updated) card
479 Assuming that any inconsistencies have just lowered the casing of the setting, the function then attempts to resolve the inconsistency
484 lower_card = [key.lower()
for key
in self.
runCardDict]
492 if default_setting
in temp_run_card:
494 elif default_setting.lower()
in lower_card:
495 mglog.warning(f
"The casing in the run card seems to be wrong for {default_setting}. We will try fix this now.")
498 temp_run_card[default_setting] = temp_run_card[default_setting.lower()]
499 temp_run_card.pop(default_setting.lower())
502 raise RuntimeError(
"Run Card Dictionary casing is inconsistent")
507 mglog.info(
'Run card casing looks good!')
510 """Checks the consistency of runCardDict.
511 This function should be called before writing runCardDict to disk to ensure that the run card is consistent and has appropriate settings.
519 mglog.warning(
"setting event_norm to average, there is basically no use case where event_norm=sum is a good idea")
524 log=
'Bad combination of settings for CKKW-L merging! ktdurham=%s and ickkw=%s.'%(self.
runCardDict[
'ktdurham'],self.
runCardDict[
'ickkw'])
526 raise RuntimeError(log)
529 if 'systematics_program' not in self.
runCardDict or self.
runCardDict[
'systematics_program']==
'systematics':
530 syscalc_settings = [
'sys_pdf',
'sys_scalefact',
'sys_alpsfact',
'sys_matchscale']
531 found_syscalc_setting =
False
532 for s
in syscalc_settings:
534 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)')
535 found_syscalc_setting =
True
536 if found_syscalc_setting:
537 syst_arguments = convertSysCalcArguments(self.
runCardDict)
538 mglog.info(
'Converted syscalc arguments to systematics arguments: '+syst_arguments)
539 syst_settings_update = {
'systematics_arguments':syst_arguments}
540 for s
in syscalc_settings:
541 syst_settings_update[s] =
None
545 mglog.info(
'Checking PDF and systematics settings')
548 syst_settings = get_pdf_and_systematic_settings(self.
pdf_setting,self.
isNLO)
552 systematics_arguments = parse_systematics_arguments(self.
runCardDict[
'systematics_arguments'])
553 if 'weight_info' not in systematics_arguments:
554 mglog.info(
'Enforcing systematic weight name convention')
556 if '--dyn' in systematics_arguments
or ' dyn' in systematics_arguments:
557 if '--dyn' in systematics_arguments:
558 dyn = systematics_arguments.split(
'--dyn')[1]
559 if ' dyn' in systematics_arguments:
560 dyn = systematics_arguments.split(
' dyn')[1]
562 if dyn
is not None and len(dyn.split(
','))>1:
563 systematics_arguments[
'weight_info'] = SYSTEMATICS_WEIGHT_INFO_ALTDYNSCALES
565 systematics_arguments[
'weight_info'] = SYSTEMATICS_WEIGHT_INFO
566 self.
runCardDict[
'systematics_arguments'] = write_systematics_arguments(systematics_arguments)
570 mglog.warning(
'No python seed set in run_card -- adding one with same value as iseed')
578 with open(self.
process_dir+
'/Cards/proc_card_mg5.dat',
'r')
as file:
579 content = file.readlines()
581 for rawline
in content:
582 line = rawline.split(
'#')[0]
583 if line.startswith(
"define p"):
584 if (
'b' in line.split()
and 'b~' in line.split())
or (
'5' in line.split()
and '-5' in line.split()):
587 if 'j' in line.split()
and jet_5flav:
589 if line.startswith(
"define j"):
590 if (
'b' in line.split()
and 'b~' in line.split())
or (
'5' in line.split()
and '-5' in line.split()):
593 if 'p' in line.split()
and proton_5flav:
595 if proton_5flav
or jet_5flav:
596 FS_updates[
'asrwgtflavor'] = 5
599 mglog.warning(
'Found 5-flavour jets but 4-flavour proton. This is inconsistent - please pick one.')
600 mglog.warning(
'Will proceed assuming 5-flavour scheme.')
602 mglog.warning(
'Found 5-flavour protons but 4-flavour jets. This is inconsistent - please pick one.')
603 mglog.warning(
'Will proceed assuming 5-flavour scheme.')
605 FS_updates[
'asrwgtflavor'] = 4
607 if len(FS_updates)==0:
608 mglog.warning(f
'Could not identify 4- or 5-flavor scheme from process card {self.process_dir}/Cards/proc_card_mg5.dat')
612 if FS_updates[
'asrwgtflavor'] == 5:
616 mglog.warning(
'b and b~ included in p and j for 5-flavor scheme but run card settings are inconsistent; adjusting run card')
617 run_card_updates = {
'asrwgtflavor': 5,
'maxjetflavor': 5,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 5, 21'}
620 self.
paramCard.modify_paramCardDict(params={
'MASS': {
'5':
'0.000000e+00'}})
622 mglog.debug(
'Consistent 5-flavor scheme setup detected.')
624 if FS_updates[
'asrwgtflavor'] == 4:
628 mglog.warning(
'b and b~ not included in p and j (4-flavor scheme) but run card settings are inconsistent; adjusting run card')
629 run_card_updates = {
'asrwgtflavor': 4,
'maxjetflavor': 4,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 21'}
632 self.
paramCard.modify_paramCardDict(params={
'MASS': {
'5':
'4.700000e+00'}})
634 mglog.debug(
'Consistent 4-flavor scheme setup detected.')
637 if FS_updates[
'asrwgtflavor'] == 4:
639 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.')
641 run_card_updates = {
'maxjetflavor': 4}
643 run_card_updates = {
'asrwgtflavor': 4,
'maxjetflavor': 4,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 21'}
646 self.
paramCard.modify_paramCardDict(params={
'MASS': {
'5':
'4.700000e+00'}})
647 elif FS_updates[
'asrwgtflavor'] == 5:
648 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.')
650 run_card_updates = {
'maxjetflavor': 5}
652 run_card_updates = {
'asrwgtflavor': 5,
'maxjetflavor': 5,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 5, 21'}
656 self.
paramCard.modify_paramCardDict(params={
'MASS': {
'5':
'0.000000e+00'}})
660 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.')
661 raise ValueError(
"Renormalization scale setting incorrect")
663 and self.
runCardDict.
get(
'fixed_fac_scale',
'f').lower()
in [
'f',
'false']:
664 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.')
665 raise ValueError(
"Factorization scale setting incorrect")
667 mglog.info(
'Finished checking run card - All OK!')
678 if the_base_fragment
is None:
679 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 !!!')
680 if not extras.get(
'pdlabel',
None) ==
'lhapdf' or 'lhaid' not in extras:
681 mglog.error(
'!!! No pdf base fragment was included in your job options and you did not specify a LHAPDF yourself')
682 raise RuntimeError(
'No pdf base fragment was included in your job options and you did not specify a LHAPDF yourself')
686 correct_settings=get_pdf_and_systematic_settings(the_base_fragment,isNLO)
689 for s
in correct_settings:
690 if s
is None and s
in extras:
693 if s
not in extras
or extras[s]!=correct_settings[s]:
703 """Boilerplate code that returns a bare CA fragment.
704 To be used in MadGraphConfig.py"""
705 from AthenaConfiguration.ComponentAccumulator
import ComponentAccumulator
706 from GeneratorConfig.Sequences
import EvgenSequence, EvgenSequenceFactory
708 ca = ComponentAccumulator(EvgenSequenceFactory(EvgenSequence.Generator))
715 def __init__(self, param_card_input=None, param_card_backup=None, process_dir=MADGRAPH_GRIDPACK_LOCATION,output_location=None):
717 if param_card_input
is None:
719 elif param_card_input
is not None and not os.access(param_card_input, os.R_OK):
733 mglog.info(
'Copying default param card from '+str(self.
paramCard_loc))
739 raise RuntimeError(
'Cannot find defualt param_card.dat or param_card_default.dat! I was looking here: %s'%self.
paramCard_loc)
741 with open(param_card,
'r')
as f:
744 param_blocks = card.split(
'\n\n')
747 for block
in param_blocks:
751 for line
in block.split(
'\n'):
752 if line.lower().startswith(
'block'):
753 if name
is not None and setting != {}:
756 name = line.split(
' ',1)[1].
strip()
759 elif line.startswith(
'#'):
761 elif line.lower().startswith(
'decay'):
765 data, separator, comment = l.partition(
'#')
766 columns = data.split()
769 key, value =
' '.join(columns[:-1]), columns[-1]
771 value +=
' # ' + comment.strip() +
' '
773 setting.update({key.strip() : value})
775 if name
is not None and setting != {}:
780 mglog.info(
"Successully read param_card.dat as a dictionary paramCardDict")
784 """ The DECAY parameters are written out differently in param_card.dat compared to the other parameter blocks
785 This funciton reads in the Decay parameters and adds them to the self.paramCardDict
790 mglog.info(
'Copying default param card from '+str(self.
paramCard_loc))
796 raise RuntimeError(
'You did not give a card location for reading in DECAY parameters and we cannot find defualt param_card.dat or param_card_default.dat! I was looking here: %s'%self.
paramCard_loc)
798 with open(cardloc,
'r')
as f:
801 param_lines = card.split(
'\n')
806 for line
in param_lines:
811 if l.lower().startswith(
'decay'):
812 decay = l[:5].
strip()
814 if key
is not None and value
is not None:
815 setting.update({key:value})
825 elif not l.lower().startswith(
'decay')
and not l ==
'\n' and key
is not None and value
is not None and not l.lower().startswith(
'block'):
827 value = value +
'\n' + l
828 elif l.lower().startswith(
'block')
and len(setting) != 0:
830 setting.update({key:value})
832 decay_params[decay] = setting
836 mglog.info(
"Successfully read in Decay parameters")
841 setting.update({key:value})
843 decay_params[decay] = setting
847 mglog.info(
"Successfully read in Decay parameters")
850 """ Simple function to update the paramCardDictionary that uses nested dictionaries.
851 The input params should also be a set of nested dictionaries
856 if block.strip().lower()
in dict_lower:
859 if block.strip().lower() == value.strip().lower():
862 for key
in params[block]:
866 elif len(k.split(
' ',1)) > 1:
867 new_k = k.split(
' ',1)[0].
strip() +
' ' + k.split(
' ',1)[1].
strip()
871 mglog.warning(
"Looks like the parameter "+str(block)+
" : "+str(key)+
" isn't in the parameter card dictionary. Adding now!")
877 if '# '+str(key)+
' ' in str(self.
paramCardDict[str(name)][str(value)]):
882 mglog.warning(
"Looks like the parameter "+str(block)+
" : "+str(key)+
" isn't in the parameter card dictionary. Adding now!")
890 """Write out paramCardDict to disk.
891 The function will copy the layout and format from the default card.
903 oldCard_blocks = oldCard.split(
'\n\n')
905 for block
in oldCard_blocks:
909 for line
in block.split(
'\n'):
911 if l.startswith(
'#'):
912 newCard.write(f
"{line} \n")
915 elif l.lower().startswith(
'block'):
916 if name
is not None and len(nParams) == len(self.
paramCardDict[name]):
920 elif name
is not None and len(nParams) != len(self.
paramCardDict[name]):
926 elif key
not in nParams:
927 newCard.write(f
" {key} {self.paramCardDict[name][key]}\n")
930 name = l.split(
' ',1)[1].
strip()
932 if name.lower()
not in dict_blocks:
933 raise RuntimeError(
"Cannot find %s in paramCardDict"%str(name))
936 if b.lower() == name.lower():
941 newCard.write(f
"Block {name}\n")
942 elif l.lower().startswith(
'decay'):
944 if name
is not None and name.lower() !=
'decay':
953 elif key
not in nParams:
954 newCard.write(f
" {key} {self.paramCardDict[name][key]}\n")
961 command = l[5:].
strip()
962 ID = command.split(
' ',1)[0]
965 newCard.write(f
"{self.paramCardDict[name][ID]} \n")
971 if name.lower() ==
'decay':
974 ID =
' '.join(l.partition(
'#')[0].
split()[:-1])
975 newCard.write(f
" {ID} {self.paramCardDict[name][ID]}\n")
980 if name
is not None and len(nParams) == len(self.
paramCardDict[name]):
984 elif name
is not None and len(nParams) != len(self.
paramCardDict[name]):
990 elif key
not in nParams
and key
is not None and key.strip() !=
'':
991 newCard.write(f
" {key} {self.paramCardDict[name][key]}\n")
993 elif key
is None or key.strip() ==
'':
996 mglog.info(
"Finished writing paramCardDict to param_card.dat")
compare_runCardCasing(self)
add_flags(self, flags=None)
get_runArgs_info(self, runArgs)
__init__(self, process=None, plugin=None, keepJpegs=False, usePMGSettings=False, pdf_setting=None, devices=None, catch_errors=MADGRAPH_CATCH_ERRORS)
_add_seed_and_beam_settings(self)
write_runCard(self, runArgs=None, flags=None)
setup_path_protection(self)
get_flags_info(self, flags)
base_fragment_setup_check(self, the_base_fragment, extras, isNLO)
list MADGRAPH_COMMAND_STACK
add_runArgs(self, runArgs=None)
run_card_consistency_check(self)
getConfigFromPath(self, card_loc, lowercase=False)
getRunCardDict(self, lowercase=False)
modify_paramCardDict(self, params={})
__init__(self, param_card_input=None, param_card_backup=None, process_dir=MADGRAPH_GRIDPACK_LOCATION, output_location=None)
read_decayParams(self, cardloc=None)
str paramCard_default_loc
std::string replace(std::string s, const std::string &s2, const std::string &s3)
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
std::vector< std::string > split(const std::string &s, const std::string &t=":")