9 import os,time,subprocess,glob,re,sys
11 from MCJobOptionUtils.LHAPDFsupport
import get_lhapdf_id_and_name
12 from MCJobOptionUtils.LHAPDFsupport
import get_LHAPDF_PATHS
13 from MCJobOptionUtils.JOsupport
import get_physics_short
14 from AthenaCommon
import Logging
15 from MadGraphControl.MGC
import MGControl
16 mglog = Logging.logging.getLogger(
'MadGraphUtils')
17 my_MGC_instance =
None
22 MADGRAPH_GRIDPACK_LOCATION=
'madevent'
24 MADGRAPH_RUN_NAME=
'run_01'
26 MADGRAPH_CATCH_ERRORS=
True
28 MADGRAPH_PDFSETTING=
None
29 MADGRAPH_COMMAND_STACK = []
31 patched_shutil_loc=
'/cvmfs/atlas.cern.ch/repo/sw/Generators/madgraph/models/latest/shutil_patch'
32 if 'PYTHONPATH' in os.environ
and patched_shutil_loc
not in os.environ[
'PYTHONPATH']:
35 os.environ[
'PYTHONPATH'] = patched_shutil_loc+
':'+os.environ[
'PYTHONPATH']
36 MADGRAPH_COMMAND_STACK += [
'export PYTHONPATH='+patched_shutil_loc+
':${PYTHONPATH}']
38 if 'shutil' in sys.modules:
39 sys.modules.pop(
'shutil')
41 sys.path.insert(0,patched_shutil_loc)
44 from MadGraphControl.MadGraphUtilsHelpers
import checkSettingExists,checkSetting,checkSettingIsTrue,getDictFromCard,get_runArgs_info,error_check,setup_path_protection,is_NLO_run,get_default_config_card
45 from MadGraphControl.MadGraphParamHelpers
import check_PMG_updates
48 global MADGRAPH_COMMAND_STACK
49 MADGRAPH_COMMAND_STACK += [
' '.
join(command)]
50 return subprocess.Popen(command,**kwargs)
57 global MADGRAPH_COMMAND_STACK
58 if not os.access(
'Cards_bkup',os.R_OK):
59 shutil.copytree(process_dir+
'/Cards',
'Cards_bkup')
60 shutil.copyfile(process_dir+
'/Source/make_opts',
'Cards_bkup/make_opts_bkup')
61 MADGRAPH_COMMAND_STACK += [
'# In case this fails, Cards_bkup should be in your original run directory']
62 MADGRAPH_COMMAND_STACK += [
'# And ${MGaMC_PROCESS_DIR} can be replaced with whatever process directory exists in your stand-alone test']
63 MADGRAPH_COMMAND_STACK += [
'cp '+os.getcwd()+
'/Cards_bkup/*dat ${MGaMC_PROCESS_DIR}/Cards/']
64 MADGRAPH_COMMAND_STACK += [
'cp '+os.getcwd()+
'/Cards_bkup/make_opts_bkup ${MGaMC_PROCESS_DIR}/Source/make_opts']
66 mglog.warning(
'Found Cards_bkup directory existing. Suggests you are either running generation twice (a little funny) or are not using a clean directory.')
68 while os.access(
'Cards_bkup_'+
str(bkup_v),os.R_OK)
and bkup_v<100:
71 shutil.copytree(process_dir+
'/Cards',
'Cards_bkup_'+
str(bkup_v))
72 shutil.copyfile(process_dir+
'/Source/make_opts',
'Cards_bkup_'+
str(bkup_v)+
'/make_opts_bkup')
73 MADGRAPH_COMMAND_STACK += [
'# In case this fails, Cards_bkup should be in your original run directory']
74 MADGRAPH_COMMAND_STACK += [
'# And ${MGaMC_PROCESS_DIR} can be replaced with whatever process directory exists in your stand-alone test']
75 MADGRAPH_COMMAND_STACK += [
'cp '+os.getcwd()+
'/Cards_bkup_'+
str(bkup_v)+
'/*dat ${MGaMC_PROCESS_DIR}/Cards/']
76 MADGRAPH_COMMAND_STACK += [
'cp '+os.getcwd()+
'/Cards_bkup_'+
str(bkup_v)+
'/make_opts_bkup ${MGaMC_PROCESS_DIR}/Source/make_opts']
78 mglog.warning(
'Way too many Cards_bkup* directories found. Giving up -- standalone script may not work.')
81 def new_process(process='generate p p > t t~\noutput -f', plugin=None, keepJpegs=False, usePMGSettings=False):
82 global my_MGC_instance
83 print(process,plugin,keepJpegs,usePMGSettings)
84 my_MGC_instance = MGControl(process, plugin, keepJpegs, usePMGSettings)
85 return my_MGC_instance.process_dir
88 """ Copy the default runcard from one of several locations
89 to a local file with name run_card.tmp.dat"""
90 output_name =
'run_card.tmp.dat'
93 run_card=process_dir+
'/Cards/run_card.dat'
94 if os.access(run_card,os.R_OK):
95 mglog.info(
'Copying default run_card.dat from '+
str(run_card))
96 shutil.copy(run_card,output_name)
99 run_card=process_dir+
'/Cards/run_card_default.dat'
100 mglog.info(
'Fetching default run_card.dat from '+
str(run_card))
101 if os.access(run_card,os.R_OK):
102 shutil.copy(run_card,output_name)
105 raise RuntimeError(
'Cannot find default run_card.dat or run_card_default.dat! I was looking here: %s'%run_card)
108 def generate(process_dir='PROC_mssm_0', grid_pack=False, gridpack_compile=False, extlhapath=None, required_accuracy=0.01, runArgs=None, bias_module=None, requirePMGSettings=False):
109 global my_MGC_instance
116 if 'ATHENA_CORE_NUMBER' in os.environ
and int(os.environ[
'ATHENA_CORE_NUMBER'])>0:
117 njobs =
int(os.environ[
'ATHENA_CORE_NUMBER'])
118 mglog.info(
'Lucky you - you are running on a full node queue. Will re-configure for '+
str(njobs)+
' jobs.')
122 if cluster_type
is not None:
126 mglog.info(
'Running event generation from gridpack (using smarter mode from generate() function)')
127 generate_from_gridpack(runArgs=runArgs,extlhapath=extlhapath,gridpack_compile=gridpack_compile,requirePMGSettings=requirePMGSettings)
130 mglog.info(
'Did not identify an input gridpack.')
132 mglog.info(
'The grid_pack flag is set, so I am expecting to create a gridpack in this job')
146 from distutils.spawn
import find_executable
147 if find_executable(
'f2py')
is not None:
148 mglog.info(
'Found f2py, will use it for reweighting')
150 raise RuntimeError(
'Could not find f2py, needed for reweighting')
153 global MADGRAPH_COMMAND_STACK
157 mglog.info(
'Started generating gridpack at '+
str(time.asctime()))
158 mglog.warning(
' >>>>>> THIS KIND OF JOB SHOULD ONLY BE RUN LOCALLY - NOT IN GRID JOBS <<<<<<')
161 my_settings = {
'nevents':
'1000'}
163 my_settings[
'req_acc']=
str(required_accuracy)
166 LO_has_madspin =
False
167 if os.access(f
'{process_dir}/Cards/madspin_card.dat',os.R_OK):
168 MADGRAPH_COMMAND_STACK += [f
'mv {process_dir}/Cards/madspin_card.dat {process_dir}/Cards/madspin_card.tmp.dat']
169 os.rename(f
'{process_dir}/Cards/madspin_card.dat',f
'{process_dir}/Cards/madspin_card.tmp.dat')
170 LO_has_madspin =
True
171 my_settings = {
'gridpack':
'true'}
172 modify_run_card(process_dir=process_dir,settings=my_settings,skipBaseFragment=
True)
176 mglog.info(
'Started generating at '+
str(time.asctime()))
178 mglog.info(
'Run '+MADGRAPH_RUN_NAME+
' will be performed in mode '+
str(mode)+
' with '+
str(njobs)+
' jobs in parallel.')
181 if not os.access(process_dir,os.R_OK):
182 raise RuntimeError(
'No process directory found at '+process_dir)
183 if not os.access(process_dir+
'/bin/generate_events',os.R_OK):
184 raise RuntimeError(
'No generate_events module found in '+process_dir)
186 mglog.info(
'For your information, the libraries available are (should include LHAPDF):')
187 ls_dir(process_dir+
'/lib')
190 if bias_module
is not None:
193 mglog.info(
'Now I will hack the make files a bit. Apologies, but there seems to be no good way around this.')
194 shutil.copyfile(process_dir+
'/Source/make_opts',process_dir+
'/Source/make_opts_old')
195 old_opts =
open(process_dir+
'/Source/make_opts_old',
'r')
196 new_opts =
open(process_dir+
'/Source/make_opts',
'w')
197 for aline
in old_opts:
199 mglog.info(
'Configuring the fancy gfortran compiler instead of g77 / f77')
200 new_opts.write(
' FC=gfortran\n')
202 new_opts.write(aline)
205 mglog.info(
'Make file hacking complete.')
209 os.chdir(process_dir)
211 MADGRAPH_COMMAND_STACK += [
'cd ${MGaMC_PROCESS_DIR}' ]
221 if requirePMGSettings
and code!=0:
222 raise RuntimeError(
'Settings are not compliant with PMG defaults! Please use do_PMG_updates function to get PMG default params.')
226 command = [python,
'bin/generate_events']
228 command += [
'--name='+MADGRAPH_RUN_NAME]
229 mglog.info(
'Removing Cards/shower_card.dat to ensure we get parton level events only')
230 os.unlink(
'Cards/shower_card.dat')
232 command += [MADGRAPH_RUN_NAME]
234 setNCores(process_dir=os.getcwd(), Ncores=njobs)
237 mglog.info(
'Setting up cluster running')
239 if cluster_type==
'pbs':
240 mglog.info(
'Modifying bin/internal/cluster.py for PBS cluster running')
241 os.system(
"sed -i \"s:text += prog:text += './'+prog:g\" bin/internal/cluster.py")
243 mglog.info(
'Setting up multi-core running on '+os.environ[
'ATHENA_CORE_NUMBER']+
' cores')
245 mglog.info(
'Setting up serial generation.')
248 global MADGRAPH_CATCH_ERRORS
249 generate =
stack_subprocess(command,stdin=subprocess.PIPE, stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
250 (out,err) = generate.communicate()
255 MADGRAPH_COMMAND_STACK += [
'cd -' ]
259 energy =
'%1.1f'%(beamEnergy*2./1000.)
260 energy = energy.replace(
'.0',
'').
replace(
'.',
'p')
262 mglog.info(
'Tidying up gridpack '+gridpack_name)
267 MADGRAPH_COMMAND_STACK += [f
'mv {process_dir}/Cards/madspin_card.tmp.dat {process_dir}/Cards/madspin_card.dat']
268 os.rename(f
'{process_dir}/Cards/madspin_card.tmp.dat',f
'{process_dir}/Cards/madspin_card.dat')
271 MADGRAPH_COMMAND_STACK += [
'cp '+glob.glob(process_dir+
'/'+MADGRAPH_RUN_NAME+
'_*gridpack.tar.gz')[0]+
' '+gridpack_name]
272 shutil.copy(glob.glob(process_dir+
'/'+MADGRAPH_RUN_NAME+
'_*gridpack.tar.gz')[0],gridpack_name)
275 MADGRAPH_COMMAND_STACK += [
'mkdir tmp%i/'%os.getpid(),
'cd tmp%i/'%os.getpid()]
276 os.mkdir(
'tmp%i/'%os.getpid())
277 os.chdir(
'tmp%i/'%os.getpid())
278 mglog.info(
'untar gridpack')
281 mglog.info(
'compile and clean up')
282 MADGRAPH_COMMAND_STACK += [
'cd madevent']
283 os.chdir(
'madevent/')
284 compilep =
stack_subprocess([
'./bin/compile'],stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
285 (out,err) = compilep.communicate()
287 clean =
stack_subprocess([
'./bin/clean4grid'],stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
288 (out,err) = clean.communicate()
291 MADGRAPH_COMMAND_STACK += [
'cd ..',
'rm ../'+gridpack_name]
293 mglog.info(
'remove old tarball')
294 os.unlink(
'../'+gridpack_name)
295 mglog.info(
'Package up new tarball')
296 tar =
stack_subprocess([
'tar',
'--exclude=SubProcesses/P*/G*/*_results.dat',
'--exclude=SubProcesses/P*/G*/*.log',
'--exclude=SubProcesses/P*/G*/*.txt',
'-cvsf',
'../'+gridpack_name,
'.'])
298 MADGRAPH_COMMAND_STACK += [
'cd ..',
'rm -r tmp%i/'%os.getpid()]
300 mglog.info(
'Remove temporary directory')
301 shutil.rmtree(
'tmp%i/'%os.getpid())
302 mglog.info(
'Tidying up complete!')
307 mglog.info(
'Package up process_dir')
308 MADGRAPH_COMMAND_STACK += [
'mv '+process_dir+
' '+MADGRAPH_GRIDPACK_LOCATION]
309 os.rename(process_dir,MADGRAPH_GRIDPACK_LOCATION)
310 tar =
stack_subprocess([
'tar',
'--exclude=Events/*/*events*gz',
'--exclude=SubProcesses/P*/G*/log*txt',
'--exclude=SubProcesses/P*/G*/events.lhe*',
'--exclude=*/*.o',
'--exclude=*/*/*.o',
'--exclude=*/*/*/*.o',
'--exclude=*/*/*/*/*.o',
'-czf',gridpack_name,MADGRAPH_GRIDPACK_LOCATION])
312 MADGRAPH_COMMAND_STACK += [
'mv '+MADGRAPH_GRIDPACK_LOCATION+
' '+process_dir]
313 os.rename(MADGRAPH_GRIDPACK_LOCATION,process_dir)
315 mglog.info(
'Gridpack sucessfully created, exiting the transform')
316 if hasattr(runArgs,
'outputTXTFile'):
317 mglog.info(
'Touching output TXT (LHE) file for the transform')
318 open(runArgs.outputTXTFile,
'w').close()
319 from AthenaCommon.AppMgr
import theApp
323 mglog.info(
'Finished at '+
str(time.asctime()))
328 global my_MGC_instance
335 isNLO=
is_NLO_run(process_dir=MADGRAPH_GRIDPACK_LOCATION)
340 gridpack_run_name =
'GridRun_'+
str(random_seed)
343 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/madspin_card.dat',os.R_OK):
344 os.rename(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/madspin_card.dat',MADGRAPH_GRIDPACK_LOCATION+
'/Cards/backup_madspin_card.dat')
354 if requirePMGSettings
and code!=0:
355 raise RuntimeError(
'Settings are not compliant with PMG defaults! Please use do_PMG_updates function to get PMG default params.')
358 settings={
'iseed':
str(random_seed)}
360 settings[
'python_seed']=
str(random_seed)
361 modify_run_card(process_dir=MADGRAPH_GRIDPACK_LOCATION,settings=settings,skipBaseFragment=
True)
363 mglog.info(
'Generating events from gridpack')
366 if not os.path.exists(MADGRAPH_GRIDPACK_LOCATION):
367 raise RuntimeError(
'Gridpack directory not found at '+MADGRAPH_GRIDPACK_LOCATION)
369 nevents =
getDictFromCard(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/run_card.dat')[
'nevents']
370 mglog.info(
'>>>> FOUND GRIDPACK <<<< <- This will be used for generation')
371 mglog.info(
'Generation of '+
str(
int(nevents))+
' events will be performed using the supplied gridpack with random seed '+
str(random_seed))
372 mglog.info(
'Started generating events at '+
str(time.asctime()))
375 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/bin/internal/addmasses.py',os.R_OK):
376 os.remove(MADGRAPH_GRIDPACK_LOCATION+
'/bin/internal/addmasses.py')
381 setNCores(process_dir=MADGRAPH_GRIDPACK_LOCATION)
382 global MADGRAPH_CATCH_ERRORS
386 ls_dir(MADGRAPH_GRIDPACK_LOCATION)
396 run_card_dict=
getDictFromCard(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/run_card.dat')
397 systematics_settings=
None
398 if checkSetting(
'systematics_program',
'systematics',run_card_dict):
400 raise RuntimeError(
'Trying to run NLO systematics but reweight info not stored')
402 systematics_settings=MadGraphControl.MadGraphSystematicsUtils.parse_systematics_arguments(run_card_dict[
'systematics_arguments'])
404 systematics_settings={}
405 mglog.info(
'Turning off systematics for now, running standalone later')
406 modify_run_card(process_dir=MADGRAPH_GRIDPACK_LOCATION,settings={
'systematics_program':
'none'},skipBaseFragment=
True)
408 global MADGRAPH_COMMAND_STACK
411 if not os.access(MADGRAPH_GRIDPACK_LOCATION+
'/bin/gridrun',os.R_OK):
412 mglog.error(
'/bin/gridrun not found at '+MADGRAPH_GRIDPACK_LOCATION)
413 raise RuntimeError(
'Could not find gridrun executable')
415 mglog.info(
'Found '+MADGRAPH_GRIDPACK_LOCATION+
'/bin/gridrun, starting generation.')
418 mglog.info(
"Now generating {} events with random seed {} and granularity {}".
format(
int(nevents),
int(random_seed),granularity))
420 new_ld_path=
":".
join([os.environ[
'LD_LIBRARY_PATH'],os.getcwd()+
'/'+MADGRAPH_GRIDPACK_LOCATION+
'/madevent/lib',os.getcwd()+
'/'+MADGRAPH_GRIDPACK_LOCATION+
'/HELAS/lib'])
421 os.environ[
'LD_LIBRARY_PATH']=new_ld_path
422 MADGRAPH_COMMAND_STACK+=[
"export LD_LIBRARY_PATH="+
":".
join([
'${LD_LIBRARY_PATH}',new_ld_path])]
423 generate =
stack_subprocess([python,MADGRAPH_GRIDPACK_LOCATION+
'/bin/gridrun',
str(
int(nevents)),
str(
int(random_seed)),
str(granularity)],stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
424 (out,err) = generate.communicate()
426 gp_events=MADGRAPH_GRIDPACK_LOCATION+
"/Events/GridRun_{}/unweighted_events.lhe.gz".
format(
int(random_seed))
427 if not os.path.exists(gp_events):
428 mglog.error(
'Error in gp generation, did not find events at '+gp_events)
432 if reweight_card
is not None:
433 pythonpath_backup=os.environ[
'PYTHONPATH']
435 os.environ[
'PYTHONPATH']=
':'.
join([p
for p
in pythonpath_backup.split(
':')
if 'madgraph5amc' not in p])
437 os.environ[
'PYTHONPATH']=pythonpath_backup
439 shutil.move(gp_events,
'events.lhe.gz')
443 if not os.access(MADGRAPH_GRIDPACK_LOCATION+
'/bin/generate_events',os.R_OK):
444 raise RuntimeError(
'Could not find generate_events executable at '+MADGRAPH_GRIDPACK_LOCATION)
446 mglog.info(
'Found '+MADGRAPH_GRIDPACK_LOCATION+
'/bin/generate_events, starting generation.')
448 ls_dir(MADGRAPH_GRIDPACK_LOCATION+
'/Events/')
449 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name, os.F_OK):
450 mglog.info(
'Removing '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
' directory from gridpack generation')
451 MADGRAPH_COMMAND_STACK += [
'rm -rf '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name]
452 shutil.rmtree(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name)
455 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1', os.F_OK):
456 mglog.info(
'Removing '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1 directory from gridpack generation')
457 MADGRAPH_COMMAND_STACK += [
'rm -rf '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1']
458 shutil.rmtree(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1')
460 ls_dir(MADGRAPH_GRIDPACK_LOCATION+
'/Events/')
462 if not gridpack_compile:
463 mglog.info(
'Copying make_opts from Template')
464 shutil.copy(os.environ[
'MADPATH']+
'/Template/LO/Source/make_opts',MADGRAPH_GRIDPACK_LOCATION+
'/Source/')
467 generate =
stack_subprocess([python,MADGRAPH_GRIDPACK_LOCATION+
'/bin/generate_events',
'--parton',
'--nocompile',
'--only_generation',
'-f',
'--name='+gridpack_run_name],stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
468 (out,err) = generate.communicate()
471 mglog.info(
'Allowing recompilation of gridpack')
472 if os.path.islink(MADGRAPH_GRIDPACK_LOCATION+
'/lib/libLHAPDF.a'):
473 mglog.info(
'Unlinking '+MADGRAPH_GRIDPACK_LOCATION+
'/lib/libLHAPDF.a')
474 os.unlink(MADGRAPH_GRIDPACK_LOCATION+
'/lib/libLHAPDF.a')
477 generate =
stack_subprocess([python,MADGRAPH_GRIDPACK_LOCATION+
'/bin/generate_events',
'--parton',
'--only_generation',
'-f',
'--name='+gridpack_run_name],stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
478 (out,err) = generate.communicate()
480 if isNLO
and systematics_settings
is not None:
482 mglog.info(
'Running systematics standalone')
483 systematics_path=MADGRAPH_GRIDPACK_LOCATION+
'/bin/internal/systematics.py'
484 events_location=MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/events.lhe.gz'
485 syst_cmd=[python,systematics_path]+[events_location]*2+[
"--"+k+
"="+systematics_settings[k]
for k
in systematics_settings]
486 mglog.info(
'running: '+
' '.
join(syst_cmd))
492 if not os.access(
'events.lhe.gz',os.R_OK):
493 mglog.info(
'Copying generated events to '+currdir)
494 if not os.path.exists(MADGRAPH_GRIDPACK_LOCATION+
'Events/'+gridpack_run_name):
495 shutil.copy(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/events.lhe.gz',
'events.lhe.gz')
497 mglog.info(
'Events were already in place')
501 mglog.info(
'Moving generated events to be in correct format for arrange_output().')
502 mglog.info(
'Unzipping generated events.')
506 mglog.info(
'Moving file over to '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe')
507 mkdir =
stack_subprocess([
'mkdir',
'-p',(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name)])
509 shutil.move(
'events.lhe',MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe')
511 mglog.info(
'Re-zipping into dataset name '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe.gz')
512 rezip =
stack_subprocess([
'gzip',MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe'])
520 os.rename(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/backup_madspin_card.dat',MADGRAPH_GRIDPACK_LOCATION+
'/Cards/madspin_card.dat')
521 mglog.info(
'Decaying with MadSpin.')
522 add_madspin(process_dir=MADGRAPH_GRIDPACK_LOCATION)
524 mglog.info(
'Finished at '+
str(time.asctime()))
533 mglog.info(
'Path to fastjet install dir: '+os.environ[
'FASTJETPATH'])
534 fastjetconfig = os.environ[
'FASTJETPATH']+
'/bin/fastjet-config'
536 mglog.info(
'fastjet-config --version: '+
str(subprocess.Popen([fastjetconfig,
'--version'],stdout = subprocess.PIPE).stdout.read().strip()))
537 mglog.info(
'fastjet-config --prefix: '+
str(subprocess.Popen([fastjetconfig,
'--prefix'],stdout = subprocess.PIPE).stdout.read().strip()))
540 config_card=process_dir+
'/Cards/me5_configuration.txt'
542 config_card=process_dir+
'/Cards/amcatnlo_configuration.txt'
544 oldcard =
open(config_card,
'r')
545 newcard =
open(config_card+
'.tmp',
'w')
548 if 'fastjet = ' in line:
549 newcard.write(
'fastjet = '+fastjetconfig+
'\n')
550 mglog.info(
'Setting fastjet = '+fastjetconfig+
' in '+config_card)
555 shutil.move(config_card+
'.tmp',config_card)
561 def setupLHAPDF(process_dir=None, extlhapath=None, allow_links=True):
562 global my_MGC_instance
566 origLHAPATH=os.environ[
'LHAPATH']
567 origLHAPDF_DATA_PATH=os.environ[
'LHAPDF_DATA_PATH']
575 run_card=process_dir+
'/Cards/run_card.dat'
578 if mydict[
"pdlabel"].
replace(
"'",
"") ==
'lhapdf':
580 mglog.info(
'creating local LHAPDF dir: MGC_LHAPDF/')
581 if os.path.islink(
'MGC_LHAPDF/'):
582 os.unlink(
'MGC_LHAPDF/')
583 elif os.path.isdir(
'MGC_LHAPDF/'):
584 shutil.rmtree(
'MGC_LHAPDF/')
586 newMGCLHA=
'MGC_LHAPDF/'
588 mkdir = subprocess.Popen([
'mkdir',
'-p',newMGCLHA])
591 pdfs_used=[
int(x)
for x
in mydict[
'lhaid'].
replace(
' ',
',').
split(
',') ]
593 if 'sys_pdf' in mydict:
599 pdfs_used.append(idx)
602 if 'systematics_arguments' in mydict:
603 systematics_arguments=MadGraphControl.MadGraphSystematicsUtils.parse_systematics_arguments(mydict[
'systematics_arguments'])
604 if 'pdf' in systematics_arguments:
610 pdfs_used.append(idx)
613 for pdf
in pdfs_used:
614 if isinstance(pdf,str)
and (pdf.lower()==
'errorset' or pdf.lower()==
'central'):
618 mglog.info(
"Found LHAPDF ID="+
str(pdfid)+
", name="+pdfname)
620 if not os.path.exists(newMGCLHA+pdfname)
and not os.path.lexists(newMGCLHA+pdfname):
621 if not os.path.exists(LHADATAPATH+
'/'+pdfname):
622 mglog.warning(
'PDF not installed at '+LHADATAPATH+
'/'+pdfname)
624 mglog.info(
'linking '+LHADATAPATH+
'/'+pdfname+
' --> '+newMGCLHA+pdfname)
625 os.symlink(LHADATAPATH+
'/'+pdfname,newMGCLHA+pdfname)
627 mglog.info(
'copying '+LHADATAPATH+
'/'+pdfname+
' --> '+newMGCLHA+pdfname)
628 shutil.copytree(LHADATAPATH+
'/'+pdfname,newMGCLHA+pdfname)
631 mglog.info(
'linking '+LHADATAPATH+
'/pdfsets.index --> '+newMGCLHA+
'pdfsets.index')
632 os.symlink(LHADATAPATH+
'/pdfsets.index',newMGCLHA+
'pdfsets.index')
634 atlasLHADATAPATH=LHADATAPATH.replace(
'sft.cern.ch/lcg/external/lhapdfsets/current',
'atlas.cern.ch/repo/sw/Generators/lhapdfsets/current')
635 mglog.info(
'linking '+atlasLHADATAPATH+
'/lhapdf.conf --> '+newMGCLHA+
'lhapdf.conf')
636 os.symlink(atlasLHADATAPATH+
'/lhapdf.conf',newMGCLHA+
'lhapdf.conf')
638 mglog.info(
'copying '+LHADATAPATH+
'/pdfsets.index --> '+newMGCLHA+
'pdfsets.index')
639 shutil.copy2(LHADATAPATH+
'/pdfsets.index',newMGCLHA+
'pdfsets.index')
641 atlasLHADATAPATH=LHADATAPATH.replace(
'sft.cern.ch/lcg/external/lhapdfsets/current',
'atlas.cern.ch/repo/sw/Generators/lhapdfsets/current')
642 mglog.info(
'copying '+atlasLHADATAPATH+
'/lhapdf.conf -->'+newMGCLHA+
'lhapdf.conf')
643 shutil.copy2(atlasLHADATAPATH+
'/lhapdf.conf',newMGCLHA+
'lhapdf.conf')
646 LHADATAPATH=os.getcwd()+
'/MGC_LHAPDF'
649 mglog.info(
'Not using LHAPDF')
650 return (LHAPATH,origLHAPATH,origLHAPDF_DATA_PATH)
654 os.environ[
'LHAPDF_DATA_PATH']=LHADATAPATH
656 mglog.info(
'Path to LHAPDF install dir: '+LHAPATH)
657 mglog.info(
'Path to LHAPDF data dir: '+LHADATAPATH)
658 if not os.path.isdir(LHADATAPATH):
659 raise RuntimeError(
'LHAPDF data dir not accesible: '+LHADATAPATH)
660 if not os.path.isdir(LHAPATH):
661 raise RuntimeError(
'LHAPDF path dir not accesible: '+LHAPATH)
665 lhapdfconfig=extlhapath
666 if not os.access(lhapdfconfig,os.X_OK):
667 raise RuntimeError(
'Failed to find valid external lhapdf-config at '+lhapdfconfig)
668 LHADATAPATH=subprocess.Popen([lhapdfconfig,
'--datadir'],stdout = subprocess.PIPE).stdout.read().strip()
669 mglog.info(
'Changing LHAPDF_DATA_PATH to '+LHADATAPATH)
670 os.environ[
'LHAPDF_DATA_PATH']=LHADATAPATH
672 getlhaconfig = subprocess.Popen([
'get_files',
'-data',
'lhapdf-config'])
675 if not os.access(os.getcwd()+
'/lhapdf-config',os.X_OK):
676 mglog.error(
'Failed to get lhapdf-config from MadGraphControl')
678 lhapdfconfig = os.getcwd()+
'/lhapdf-config'
680 mglog.info(
'lhapdf-config --version: '+
str(subprocess.Popen([lhapdfconfig,
'--version'],stdout = subprocess.PIPE).stdout.read().strip()))
681 mglog.info(
'lhapdf-config --prefix: '+
str(subprocess.Popen([lhapdfconfig,
'--prefix'],stdout = subprocess.PIPE).stdout.read().strip()))
682 mglog.info(
'lhapdf-config --libdir: '+
str(subprocess.Popen([lhapdfconfig,
'--libdir'],stdout = subprocess.PIPE).stdout.read().strip()))
683 mglog.info(
'lhapdf-config --datadir: '+
str(subprocess.Popen([lhapdfconfig,
'--datadir'],stdout = subprocess.PIPE).stdout.read().strip()))
684 mglog.info(
'lhapdf-config --pdfsets-path: '+
str(subprocess.Popen([lhapdfconfig,
'--pdfsets-path'],stdout = subprocess.PIPE).stdout.read().strip()))
686 modify_config_card(process_dir=process_dir,settings={
'lhapdf':lhapdfconfig,
'lhapdf_py3':lhapdfconfig})
688 mglog.info(
'Creating links for LHAPDF')
689 if os.path.islink(process_dir+
'/lib/PDFsets'):
690 os.unlink(process_dir+
'/lib/PDFsets')
691 elif os.path.isdir(process_dir+
'/lib/PDFsets'):
692 shutil.rmtree(process_dir+
'/lib/PDFsets')
694 os.symlink(LHADATAPATH,process_dir+
'/lib/PDFsets')
696 shutil.copytree(LHADATAPATH,process_dir+
'/lib/PDFsets')
697 mglog.info(
'Available PDFs are:')
698 mglog.info(
sorted( [ x
for x
in os.listdir(process_dir+
'/lib/PDFsets')
if ".tar.gz" not in x ] ) )
700 global MADGRAPH_COMMAND_STACK
701 MADGRAPH_COMMAND_STACK += [
'# Copy the LHAPDF files locally' ]
702 MADGRAPH_COMMAND_STACK += [
'cp -r '+os.getcwd()+
'/MGC_LHAPDF .' ]
703 MADGRAPH_COMMAND_STACK += [
'cp -r '+process_dir+
'/lib/PDFsets ${MGaMC_PROCESS_DIR}/lib/' ]
705 return (LHAPATH,origLHAPATH,origLHAPDF_DATA_PATH)
711 my_runMode = 2
if 'ATHENA_CORE_NUMBER' in os.environ
else 0
712 if Ncores
is None and 'ATHENA_CORE_NUMBER' in os.environ
and int(os.environ[
'ATHENA_CORE_NUMBER'])>0:
713 my_Ncores =
int(os.environ[
'ATHENA_CORE_NUMBER'])
715 if my_Ncores
is None:
716 mglog.info(
'Setting up for serial run')
719 modify_config_card(process_dir=process_dir,settings={
'nb_core':my_Ncores,
'run_mode':my_runMode,
'automatic_html_opening':
'False'})
728 madpath=os.environ[
'MADPATH']
729 if not os.access(madpath+
'/bin/mg5_aMC',os.R_OK):
730 raise RuntimeError(
'mg5_aMC executable not found in '+madpath)
731 return madpath+
'/bin/mg5_aMC'
735 """ Add lifetimes to the generated LHE file. Should be
736 called after generate_events is called.
741 if len(glob.glob(process_dir+
'/Events/*'))<1:
742 mglog.error(
'Process dir '+process_dir+
' does not contain events?')
743 run = glob.glob(process_dir+
'/Events/*')[0].
split(
'/')[-1]
748 tof_c =
open(
'time_of_flight_exec_card',
'w')
749 tof_c.write(
'launch '+process_dir+
''' -i
750 add_time_of_flight '''+run+((
' --threshold='+
str(threshold))
if threshold
is not None else ''))
753 mglog.info(
'Started adding time of flight info '+
str(time.asctime()))
755 global MADGRAPH_CATCH_ERRORS
756 generate =
stack_subprocess([python,me_exec,
'time_of_flight_exec_card'],stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
757 (out,err) = generate.communicate()
760 mglog.info(
'Finished adding time of flight information at '+
str(time.asctime()))
763 lhe_gz = glob.glob(process_dir+
'/Events/*/*lhe.gz')[0]
764 if not os.access(lhe_gz,os.R_OK):
765 mglog.info(
'LHE file needs to be zipped')
766 lhe = glob.glob(process_dir+
'/Events/*/*lhe.gz')[0]
771 mglog.info(
'LHE file zipped by MadGraph automatically. Nothing to do')
776 def add_madspin(madspin_card=None,process_dir=MADGRAPH_GRIDPACK_LOCATION):
777 """ Run madspin on the generated LHE file. Should be
778 run when you have inputGeneratorFile set.
779 Only requires a simplified process with the same model that you are
780 interested in (needed to set up a process directory for MG5_aMC)
785 if madspin_card
is not None:
786 shutil.copyfile(madspin_card,process_dir+
'/Cards/madspin_card.dat')
788 if len(glob.glob(process_dir+
'/Events/*'))<1:
789 mglog.error(
'Process dir '+process_dir+
' does not contain events?')
790 proc_dir_list = glob.glob(process_dir+
'/Events/*')
792 for adir
in proc_dir_list:
793 if 'GridRun_' in adir:
794 run=adir.split(
'/')[-1]
797 run=proc_dir_list[0].
split(
'/')[-1]
802 ms_c =
open(
'madspin_exec_card',
'w')
803 ms_c.write(
'launch '+process_dir+
''' -i
804 decay_events '''+run)
807 mglog.info(
'Started running madspin at '+
str(time.asctime()))
809 global MADGRAPH_CATCH_ERRORS
810 generate =
stack_subprocess([python,me_exec,
'madspin_exec_card'],stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
811 (out,err) = generate.communicate()
813 if len(glob.glob(process_dir+
'/Events/'+run+
'_decayed_*/')) == 0:
814 mglog.error(
'No '+process_dir+
'/Events/'+run+
'_decayed_*/ can be found')
815 raise RuntimeError(
'Problem while running MadSpin')
817 mglog.info(
'Finished running madspin at '+
str(time.asctime()))
820 lhe_gz = glob.glob(process_dir+
'/Events/*/*lhe.gz')[0]
821 if not os.access(lhe_gz,os.R_OK):
822 mglog.info(
'LHE file needs to be zipped')
823 lhe = glob.glob(process_dir+
'/Events/*/*lhe.gz')[0]
828 mglog.info(
'LHE file zipped by MadGraph automatically. Nothing to do')
832 """ Run MadSpin on an input LHE file. Takes the process
833 from the LHE file, so you don't need to have a process directory
834 set up in advance. Runs MadSpin and packs the LHE file up appropriately
835 Needs runArgs for the file handling"""
836 if not os.access(input_LHE,os.R_OK):
837 raise RuntimeError(
'Could not find LHE file '+input_LHE)
838 if not os.access(madspin_card,os.R_OK):
839 raise RuntimeError(
'Could not find input MadSpin card '+madspin_card)
841 shutil.copy(input_LHE,input_LHE+
'.original')
842 mglog.info(
'Put backup copy of LHE file at '+input_LHE+
'.original')
844 madspin_exec_card =
open(
'madspin_exec_card',
'w')
845 madspin_exec_card.write(
'import '+input_LHE+
'\n')
847 input_madspin_card =
open(madspin_card,
'r')
849 for l
in input_madspin_card.readlines():
850 commands = l.split(
'#')[0].
split()
852 if len(commands)>1
and 'import'==commands[0]
and not 'model'==commands[1]:
855 if len(commands)>0
and 'launch' == commands[0]:
857 madspin_exec_card.write(l.strip()+
'\n')
859 madspin_exec_card.write(
'launch\n')
860 madspin_exec_card.close()
861 input_madspin_card.close()
863 madpath=os.environ[
'MADPATH']
864 if not os.access(madpath+
'/MadSpin/madspin',os.R_OK):
865 raise RuntimeError(
'madspin executable not found in '+madpath)
866 mglog.info(
'Starting madspin at '+
str(time.asctime()))
867 global MADGRAPH_CATCH_ERRORS
868 generate =
stack_subprocess([python,madpath+
'/MadSpin/madspin',
'madspin_exec_card'],stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
869 (out,err) = generate.communicate()
871 mglog.info(
'Done with madspin at '+
str(time.asctime()))
875 if os.path.exists(os.getcwd()+
'/events.lhe'):
876 os.remove(os.getcwd()+
'/events.lhe')
878 mglog.info(
'Unzipping generated events.')
882 mglog.info(
'Putting a copy in place for the transform.')
883 mod_output =
open(os.getcwd()+
'/events.lhe',
'w')
887 with open(input_LHE,
'r')
as fileobject:
888 for line
in fileobject:
890 mod_output.write(line)
895 mglog.info(
'Removed '+
str(nEmpty)+
' empty lines from LHEF')
899 raise RuntimeError(
'Must provide runArgs to madspin_on_lhe')
901 outputDS = runArgs.outputTXTFile
if hasattr(runArgs,
'outputTXTFile')
else 'tmp_LHE_events.tar.gz'
903 mglog.info(
'Moving file over to '+outputDS.split(
'.tar.gz')[0]+
'.events')
904 shutil.move(os.getcwd()+
'/events.lhe',outputDS.split(
'.tar.gz')[0]+
'.events')
906 mglog.info(
'Re-zipping into dataset name '+outputDS)
907 rezip =
stack_subprocess([
'tar',
'cvzf',outputDS,outputDS.split(
'.tar.gz')[0]+
'.events'])
911 if hasattr(runArgs,
'outputTXTFile')
and runArgs.outputTXTFile
is not None:
912 outputDS = outputDS.split(
'.TXT')[0]
914 if runArgs
is not None:
915 mglog.debug(
'Setting inputGenerator file to '+outputDS)
916 runArgs.inputGeneratorFile=outputDS
919 def arrange_output(process_dir=MADGRAPH_GRIDPACK_LOCATION,lhe_version=None,saveProcDir=False,runArgs=None,fixEventWeightsForBridgeMode=False):
924 if len(glob.glob(os.path.join(process_dir,
'Events',
'*')))<1:
925 mglog.error(
'Process dir '+process_dir+
' does not contain events?')
926 proc_dir_list = glob.glob(os.path.join(process_dir,
'Events',
'*'))
929 for adir
in proc_dir_list:
930 if 'decayed' in adir:
933 if 'GridRun_' in adir:
936 elif os.path.join(process_dir,
'Events',MADGRAPH_RUN_NAME)
in adir:
938 if not os.access(this_run_name,os.R_OK):
939 raise RuntimeError(
'Unable to locate run directory')
941 hasUnweighted = os.access(this_run_name+
'/unweighted_events.lhe.gz',os.R_OK)
944 madspinDirs=
sorted(glob.glob(this_run_name+
'_decayed_*/'))
947 if hasRunMadSpin
and not hasUnweighted:
949 hasUnweighted = os.access(madspinDirs[-1]+
'/unweighted_events.lhe.gz',os.R_OK)
951 global MADGRAPH_COMMAND_STACK
960 if os.path.exists(madspinDirs[-1]+
'/unweighted_events.lhe.gz'):
961 MADGRAPH_COMMAND_STACK += [
'mv '+madspinDirs[-1]+
'/unweighted_events.lhe.gz'+
' '+this_run_name+
'/unweighted_events.lhe.gz']
962 shutil.move(madspinDirs[-1]+
'/unweighted_events.lhe.gz',this_run_name+
'/unweighted_events.lhe.gz')
963 mglog.info(
'Moving MadSpin events from '+madspinDirs[-1]+
'/unweighted_events.lhe.gz to '+this_run_name+
'/unweighted_events.lhe.gz')
964 elif os.path.exists(madspinDirs[-1]+
'/events.lhe.gz'):
965 MADGRAPH_COMMAND_STACK += [
'mv '+madspinDirs[-1]+
'/events.lhe.gz'+
' '+this_run_name+
'/unweighted_events.lhe.gz']
966 shutil.move(madspinDirs[-1]+
'/events.lhe.gz',this_run_name+
'/unweighted_events.lhe.gz')
967 mglog.info(
'Moving MadSpin events from '+madspinDirs[-1]+
'/events.lhe.gz to '+this_run_name+
'/unweighted_events.lhe.gz')
969 raise RuntimeError(
'MadSpin was run but can\'t find files :(')
972 MADGRAPH_COMMAND_STACK += [
'mv '+madspinDirs[-1]+
'/events.lhe.gz '+this_run_name+
'/events.lhe.gz']
973 shutil.move(madspinDirs[-1]+
'/events.lhe.gz',this_run_name+
'/events.lhe.gz')
974 mglog.info(
'Moving MadSpin events from '+madspinDirs[-1]+
'/events.lhe.gz to '+this_run_name+
'/events.lhe.gz')
977 mglog.error(
'MadSpin was run but can\'t find output folder '+(this_run_name+
'_decayed_1/'))
978 raise RuntimeError(
'MadSpin was run but can\'t find output folder '+(this_run_name+
'_decayed_1/'))
980 if fixEventWeightsForBridgeMode:
981 mglog.info(
"Fixing event weights after MadSpin... initial checks.")
989 eventsfilename=
"unweighted_events"
991 eventsfilename=
"events"
992 unzip =
stack_subprocess([
'gunzip',
'-f',this_run_name+
'/%s.lhe.gz' % eventsfilename])
995 for line
in open(process_dir+
'/Events/'+MADGRAPH_RUN_NAME+
'/%s.lhe'%eventsfilename):
996 if "Number of Events" in line:
998 MGnumevents=
int(sline[-1])
999 elif "Integrated weight (pb)" in line:
1001 MGintweight=
float(sline[-1])
1002 elif "set spinmode none" in line:
1004 elif "</header>" in line:
1007 if spinmodenone
and MGnumevents>0
and MGintweight>0:
1008 mglog.info(
"Fixing event weights after MadSpin... modifying LHE file.")
1009 newlhe=
open(this_run_name+
'/%s_fixXS.lhe'%eventsfilename,
'w')
1017 event_norm_setting=
"average"
1019 for line
in open(this_run_name+
'/%s.lhe'%eventsfilename):
1022 if "<init>" in line:
1025 elif "</init>" in line:
1027 elif inInit
and initlinecount==0:
1031 if abs(
int(sline[-2])) == 3:
1032 event_norm_setting=
"sum"
1033 elif abs(
int(sline[-2])) == 4:
1034 event_norm_setting=
"average"
1035 elif inInit
and initlinecount==1:
1039 sline[0]=
str(MGintweight)
1040 sline[1]=
str(
float(sline[0])*relunc)
1041 if event_norm_setting==
"sum":
1042 sline[2]=
str(MGintweight/MGnumevents)
1043 elif event_norm_setting==
"average":
1044 sline[2]=
str(MGintweight)
1045 newline=
' '.
join(sline)
1048 elif inInit
and initlinecount>1:
1050 elif "<event>" in line:
1053 elif "</event>" in line:
1055 elif inEvent
and eventlinecount==0:
1058 if event_norm_setting==
"sum":
1059 sline[2]=
str(MGintweight/MGnumevents)
1060 elif event_norm_setting==
"average":
1061 sline[2]=
str(MGintweight)
1062 newline=
' '.
join(sline)
1065 newlhe.write(newline)
1068 mglog.info(
"Fixing event weights after MadSpin... cleaning up.")
1069 shutil.copyfile(this_run_name+
'/%s.lhe' % eventsfilename,
1070 this_run_name+
'/%s_badXS.lhe' % eventsfilename)
1072 shutil.move(this_run_name+
'/%s_fixXS.lhe' % eventsfilename,
1073 this_run_name+
'/%s.lhe' % eventsfilename)
1075 rezip =
stack_subprocess([
'gzip',this_run_name+
'/%s.lhe' % eventsfilename])
1078 rezip =
stack_subprocess([
'gzip',this_run_name+
'/%s_badXS.lhe' % eventsfilename])
1082 if os.path.exists(os.getcwd()+
'/events.lhe'):
1083 os.remove(os.getcwd()+
'/events.lhe')
1085 mglog.info(
'Unzipping generated events.')
1087 unzip =
stack_subprocess([
'gunzip',
'-f',this_run_name+
'/unweighted_events.lhe.gz'])
1093 mglog.info(
'Putting a copy in place for the transform.')
1095 orig_input = this_run_name+
'/unweighted_events.lhe'
1096 mod_output =
open(os.getcwd()+
'/events.lhe',
'w')
1098 orig_input = this_run_name+
'/events.lhe'
1099 mod_output =
open(os.getcwd()+
'/events.lhe',
'w')
1106 with open(orig_input,
'r')
as fileobject:
1107 for line
in fileobject:
1111 if '#' not in newline:
1113 elif '>' not in newline[ newline.find(
'#'): ]:
1116 mglog.info(
'Found bad LHE line with an XML mark in a comment: "'+newline.strip()+
'"')
1117 newline=newline[:newline.find(
'#')]+
'#'+ (newline[newline.find(
'#'):].
replace(
'>',
'-'))
1119 if initrwgt
is False:
1121 elif "</initrwgt>" in newline:
1123 elif "<initrwgt>" in newline:
1125 elif initrwgt
is not None:
1126 newline=newline.replace(
'_DYNSCALE-1',
'')
1127 if '</weight>' in newline:
1128 iend=newline.find(
'</weight>')
1129 istart=newline[:iend].rfind(
'>')
1130 lhe_weights+=[newline[istart+1:iend].strip()]
1131 mod_output.write(newline)
1135 mglog.info(
'Removed '+
str(nEmpty)+
' empty lines from LHEF')
1137 mglog.info(
"The following "+
str(len(lhe_weights))+
" weights have been written to the LHE file: "+
",".
join(lhe_weights))
1140 mglog.info(
"Checking whether the following expected weights are in LHE file: "+
",".
join(expected_weights))
1141 for w
in expected_weights:
1142 if w
not in lhe_weights:
1143 raise RuntimeError(
"Did not find expected weight "+w+
" in lhe file. Did the reweight or systematics module crash?")
1144 mglog.info(
"Found all required weights!")
1147 mod_output2 =
open(os.getcwd()+
'/events.lhe',
'r')
1148 test=mod_output2.readline()
1149 if 'version="' in test:
1150 mglog.info(
'Applying LHE version hack')
1151 final_file =
open(os.getcwd()+
'/events.lhe.copy',
'w')
1152 final_file.write(
'<LesHouchesEvents version="%i.0">\n'%lhe_version)
1153 shutil.copyfileobj(mod_output2, final_file)
1155 shutil.copy(os.getcwd()+
'/events.lhe.copy',os.getcwd()+
'/events.lhe')
1157 os.remove(os.getcwd()+
'/events.lhe.copy')
1162 raise RuntimeError(
'Must provide runArgs to arrange_output')
1164 if hasattr(runArgs,
'outputTXTFile'):
1165 outputDS = runArgs.outputTXTFile
1167 outputDS =
'tmp_LHE_events.tar.gz'
1169 mglog.info(
'Moving file over to '+outputDS.split(
'.tar.gz')[0]+
'.events')
1171 shutil.move(os.getcwd()+
'/events.lhe',outputDS.split(
'.tar.gz')[0]+
'.events')
1173 mglog.info(
'Re-zipping into dataset name '+outputDS)
1174 rezip =
stack_subprocess([
'tar',
'cvzf',outputDS,outputDS.split(
'.tar.gz')[0]+
'.events'])
1178 mglog.info(
'Removing the process directory')
1179 shutil.rmtree(process_dir,ignore_errors=
True)
1181 if os.path.isdir(
'MGC_LHAPDF/'):
1182 shutil.rmtree(
'MGC_LHAPDF/',ignore_errors=
True)
1185 if hasattr(runArgs,
'outputTXTFile')
and runArgs.outputTXTFile
is not None:
1186 outputDS = outputDS.split(
'.TXT')[0]
1188 if runArgs
is not None:
1189 mglog.debug(
'Setting inputGenerator file to '+outputDS)
1190 runArgs.inputGeneratorFile=outputDS
1192 mglog.info(
'All done with output arranging!')
1196 if reweight_card_loc
is None:
1199 f_rw=
open(reweight_card_loc)
1201 if 'launch' not in line:
1203 match=re.match(
r'launch.*--rwgt_info\s*=\s*(\S+).*',line.strip())
1204 if len(match.groups())!=1:
1205 raise RuntimeError(
'Unexpected format of reweight card in line'+line)
1207 names+=[match.group(1)]
1213 if syst_setting
is None or 'central_pdf' not in syst_setting:
1214 mglog.warning(
"Systematics have not been defined via base fragment or 'MADGRAPH_PDFSETTING', cannot check for expected weights")
1216 if 'pdf_variations' in syst_setting
and isinstance(syst_setting[
'pdf_variations'],list):
1217 names+=[MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO%{
'mur':1.0,
'muf':1.0,
'pdf':syst_setting[
'central_pdf']}]
1218 for pdf
in syst_setting[
'pdf_variations']:
1219 names+=[MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO%{
'mur':1.0,
'muf':1.0,
'pdf':pdf+1}]
1220 if 'alternative_pdfs' in syst_setting
and isinstance(syst_setting[
'alternative_pdfs'],list):
1221 for pdf
in syst_setting[
'alternative_pdfs']:
1222 names+=[MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO%{
'mur':1.0,
'muf':1.0,
'pdf':pdf}]
1223 if 'scale_variations' in syst_setting
and isinstance(syst_setting[
'scale_variations'],list):
1224 for mur
in syst_setting[
'scale_variations']:
1225 for muf
in syst_setting[
'scale_variations']:
1226 names+=[MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO%{
'mur':mur,
'muf':muf,
'pdf':syst_setting[
'central_pdf']}]
1230 run_card = process_dir+
'/Cards/run_card.dat'
1231 if isinstance(bias_module,tuple):
1232 mglog.info(
'Using bias module '+bias_module[0])
1233 the_run_card =
open(run_card,
'r')
1234 for line
in the_run_card:
1235 if 'bias_module' in line
and not bias_module[0]
in line:
1236 raise RuntimeError(
'You need to add the bias module '+bias_module[0]+
' to the run card to actually run it')
1237 the_run_card.close()
1238 if len(bias_module)!=3:
1239 raise RuntimeError(
'Please give a 3-tuple of strings containing bias module name, bias module, and makefile. Alternatively, give path to bias module tarball.')
1240 bias_module_newpath=process_dir+
'/Source/BIAS/'+bias_module[0]
1241 os.makedirs(bias_module_newpath)
1242 bias_module_file=
open(bias_module_newpath+
'/'+bias_module[0]+
'.f',
'w')
1243 bias_module_file.write(bias_module[1])
1244 bias_module_file.close()
1245 bias_module_make_file=
open(bias_module_newpath+
'/Makefile',
'w')
1246 bias_module_make_file.write(bias_module[2])
1247 bias_module_make_file.close()
1249 mglog.info(
'Using bias module '+bias_module)
1250 bias_module_name=bias_module.split(
'/')[-1].
replace(
'.gz',
'')
1251 bias_module_name=bias_module_name.replace(
'.tar',
'')
1252 the_run_card =
open(run_card,
'r')
1253 for line
in the_run_card:
1254 if 'bias_module' in line
and bias_module_name
not in line:
1255 raise RuntimeError(
'You need to add the bias module '+bias_module_name+
' to the run card to actually run it')
1256 the_run_card.close()
1258 if os.path.exists(bias_module+
'.tar.gz'):
1259 bias_module_path=bias_module+
'.tar.gz'
1260 elif os.path.exists(bias_module+
'.gz'):
1261 bias_module_path=bias_module+
'.gz'
1262 elif os.path.exists(bias_module):
1263 bias_module_path=bias_module
1265 mglog.error(
'Did not find bias module '+bias_module+
' , this path should point to folder or tarball. Alternatively give a tuple of strings containing module name, module, and makefile')
1267 bias_module_newpath=process_dir+
'/Source/BIAS/'+bias_module_path.split(
'/')[-1]
1268 mglog.info(
'Copying bias module into place: '+bias_module_newpath)
1269 shutil.copy(bias_module_path,bias_module_newpath)
1270 mglog.info(
'Unpacking bias module')
1271 if bias_module_newpath.endswith(
'.tar.gz'):
1272 untar =
stack_subprocess([
'tar',
'xvzf',bias_module_newpath,
'--directory='+process_dir+
'/Source/BIAS/'])
1274 elif bias_module_path.endswith(
'.gz'):
1280 if os.access(process_dir+
'/Cards/reweight_card.dat',os.R_OK):
1281 return process_dir+
'/Cards/reweight_card.dat'
1287 shutil.move(reweight_card,reweight_card+
'.old')
1288 oldcard =
open(reweight_card+
'.old',
'r')
1289 newcard =
open(reweight_card,
'w')
1291 info_expression=
r'launch.*--rwgt_info\s*=\s*(\S+).*'
1292 name_expression=info_expression.replace(
'info',
'name')
1293 goodname_expression=
r'^[A-Za-z0-9_\-.]+$'
1294 for line
in oldcard:
1296 if not line.strip().startswith(
'launch') :
1299 rwgt_name_match=re.match(name_expression,line.strip())
1300 rwgt_info_match=re.match(info_expression,line.strip())
1301 if rwgt_name_match
is None and rwgt_info_match
is None:
1302 raise RuntimeError(
'Every reweighting should have a --rwgt_info (see https://cp3.irmp.ucl.ac.be/projects/madgraph/wiki/Reweight), please update your reweight_card accordingly. Line to fix: '+line)
1303 for match
in [rwgt_info_match,rwgt_name_match]:
1306 if len(match.groups())!=1:
1307 raise RuntimeError(
'Unexpected format of reweight card in line: '+line)
1308 if not re.match(goodname_expression,match.group(1)):
1309 raise RuntimeError(
'No special character in reweighting info/name, only allowing '+goodname_expression)
1310 if rwgt_info_match
is not None:
1312 elif rwgt_name_match
is not None:
1313 newcard.write(line.strip()+
' --rwgt_info={0}\n'.
format(rwgt_name_match.group(1)))
1316 mglog.info(
'Updated reweight_card')
1321 def update_lhe_file(lhe_file_old,param_card_old=None,lhe_file_new=None,masses={},delete_old_lhe=True):
1322 """Build a new LHE file from an old one and an updated param card.
1323 The masses of some particles can be changed via the masses dictionary. No particles that appear in the events
1324 may have their masses changed.
1325 If the param card is provided, the decay block in the LHE file will be replaced with the one in the param card.
1326 By default, the old LHE file is removed.
1327 If None is provided as a new LHE file name, the new file will replace the old one."""
1329 lhe_file_new_tmp = lhe_file_new
if lhe_file_new
is not None else lhe_file_old+
'.tmp'
1331 if not os.access(lhe_file_old,os.R_OK):
1332 raise RuntimeError(
'Could not access old LHE file at '+
str(lhe_file_old)+
'. Please check the file location.')
1334 if param_card_old
is not None:
1335 paramcard = subprocess.Popen([
'get_files',
'-data',param_card_old])
1337 if not os.access(param_card_old,os.R_OK):
1338 raise RuntimeError(
'Could not get param card '+param_card_old)
1340 if os.access(lhe_file_new_tmp,os.R_OK):
1341 raise RuntimeError(
'Old file at'+
str(lhe_file_new_tmp)+
' in the current directory. Dont want to clobber it. Please move it first.')
1343 newlhe =
open(lhe_file_new_tmp,
'w')
1347 particles_in_events = []
1350 with open(lhe_file_old,
'r')
as fileobject:
1351 for line
in fileobject:
1352 if decayEdit
and '</slha>' not in line:
1354 if decayEdit
and '</slha>' in line:
1356 if line.strip().
upper().startswith(
'BLOCK')
or line.strip().
upper().startswith(
'DECAY')\
1357 and len(line.strip().
split()) > 1:
1358 pos = 0
if line.strip().startswith(
'DECAY')
else 1
1359 blockName = line.strip().
upper().
split()[pos]
1362 if blockName !=
'DECAY' and len(line.strip().
split()) > 0:
1363 akey = line.strip().
split()[0]
1364 elif blockName ==
'DECAY' and len(line.strip().
split()) > 1:
1365 akey = line.strip().
split()[1]
1368 if akey
is not None and blockName ==
'MASS' and akey
in masses:
1369 newlhe.write(
' '+akey+
' '+
str(masses[akey])+
' # \n')
1370 mglog.info(
' '+akey+
' '+
str(masses[akey])+
' #')
1375 if blockName ==
'DECAY' and param_card_old
is not None:
1377 oldparam =
open(param_card_old,
'r')
1379 for old_line
in oldparam.readlines():
1381 if old_line.strip().
upper().startswith(
'DECAY')
and len(old_line.strip().
split()) > 1:
1382 newBlockName = line.strip().
upper().
split()[pos]
1384 newlhe.write(old_line)
1385 elif newBlockName ==
'DECAY':
1387 newlhe.write(old_line)
1395 if not eventRead
and '<event>' in line:
1398 if len(line.split())==11:
1399 aparticle = line.split()[0]
1400 if aparticle
not in particles_in_events:
1401 particles_in_events += [aparticle]
1408 if akey
in particles_in_events:
1409 mglog.error(
'Attempted to change mass of a particle that was in an LHE event! This is not allowed!')
1416 if lhe_file_new
is None:
1417 os.remove(lhe_file_old)
1418 shutil.move(lhe_file_new_tmp,lhe_file_old)
1419 lhe_file_new_tmp = lhe_file_old
1421 elif delete_old_lhe:
1422 os.remove(lhe_file_old)
1424 return lhe_file_new_tmp
1429 """ Helper function when looking at param cards
1430 In some cases it's tricky to match keys - they may differ
1431 only in white space. This tries to sort out when we have
1432 a match, and then uses the one in blockParams afterwards.
1433 In the case of no match, it returns the original key.
1436 for key
in dictionary:
1438 if mod_key==test_key:
1443 def modify_param_card(param_card_input=None,param_card_backup=None,process_dir=MADGRAPH_GRIDPACK_LOCATION,params={},output_location=None):
1444 """Build a new param_card.dat from an existing one.
1445 Params should be a dictionary of dictionaries. The first key is the block name, and the second in the param name.
1446 Keys can include MASS (for masses) and DECAY X (for decays of particle X)"""
1450 if param_card_input
is None:
1451 param_card_input=process_dir+
'/Cards/param_card.dat'
1452 elif param_card_input
is not None and not os.access(param_card_input,os.R_OK):
1453 paramcard = subprocess.Popen([
'get_files',
'-data',param_card_input])
1455 if not os.access(param_card_input,os.R_OK):
1456 raise RuntimeError(
'Could not get param card '+param_card_input)
1457 mglog.info(
'Using input param card at '+param_card_input)
1461 for blockName
in list(params.keys()):
1462 paramsUpper[blockName.upper()] = {}
1463 for paramName
in list(params[blockName].
keys()):
1464 paramsUpper[blockName.upper()][paramName.upper()] = params[blockName][paramName]
1466 if param_card_backup
is not None:
1467 mglog.info(
'Keeping backup of original param card at '+param_card_backup)
1468 param_card_old = param_card_backup
1470 param_card_old = param_card_input+
'.old_to_be_deleted'
1471 if os.path.isfile(param_card_old):
1472 os.unlink(param_card_old)
1473 os.rename(param_card_input, param_card_old)
1475 oldcard =
open(param_card_old,
'r')
1476 param_card_location= process_dir+
'/Cards/param_card.dat' if output_location
is None else output_location
1477 newcard =
open(param_card_location,
'w')
1481 for linewithcomment
in oldcard:
1482 line=linewithcomment.split(
'#')[0]
1483 if line.strip().
upper().startswith(
'BLOCK')
or line.strip().
upper().startswith(
'DECAY')\
1484 and len(line.strip().
split()) > 1:
1485 if decayEdit
and blockName ==
'DECAY':
1487 pos = 0
if line.strip().startswith(
'DECAY')
else 1
1488 if blockName==
'MASS' and 'MASS' in paramsUpper:
1490 if "MASS" in doneParams:
1491 leftOvers = [ x
for x
in paramsUpper[
'MASS']
if x
not in doneParams[
'MASS'] ]
1493 leftOvers = [ x
for x
in paramsUpper[
'MASS'] ]
1495 for pdg_id
in leftOvers:
1496 mglog.warning(
'Adding mass line for '+
str(pdg_id)+
' = '+
str(paramsUpper[
'MASS'][pdg_id])+
' which was not in original param card')
1497 newcard.write(
' '+
str(pdg_id)+
' '+
str(paramsUpper[
'MASS'][pdg_id])+
'\n')
1498 doneParams[
'MASS'][pdg_id]=
True
1499 if blockName==
'DECAY' and 'DECAY' not in line.strip().
upper()
and 'DECAY' in paramsUpper:
1501 leftOvers = [ x
for x
in paramsUpper[
'DECAY']
if x
not in doneParams[
'DECAY'] ]
1502 for pdg_id
in leftOvers:
1503 mglog.warning(
'Adding decay for pdg id '+
str(pdg_id)+
' which was not in the original param card')
1504 newcard.write( paramsUpper[
'DECAY'][pdg_id].strip()+
'\n' )
1505 doneParams[
'DECAY'][pdg_id]=
True
1506 blockName = line.strip().
upper().
split()[pos]
1511 if blockName !=
'DECAY' and len(line.strip().
split()) > 0:
1514 if len(line.split())==2:
1515 akey = line.upper().strip().
split()[0]
1518 akey = line.upper().strip()[:line.strip().rfind(
' ')].strip()
1519 elif blockName ==
'DECAY' and len(line.strip().
split()) > 1:
1520 akey = line.strip().
split()[1]
1522 newcard.write(linewithcomment)
1526 if blockName
not in paramsUpper:
1527 newcard.write(linewithcomment)
1529 blockParams = paramsUpper[blockName]
1535 if '#' in linewithcomment:
1536 stringkey = linewithcomment[linewithcomment.find(
'#')+1:].strip()
1537 if len(stringkey.split()) > 0:
1538 stringkey = stringkey.split()[0].
upper()
1540 if akey
not in blockParams
and not (stringkey
is not None and stringkey
in blockParams):
1541 newcard.write(linewithcomment)
1544 if akey
in blockParams
and (stringkey
is not None and stringkey
in blockParams):
1545 raise RuntimeError(
'Conflicting use of numeric and string keys '+akey+
' and '+stringkey)
1547 theParam = blockParams.get(akey,blockParams[stringkey]
if stringkey
in blockParams
else None)
1548 if blockName
not in doneParams:
1549 doneParams[blockName] = {}
1550 if akey
in blockParams:
1551 doneParams[blockName][akey]=
True
1552 elif stringkey
is not None and stringkey
in blockParams:
1553 doneParams[blockName][stringkey]=
True
1556 if blockName==
"DECAY":
1557 if theParam.splitlines()[0].
split()[0].
upper()==
"DECAY":
1559 for newline
in theParam.splitlines():
1560 newcard.write(newline+
'\n')
1564 newcard.write(
'DECAY '+akey+
' '+
str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1565 mglog.info(
'DECAY '+akey+
' '+
str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1567 elif blockName==
'QNUMBERS':
1569 for newline
in theParam.splitlines():
1570 newcard.write(newline+
'\n')
1574 newcard.write(
' '+akey+
' '+
str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1575 mglog.info(
' '+akey+
' '+
str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1579 for blockName
in paramsUpper:
1580 if blockName
not in doneParams
and len(paramsUpper[blockName].
keys())>0:
1581 raise RuntimeError(
'Did not find any of the parameters for block '+blockName+
' in param_card')
1582 for paramName
in paramsUpper[blockName]:
1583 if paramName
not in doneParams[blockName]:
1584 raise RuntimeError(
'Was not able to replace parameter '+paramName+
' in param_card')
1593 card_dir=process_dir+
'/Cards/'
1594 print_cards(proc_card=card_dir+
'proc_card_mg5.dat',run_card=card_dir+
'run_card.dat',param_card=card_dir+
'param_card.dat',\
1595 madspin_card=card_dir+
'madspin_card.dat',reweight_card=card_dir+
'reweight_card.dat',warn_on_missing=
False)
1598 def print_cards(proc_card='proc_card_mg5.dat',run_card=None,param_card=None,madspin_card=None,reweight_card=None,warn_on_missing=True):
1599 if os.access(proc_card,os.R_OK):
1600 mglog.info(
"proc_card:")
1601 procCard = subprocess.Popen([
'cat',proc_card])
1603 elif warn_on_missing:
1604 mglog.warning(
'No proc_card: '+proc_card+
' found')
1606 if run_card
is not None and os.access(run_card,os.R_OK):
1607 mglog.info(
"run_card:")
1608 runCard = subprocess.Popen([
'cat',run_card])
1610 elif run_card
is not None and warn_on_missing:
1611 mglog.warning(
'No run_card: '+run_card+
' found')
1613 mglog.info(
'Default run card in use')
1615 if param_card
is not None and os.access(param_card,os.R_OK):
1616 mglog.info(
"param_card:")
1617 paramCard = subprocess.Popen([
'cat',param_card])
1619 elif param_card
is not None and warn_on_missing:
1620 mglog.warning(
'No param_card: '+param_card+
' found')
1622 mglog.info(
'Default param card in use')
1624 if madspin_card
is not None and os.access(madspin_card,os.R_OK):
1625 mglog.info(
"madspin_card:")
1626 madspinCard = subprocess.Popen([
'cat',madspin_card])
1628 elif madspin_card
is not None and warn_on_missing:
1629 mglog.warning(
'No madspin_card: '+madspin_card+
' found')
1631 mglog.info(
'No madspin card in use')
1633 if reweight_card
is not None and os.access(reweight_card,os.R_OK):
1634 mglog.info(
"reweight_card:")
1635 madspinCard = subprocess.Popen([
'cat',reweight_card])
1637 elif reweight_card
is not None and warn_on_missing:
1638 mglog.warning(
'No reweight_card: '+reweight_card+
' found')
1640 mglog.info(
'No reweight card in use')
1644 """ Simple function for checking if there is a grid pack.
1645 Relies on the specific location of the unpacked gridpack (madevent)
1646 which is here set as a global variable. The gridpack is untarred by
1647 the transform (Gen_tf.py) and no sign is sent to the job itself
1648 that there is a gridpack in use except the file's existence"""
1649 if os.access(MADGRAPH_GRIDPACK_LOCATION,os.R_OK):
1650 mglog.info(
'Located input grid pack area')
1656 def modify_run_card(run_card_input=None,run_card_backup=None,process_dir=MADGRAPH_GRIDPACK_LOCATION,runArgs=None,settings={},skipBaseFragment=False):
1657 """Build a new run_card.dat from an existing one.
1658 This function can get a fresh runcard from DATAPATH or start from the process directory.
1659 Settings is a dictionary of keys (no spaces needed) and values to replace.
1664 for s
in list(settings.keys()):
1665 settings_lower[s.lower()] = settings[s]
1668 if run_card_input
is None:
1670 elif run_card_input
is not None and not os.access(run_card_input,os.R_OK):
1671 runcard = subprocess.Popen([
'get_files',
'-data',run_card_input])
1673 if not os.access(run_card_input,os.R_OK):
1674 raise RuntimeError(
'Could not get run card '+run_card_input)
1679 if not skipBaseFragment:
1680 MadGraphControl.MadGraphSystematicsUtils.setup_pdf_and_systematic_weights(MADGRAPH_PDFSETTING,settings_lower,isNLO)
1683 if runArgs
is not None:
1685 if 'iseed' not in settings_lower:
1686 settings_lower[
'iseed']=rand_seed
1687 if not isNLO
and 'python_seed' not in settings_lower:
1688 settings_lower[
'python_seed']=rand_seed
1689 if 'beamenergy' in settings_lower:
1690 mglog.warning(
'Do not set beam energy in MG settings. The variables are ebeam1 and ebeam2. Will use your setting of '+
str(settings_lower[
'beamenergy']))
1691 beamEnergy=settings_lower[
'beamenergy']
1692 settings_lower.pop(
'beamenergy')
1693 if 'ebeam1' not in settings_lower:
1694 settings_lower[
'ebeam1']=beamEnergy
1695 if 'ebeam2' not in settings_lower:
1696 settings_lower[
'ebeam2']=beamEnergy
1698 if 'nevents' in settings_lower:
1699 settings_lower[
'nevents'] =
int(settings_lower[
'nevents'])
1702 if 'custom_fcts' in settings_lower
and settings_lower[
'custom_fcts']:
1703 raw_name =
str(settings_lower[
'custom_fcts']).
split()[0]
1705 if runArgs
is not None and hasattr(runArgs,
'jobConfig'):
1706 cfgdir = runArgs.jobConfig[0]
if isinstance(runArgs.jobConfig, (list, tuple))
else runArgs.jobConfig
1708 full_path = os.path.join(cfgdir, raw_name)
1709 settings_lower[
'custom_fcts'] = os.path.abspath(full_path)
1710 print(f
"Using custom function(s), specified in custom_fcts with path: {settings_lower['custom_fcts']}")
1713 settings_lower[
'custom_fcts'] = os.path.abspath(raw_name)
1715 mglog.info(
'Modifying run card located at '+run_card_input)
1716 if run_card_backup
is not None:
1717 mglog.info(
'Keeping backup of original run card at '+run_card_backup)
1718 run_card_old = run_card_backup
1720 run_card_old = run_card_input+
'.old_to_be_deleted'
1721 mglog.debug(
'Modifying runcard settings: '+
str(settings_lower))
1722 if os.path.isfile(run_card_old):
1723 os.unlink(run_card_old)
1724 os.rename(run_card_input, run_card_old)
1726 oldCard =
open(run_card_old,
'r')
1727 newCard =
open(process_dir+
'/Cards/run_card.dat',
'w')
1729 for line
in iter(oldCard):
1730 if not line.strip().startswith(
'#'):
1731 command = line.split(
'!', 1)[0]
1732 comment = line.split(
'!', 1)[1]
if '!' in line
else ''
1734 setting = command.split(
'=')[-1]
1735 stripped_setting = setting.strip()
1736 oldValue =
'='.
join(command.split(
'=')[:-1])
1737 if stripped_setting.lower()
in settings_lower:
1739 if settings_lower[stripped_setting.lower()]
is None:
1741 mglog.info(
'Removing '+stripped_setting+
'.')
1742 used_settings += [ stripped_setting.lower() ]
1744 if stripped_setting.lower() ==
'custom_fcts':
1746 line =
' '+
str(settings_lower[stripped_setting.lower()])+
' = '+setting
1748 line +=
' !'+comment
1750 line = oldValue.replace(oldValue.strip(),
str(settings_lower[stripped_setting.lower()]))+
'='+setting
1752 line +=
' !' + comment
1753 mglog.info(
'Setting '+stripped_setting+
' = '+
str(settings_lower[stripped_setting.lower()]))
1754 used_settings += [ stripped_setting.lower() ]
1755 newCard.write(line.strip()+
'\n')
1758 if 'mcatnlo_delta' in settings_lower:
1759 if settings_lower[
'mcatnlo_delta'] ==
'True':
1760 modify_config_card(process_dir=process_dir,settings={
'pythia8_path':os.getenv(
"PY8PATH")})
1763 for asetting
in settings_lower:
1764 if asetting
in used_settings:
1766 if settings_lower[asetting]
is None:
1768 mglog.info(
'Option '+asetting+
' was not in the default run_card (normal for hidden options). Adding by hand a setting to '+
str(settings_lower[asetting]) )
1769 newCard.write(
' '+
str(settings_lower[asetting])+
' = '+
str(asetting)+
'\n')
1773 mglog.info(
'Finished modification of run card.')
1774 if run_card_backup
is None:
1775 os.unlink(run_card_old)
1778 def modify_config_card(config_card_backup=None,process_dir=MADGRAPH_GRIDPACK_LOCATION,settings={},set_commented=True):
1779 """Build a new configuration from an existing one.
1780 This function can get a fresh runcard from DATAPATH or start from the process directory.
1781 Settings is a dictionary of keys (no spaces needed) and values to replace.
1787 mglog.info(
'Modifying config card located at '+config_card)
1788 if config_card_backup
is not None:
1789 mglog.info(
'Keeping backup of original config card at '+config_card_backup)
1790 config_card_old = config_card_backup
1792 config_card_old = config_card+
'.old_to_be_deleted'
1793 mglog.debug(
'Modifying config card settings: '+
str(settings))
1794 if os.path.isfile(config_card_old):
1795 os.unlink(config_card_old)
1796 os.rename(config_card, config_card_old)
1798 oldCard =
open(config_card_old,
'r')
1799 newCard =
open(config_card,
'w')
1801 for line
in iter(oldCard):
1802 lmod = line
if set_commented
else line.split(
'#')[0]
1805 for setting
in settings:
1806 if setting
not in lmod:
1809 mglog.info(
'Setting '+setting.strip()+
' to '+
str(settings[setting]))
1810 newCard.write(
' '+
str(setting.strip())+
' = '+
str(settings[setting])+
'\n')
1811 used_settings += [ setting.strip() ]
1819 for asetting
in settings:
1820 if asetting
in used_settings:
1822 if settings[asetting]
is None:
1824 mglog.warning(
'Option '+asetting+
' was not in the default config card. Adding by hand a setting to '+
str(settings[asetting]) )
1825 newCard.write(
' '+
str(asetting)+
' = '+
str(settings[asetting])+
'\n')
1829 mglog.info(
'Finished modification of config card.')
1830 if config_card_backup
is None:
1831 os.unlink(config_card_old)
1837 for l
in card_in.readlines():
1838 if 'cluster_type' not in l.split(
'#')[0]:
1840 cluster_type = l.split(
'#')[0].
split(
'=')[1]
1841 mglog.info(
'Returning cluster type: '+cluster_type)
1848 cardpath=process_dir+
'/Cards/run_card.dat'
1850 global my_MGC_instance
1854 modify_run_card(process_dir=process_dir,settings={
'event_norm':
'average'},skipBaseFragment=
True)
1855 mglog.warning(
"setting event_norm to average, there is basically no use case where event_norm=sum is a good idea")
1859 if 'ktdurham' in mydict
and float(mydict[
'ktdurham']) > 0
and int(mydict[
'ickkw']) != 0:
1860 log=
'Bad combination of settings for CKKW-L merging! ktdurham=%s and ickkw=%s.'%(mydict[
'ktdurham'],mydict[
'ickkw'])
1862 raise RuntimeError(log)
1865 if 'systematics_program' not in mydict
or mydict[
'systematics_program']==
'systematics':
1866 syscalc_settings=[
'sys_pdf',
'sys_scalefact',
'sys_alpsfact',
'sys_matchscale']
1867 found_syscalc_setting=
False
1868 for s
in syscalc_settings:
1870 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)')
1871 found_syscalc_setting=
True
1872 if found_syscalc_setting:
1873 syst_arguments=MadGraphControl.MadGraphSystematicsUtils.convertSysCalcArguments(mydict)
1874 mglog.info(
'Converted syscalc arguments to systematics arguments: '+syst_arguments)
1875 syst_settings_update={
'systematics_arguments':syst_arguments}
1876 for s
in syscalc_settings:
1877 syst_settings_update[s]=
None
1878 modify_run_card(process_dir=process_dir,settings=syst_settings_update,skipBaseFragment=
True)
1883 mglog.info(
'Checking PDF and systematics settings')
1884 if not MadGraphControl.MadGraphSystematicsUtils.base_fragment_setup_check(MADGRAPH_PDFSETTING,mydict,isNLO):
1886 syst_settings=MadGraphControl.MadGraphSystematicsUtils.get_pdf_and_systematic_settings(MADGRAPH_PDFSETTING,isNLO)
1887 modify_run_card(process_dir=process_dir,settings=syst_settings,skipBaseFragment=
True)
1890 if 'systematics_arguments' in mydict_new:
1891 systematics_arguments=MadGraphControl.MadGraphSystematicsUtils.parse_systematics_arguments(mydict_new[
'systematics_arguments'])
1892 if 'weight_info' not in systematics_arguments:
1893 mglog.info(
'Enforcing systematic weight name convention')
1895 if '--dyn' in systematics_arguments
or ' dyn' in systematics_arguments:
1896 if '--dyn' in systematics_arguments:
1897 dyn = systematics_arguments.split(
'--dyn')[1]
1898 if ' dyn' in systematics_arguments:
1899 dyn = systematics_arguments.split(
' dyn')[1]
1900 dyn = dyn.replace(
'\'',
' ').
replace(
'=',
' ').
split()[0]
1901 if dyn
is not None and len(dyn.split(
','))>1:
1902 systematics_arguments[
'weight_info']=MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO_ALTDYNSCALES
1904 systematics_arguments[
'weight_info']=MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO
1905 modify_run_card(process_dir=process_dir,settings={
'systematics_arguments':MadGraphControl.MadGraphSystematicsUtils.write_systematics_arguments(systematics_arguments)},skipBaseFragment=
True)
1908 if 'python_seed' not in mydict:
1909 mglog.warning(
'No python seed set in run_card -- adding one with same value as iseed')
1910 modify_run_card(process_dir=process_dir,settings={
'python_seed':mydict[
'iseed']},skipBaseFragment=
True)
1914 proton_5flav =
False
1916 with open(process_dir+
'/Cards/proc_card_mg5.dat',
'r')
as file:
1917 content = file.readlines()
1918 for rawline
in content:
1919 line = rawline.split(
'#')[0]
1920 if line.startswith(
"define p"):
1921 if (
'b' in line.split()
and 'b~' in line.split())
or (
'5' in line.split()
and '-5' in line.split()):
1923 if 'j' in line.split()
and jet_5flav:
1925 if line.startswith(
"define j"):
1926 if (
'b' in line.split()
and 'b~' in line.split())
or (
'5' in line.split()
and '-5' in line.split()):
1928 if 'p' in line.split()
and proton_5flav:
1930 if proton_5flav
or jet_5flav:
1931 FS_updates[
'asrwgtflavor'] = 5
1932 if not proton_5flav:
1933 mglog.warning(
'Found 5-flavour jets but 4-flavour proton. This is inconsistent - please pick one.')
1934 mglog.warning(
'Will proceed assuming 5-flavour scheme.')
1936 mglog.warning(
'Found 5-flavour protons but 4-flavour jets. This is inconsistent - please pick one.')
1937 mglog.warning(
'Will proceed assuming 5-flavour scheme.')
1939 FS_updates[
'asrwgtflavor'] = 4
1941 if len(FS_updates)==0:
1942 mglog.warning(f
'Could not identify 4- or 5-flavor scheme from process card {process_dir}/Cards/proc_card_mg5.dat')
1944 if 'asrwgtflavor' in mydict
or 'maxjetflavor' in mydict
or 'pdgs_for_merging_cut' in mydict:
1945 if FS_updates[
'asrwgtflavor'] == 5:
1947 if (
'asrwgtflavor' in mydict
and int(mydict[
'asrwgtflavor']) != 5)
or (
'maxjetflavor' in mydict
and int(mydict[
'maxjetflavor']) != 5)
or (
'pdgs_for_merging_cut' in mydict
and '5' not in mydict[
'pdgs_for_merging_cut']):
1949 mglog.warning(
'b and b~ included in p and j for 5-flavor scheme but run card settings are inconsistent; adjusting run card')
1950 run_card_updates = {
'asrwgtflavor': 5,
'maxjetflavor': 5,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 5, 21'}
1951 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1952 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'0.000000e+00'}})
1954 mglog.debug(
'Consistent 5-flavor scheme setup detected.')
1955 if FS_updates[
'asrwgtflavor'] == 4:
1957 if (
'asrwgtflavor' in mydict
and int(mydict[
'asrwgtflavor']) != 4)
or (
'maxjetflavor' in mydict
and int(mydict[
'maxjetflavor']) != 4)
or (
'pdgs_for_merging_cut' in mydict
and '5' in mydict[
'pdgs_for_merging_cut']):
1959 mglog.warning(
'b and b~ not included in p and j (4-flavor scheme) but run card settings are inconsistent; adjusting run card')
1960 run_card_updates = {
'asrwgtflavor': 4,
'maxjetflavor': 4,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 21'}
1961 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1962 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'4.700000e+00'}})
1964 mglog.debug(
'Consistent 4-flavor scheme setup detected.')
1967 if FS_updates[
'asrwgtflavor'] == 4:
1969 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.')
1970 run_card_updates = {
'asrwgtflavor': 4,
'maxjetflavor': 4,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 21'}
1971 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1972 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'4.700000e+00'}})
1973 elif FS_updates[
'asrwgtflavor'] == 5:
1974 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.')
1975 run_card_updates = {
'asrwgtflavor': 5,
'maxjetflavor': 5,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 5, 21'}
1976 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1977 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'0.000000e+00'}})
1979 mglog.info(
'Finished checking run card - All OK!')
1982 mglog.info(
'Running reweighting module on existing events')
1983 if reweight_card
is not None:
1984 mglog.info(
'Copying new reweight card from '+reweight_card)
1985 shutil.move(reweight_card,process_dir+
'/Cards/reweight_card.dat')
1986 reweight_cmd=
'{}/bin/madevent reweight {} -f'.
format(process_dir,run_name)
1987 global MADGRAPH_CATCH_ERRORS
1988 reweight =
stack_subprocess([python]+reweight_cmd.split(),stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
1989 (out,err) = reweight.communicate()
1991 mglog.info(
'Finished reweighting')
1997 mglog.info(
'For your information, ls of '+directory+
':')
1998 mglog.info(
sorted( os.listdir( directory ) ) )
2001 import MadGraphControl.MadGraphSystematicsUtils
2005 makefile_fks=process_dir+
'/SubProcesses/makefile_fks_dir'
2006 mglog.info(
'Fixing '+makefile_fks)
2007 shutil.move(makefile_fks,makefile_fks+
'_orig')
2008 fin=
open(makefile_fks+
'_orig')
2009 fout=
open(makefile_fks,
'w')
2012 if 'FKSParams.mod' in line:
2013 fout.write(line.replace(
'FKSParams.mod',
'FKSParams.o'))
2015 elif edit
and 'driver_mintFO' in line:
2016 fout.write(
'driver_mintFO.o: weight_lines.o mint_module.o FKSParams.o\n')
2017 elif edit
and 'genps_fks.o' in line:
2018 fout.write(
'genps_fks.o: mint_module.o FKSParams.o\n')
2019 elif edit
and 'test_soft_col_limits' in line:
2021 fout.write(
'madfks_plot.o: mint_module.o\n')
2022 fout.write(
'cluster.o: weight_lines.o\n')