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)
86 modify_run_card(process_dir=my_MGC_instance.process_dir,settings=my_MGC_instance.runCardDict,skipBaseFragment=
True)
89 return my_MGC_instance.process_dir
92 """ Copy the default runcard from one of several locations
93 to a local file with name run_card.tmp.dat"""
94 output_name =
'run_card.tmp.dat'
97 run_card=process_dir+
'/Cards/run_card.dat'
98 if os.access(run_card,os.R_OK):
99 mglog.info(
'Copying default run_card.dat from '+
str(run_card))
100 shutil.copy(run_card,output_name)
103 run_card=process_dir+
'/Cards/run_card_default.dat'
104 mglog.info(
'Fetching default run_card.dat from '+
str(run_card))
105 if os.access(run_card,os.R_OK):
106 shutil.copy(run_card,output_name)
109 raise RuntimeError(
'Cannot find default run_card.dat or run_card_default.dat! I was looking here: %s'%run_card)
112 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):
113 global my_MGC_instance
120 if 'ATHENA_CORE_NUMBER' in os.environ
and int(os.environ[
'ATHENA_CORE_NUMBER'])>0:
121 njobs =
int(os.environ[
'ATHENA_CORE_NUMBER'])
122 mglog.info(
'Lucky you - you are running on a full node queue. Will re-configure for '+
str(njobs)+
' jobs.')
126 if cluster_type
is not None:
130 mglog.info(
'Running event generation from gridpack (using smarter mode from generate() function)')
131 generate_from_gridpack(runArgs=runArgs,extlhapath=extlhapath,gridpack_compile=gridpack_compile,requirePMGSettings=requirePMGSettings)
134 mglog.info(
'Did not identify an input gridpack.')
136 mglog.info(
'The grid_pack flag is set, so I am expecting to create a gridpack in this job')
150 from distutils.spawn
import find_executable
151 if find_executable(
'f2py')
is not None:
152 mglog.info(
'Found f2py, will use it for reweighting')
154 raise RuntimeError(
'Could not find f2py, needed for reweighting')
157 global MADGRAPH_COMMAND_STACK
161 mglog.info(
'Started generating gridpack at '+
str(time.asctime()))
162 mglog.warning(
' >>>>>> THIS KIND OF JOB SHOULD ONLY BE RUN LOCALLY - NOT IN GRID JOBS <<<<<<')
165 my_settings = {
'nevents':
'1000'}
167 my_settings[
'req_acc']=
str(required_accuracy)
170 LO_has_madspin =
False
171 if os.access(f
'{process_dir}/Cards/madspin_card.dat',os.R_OK):
172 MADGRAPH_COMMAND_STACK += [f
'mv {process_dir}/Cards/madspin_card.dat {process_dir}/Cards/madspin_card.tmp.dat']
173 os.rename(f
'{process_dir}/Cards/madspin_card.dat',f
'{process_dir}/Cards/madspin_card.tmp.dat')
174 LO_has_madspin =
True
175 my_settings = {
'gridpack':
'true'}
176 modify_run_card(process_dir=process_dir,settings=my_settings,skipBaseFragment=
True)
180 mglog.info(
'Started generating at '+
str(time.asctime()))
182 mglog.info(
'Run '+MADGRAPH_RUN_NAME+
' will be performed in mode '+
str(mode)+
' with '+
str(njobs)+
' jobs in parallel.')
185 if not os.access(process_dir,os.R_OK):
186 raise RuntimeError(
'No process directory found at '+process_dir)
187 if not os.access(process_dir+
'/bin/generate_events',os.R_OK):
188 raise RuntimeError(
'No generate_events module found in '+process_dir)
190 mglog.info(
'For your information, the libraries available are (should include LHAPDF):')
191 ls_dir(process_dir+
'/lib')
194 if bias_module
is not None:
197 mglog.info(
'Now I will hack the make files a bit. Apologies, but there seems to be no good way around this.')
198 shutil.copyfile(process_dir+
'/Source/make_opts',process_dir+
'/Source/make_opts_old')
199 old_opts =
open(process_dir+
'/Source/make_opts_old',
'r')
200 new_opts =
open(process_dir+
'/Source/make_opts',
'w')
201 for aline
in old_opts:
203 mglog.info(
'Configuring the fancy gfortran compiler instead of g77 / f77')
204 new_opts.write(
' FC=gfortran\n')
206 new_opts.write(aline)
209 mglog.info(
'Make file hacking complete.')
213 os.chdir(process_dir)
215 MADGRAPH_COMMAND_STACK += [
'cd ${MGaMC_PROCESS_DIR}' ]
225 if requirePMGSettings
and code!=0:
226 raise RuntimeError(
'Settings are not compliant with PMG defaults! Please use do_PMG_updates function to get PMG default params.')
230 command = [python,
'bin/generate_events']
232 command += [
'--name='+MADGRAPH_RUN_NAME]
233 mglog.info(
'Removing Cards/shower_card.dat to ensure we get parton level events only')
234 os.unlink(
'Cards/shower_card.dat')
236 command += [MADGRAPH_RUN_NAME]
238 setNCores(process_dir=os.getcwd(), Ncores=njobs)
241 mglog.info(
'Setting up cluster running')
243 if cluster_type==
'pbs':
244 mglog.info(
'Modifying bin/internal/cluster.py for PBS cluster running')
245 os.system(
"sed -i \"s:text += prog:text += './'+prog:g\" bin/internal/cluster.py")
247 mglog.info(
'Setting up multi-core running on '+os.environ[
'ATHENA_CORE_NUMBER']+
' cores')
249 mglog.info(
'Setting up serial generation.')
252 global MADGRAPH_CATCH_ERRORS
253 generate =
stack_subprocess(command,stdin=subprocess.PIPE, stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
254 (out,err) = generate.communicate()
259 MADGRAPH_COMMAND_STACK += [
'cd -' ]
263 energy =
'%1.1f'%(beamEnergy*2./1000.)
264 energy = energy.replace(
'.0',
'').
replace(
'.',
'p')
266 mglog.info(
'Tidying up gridpack '+gridpack_name)
271 MADGRAPH_COMMAND_STACK += [f
'mv {process_dir}/Cards/madspin_card.tmp.dat {process_dir}/Cards/madspin_card.dat']
272 os.rename(f
'{process_dir}/Cards/madspin_card.tmp.dat',f
'{process_dir}/Cards/madspin_card.dat')
275 MADGRAPH_COMMAND_STACK += [
'cp '+glob.glob(process_dir+
'/'+MADGRAPH_RUN_NAME+
'_*gridpack.tar.gz')[0]+
' '+gridpack_name]
276 shutil.copy(glob.glob(process_dir+
'/'+MADGRAPH_RUN_NAME+
'_*gridpack.tar.gz')[0],gridpack_name)
279 MADGRAPH_COMMAND_STACK += [
'mkdir tmp%i/'%os.getpid(),
'cd tmp%i/'%os.getpid()]
280 os.mkdir(
'tmp%i/'%os.getpid())
281 os.chdir(
'tmp%i/'%os.getpid())
282 mglog.info(
'untar gridpack')
285 mglog.info(
'compile and clean up')
286 MADGRAPH_COMMAND_STACK += [
'cd madevent']
287 os.chdir(
'madevent/')
288 compilep =
stack_subprocess([
'./bin/compile'],stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
289 (out,err) = compilep.communicate()
291 clean =
stack_subprocess([
'./bin/clean4grid'],stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
292 (out,err) = clean.communicate()
295 MADGRAPH_COMMAND_STACK += [
'cd ..',
'rm ../'+gridpack_name]
297 mglog.info(
'remove old tarball')
298 os.unlink(
'../'+gridpack_name)
299 mglog.info(
'Package up new tarball')
300 tar =
stack_subprocess([
'tar',
'--exclude=SubProcesses/P*/G*/*_results.dat',
'--exclude=SubProcesses/P*/G*/*.log',
'--exclude=SubProcesses/P*/G*/*.txt',
'-cvsf',
'../'+gridpack_name,
'.'])
302 MADGRAPH_COMMAND_STACK += [
'cd ..',
'rm -r tmp%i/'%os.getpid()]
304 mglog.info(
'Remove temporary directory')
305 shutil.rmtree(
'tmp%i/'%os.getpid())
306 mglog.info(
'Tidying up complete!')
311 mglog.info(
'Package up process_dir')
312 MADGRAPH_COMMAND_STACK += [
'mv '+process_dir+
' '+MADGRAPH_GRIDPACK_LOCATION]
313 os.rename(process_dir,MADGRAPH_GRIDPACK_LOCATION)
314 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])
316 MADGRAPH_COMMAND_STACK += [
'mv '+MADGRAPH_GRIDPACK_LOCATION+
' '+process_dir]
317 os.rename(MADGRAPH_GRIDPACK_LOCATION,process_dir)
319 mglog.info(
'Gridpack sucessfully created, exiting the transform')
320 if hasattr(runArgs,
'outputTXTFile'):
321 mglog.info(
'Touching output TXT (LHE) file for the transform')
322 open(runArgs.outputTXTFile,
'w').close()
323 from AthenaCommon.AppMgr
import theApp
327 mglog.info(
'Finished at '+
str(time.asctime()))
332 global my_MGC_instance
339 isNLO=
is_NLO_run(process_dir=MADGRAPH_GRIDPACK_LOCATION)
344 gridpack_run_name =
'GridRun_'+
str(random_seed)
347 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/madspin_card.dat',os.R_OK):
348 os.rename(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/madspin_card.dat',MADGRAPH_GRIDPACK_LOCATION+
'/Cards/backup_madspin_card.dat')
358 if requirePMGSettings
and code!=0:
359 raise RuntimeError(
'Settings are not compliant with PMG defaults! Please use do_PMG_updates function to get PMG default params.')
362 settings={
'iseed':
str(random_seed)}
364 settings[
'python_seed']=
str(random_seed)
365 modify_run_card(process_dir=MADGRAPH_GRIDPACK_LOCATION,settings=settings,skipBaseFragment=
True)
367 mglog.info(
'Generating events from gridpack')
370 if not os.path.exists(MADGRAPH_GRIDPACK_LOCATION):
371 raise RuntimeError(
'Gridpack directory not found at '+MADGRAPH_GRIDPACK_LOCATION)
373 nevents =
getDictFromCard(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/run_card.dat')[
'nevents']
374 mglog.info(
'>>>> FOUND GRIDPACK <<<< <- This will be used for generation')
375 mglog.info(
'Generation of '+
str(
int(nevents))+
' events will be performed using the supplied gridpack with random seed '+
str(random_seed))
376 mglog.info(
'Started generating events at '+
str(time.asctime()))
379 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/bin/internal/addmasses.py',os.R_OK):
380 os.remove(MADGRAPH_GRIDPACK_LOCATION+
'/bin/internal/addmasses.py')
385 setNCores(process_dir=MADGRAPH_GRIDPACK_LOCATION)
386 global MADGRAPH_CATCH_ERRORS
390 ls_dir(MADGRAPH_GRIDPACK_LOCATION)
400 run_card_dict=
getDictFromCard(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/run_card.dat')
401 systematics_settings=
None
402 if checkSetting(
'systematics_program',
'systematics',run_card_dict):
404 raise RuntimeError(
'Trying to run NLO systematics but reweight info not stored')
406 systematics_settings=MadGraphControl.MadGraphSystematicsUtils.parse_systematics_arguments(run_card_dict[
'systematics_arguments'])
408 systematics_settings={}
409 mglog.info(
'Turning off systematics for now, running standalone later')
410 modify_run_card(process_dir=MADGRAPH_GRIDPACK_LOCATION,settings={
'systematics_program':
'none'},skipBaseFragment=
True)
412 global MADGRAPH_COMMAND_STACK
415 if not os.access(MADGRAPH_GRIDPACK_LOCATION+
'/bin/gridrun',os.R_OK):
416 mglog.error(
'/bin/gridrun not found at '+MADGRAPH_GRIDPACK_LOCATION)
417 raise RuntimeError(
'Could not find gridrun executable')
419 mglog.info(
'Found '+MADGRAPH_GRIDPACK_LOCATION+
'/bin/gridrun, starting generation.')
422 mglog.info(
"Now generating {} events with random seed {} and granularity {}".
format(
int(nevents),
int(random_seed),granularity))
424 new_ld_path=
":".
join([os.environ[
'LD_LIBRARY_PATH'],os.getcwd()+
'/'+MADGRAPH_GRIDPACK_LOCATION+
'/madevent/lib',os.getcwd()+
'/'+MADGRAPH_GRIDPACK_LOCATION+
'/HELAS/lib'])
425 os.environ[
'LD_LIBRARY_PATH']=new_ld_path
426 MADGRAPH_COMMAND_STACK+=[
"export LD_LIBRARY_PATH="+
":".
join([
'${LD_LIBRARY_PATH}',new_ld_path])]
427 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)
428 (out,err) = generate.communicate()
430 gp_events=MADGRAPH_GRIDPACK_LOCATION+
"/Events/GridRun_{}/unweighted_events.lhe.gz".
format(
int(random_seed))
431 if not os.path.exists(gp_events):
432 mglog.error(
'Error in gp generation, did not find events at '+gp_events)
436 if reweight_card
is not None:
437 pythonpath_backup=os.environ[
'PYTHONPATH']
439 os.environ[
'PYTHONPATH']=
':'.
join([p
for p
in pythonpath_backup.split(
':')
if 'madgraph5amc' not in p])
441 os.environ[
'PYTHONPATH']=pythonpath_backup
443 shutil.move(gp_events,
'events.lhe.gz')
447 if not os.access(MADGRAPH_GRIDPACK_LOCATION+
'/bin/generate_events',os.R_OK):
448 raise RuntimeError(
'Could not find generate_events executable at '+MADGRAPH_GRIDPACK_LOCATION)
450 mglog.info(
'Found '+MADGRAPH_GRIDPACK_LOCATION+
'/bin/generate_events, starting generation.')
452 ls_dir(MADGRAPH_GRIDPACK_LOCATION+
'/Events/')
453 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name, os.F_OK):
454 mglog.info(
'Removing '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
' directory from gridpack generation')
455 MADGRAPH_COMMAND_STACK += [
'rm -rf '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name]
456 shutil.rmtree(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name)
459 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1', os.F_OK):
460 mglog.info(
'Removing '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1 directory from gridpack generation')
461 MADGRAPH_COMMAND_STACK += [
'rm -rf '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1']
462 shutil.rmtree(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1')
464 ls_dir(MADGRAPH_GRIDPACK_LOCATION+
'/Events/')
466 if not gridpack_compile:
467 mglog.info(
'Copying make_opts from Template')
468 shutil.copy(os.environ[
'MADPATH']+
'/Template/LO/Source/make_opts',MADGRAPH_GRIDPACK_LOCATION+
'/Source/')
471 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)
472 (out,err) = generate.communicate()
475 mglog.info(
'Allowing recompilation of gridpack')
476 if os.path.islink(MADGRAPH_GRIDPACK_LOCATION+
'/lib/libLHAPDF.a'):
477 mglog.info(
'Unlinking '+MADGRAPH_GRIDPACK_LOCATION+
'/lib/libLHAPDF.a')
478 os.unlink(MADGRAPH_GRIDPACK_LOCATION+
'/lib/libLHAPDF.a')
481 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)
482 (out,err) = generate.communicate()
484 if isNLO
and systematics_settings
is not None:
486 mglog.info(
'Running systematics standalone')
487 systematics_path=MADGRAPH_GRIDPACK_LOCATION+
'/bin/internal/systematics.py'
488 events_location=MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/events.lhe.gz'
489 syst_cmd=[python,systematics_path]+[events_location]*2+[
"--"+k+
"="+systematics_settings[k]
for k
in systematics_settings]
490 mglog.info(
'running: '+
' '.
join(syst_cmd))
496 if not os.access(
'events.lhe.gz',os.R_OK):
497 mglog.info(
'Copying generated events to '+currdir)
498 if not os.path.exists(MADGRAPH_GRIDPACK_LOCATION+
'Events/'+gridpack_run_name):
499 shutil.copy(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/events.lhe.gz',
'events.lhe.gz')
501 mglog.info(
'Events were already in place')
505 mglog.info(
'Moving generated events to be in correct format for arrange_output().')
506 mglog.info(
'Unzipping generated events.')
510 mglog.info(
'Moving file over to '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe')
511 mkdir =
stack_subprocess([
'mkdir',
'-p',(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name)])
513 shutil.move(
'events.lhe',MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe')
515 mglog.info(
'Re-zipping into dataset name '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe.gz')
516 rezip =
stack_subprocess([
'gzip',MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe'])
524 os.rename(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/backup_madspin_card.dat',MADGRAPH_GRIDPACK_LOCATION+
'/Cards/madspin_card.dat')
525 mglog.info(
'Decaying with MadSpin.')
526 add_madspin(process_dir=MADGRAPH_GRIDPACK_LOCATION)
528 mglog.info(
'Finished at '+
str(time.asctime()))
537 mglog.info(
'Path to fastjet install dir: '+os.environ[
'FASTJETPATH'])
538 fastjetconfig = os.environ[
'FASTJETPATH']+
'/bin/fastjet-config'
540 mglog.info(
'fastjet-config --version: '+
str(subprocess.Popen([fastjetconfig,
'--version'],stdout = subprocess.PIPE).stdout.read().strip()))
541 mglog.info(
'fastjet-config --prefix: '+
str(subprocess.Popen([fastjetconfig,
'--prefix'],stdout = subprocess.PIPE).stdout.read().strip()))
544 config_card=process_dir+
'/Cards/me5_configuration.txt'
546 config_card=process_dir+
'/Cards/amcatnlo_configuration.txt'
548 oldcard =
open(config_card,
'r')
549 newcard =
open(config_card+
'.tmp',
'w')
552 if 'fastjet = ' in line:
553 newcard.write(
'fastjet = '+fastjetconfig+
'\n')
554 mglog.info(
'Setting fastjet = '+fastjetconfig+
' in '+config_card)
559 shutil.move(config_card+
'.tmp',config_card)
565 def setupLHAPDF(process_dir=None, extlhapath=None, allow_links=True):
566 global my_MGC_instance
570 origLHAPATH=os.environ[
'LHAPATH']
571 origLHAPDF_DATA_PATH=os.environ[
'LHAPDF_DATA_PATH']
579 run_card=process_dir+
'/Cards/run_card.dat'
582 if mydict[
"pdlabel"].
replace(
"'",
"") ==
'lhapdf':
584 mglog.info(
'creating local LHAPDF dir: MGC_LHAPDF/')
585 if os.path.islink(
'MGC_LHAPDF/'):
586 os.unlink(
'MGC_LHAPDF/')
587 elif os.path.isdir(
'MGC_LHAPDF/'):
588 shutil.rmtree(
'MGC_LHAPDF/')
590 newMGCLHA=
'MGC_LHAPDF/'
592 mkdir = subprocess.Popen([
'mkdir',
'-p',newMGCLHA])
595 pdfs_used=[
int(x)
for x
in mydict[
'lhaid'].
replace(
' ',
',').
split(
',') ]
597 if 'sys_pdf' in mydict:
603 pdfs_used.append(idx)
606 if 'systematics_arguments' in mydict:
607 systematics_arguments=MadGraphControl.MadGraphSystematicsUtils.parse_systematics_arguments(mydict[
'systematics_arguments'])
608 if 'pdf' in systematics_arguments:
614 pdfs_used.append(idx)
617 for pdf
in pdfs_used:
618 if isinstance(pdf,str)
and (pdf.lower()==
'errorset' or pdf.lower()==
'central'):
622 mglog.info(
"Found LHAPDF ID="+
str(pdfid)+
", name="+pdfname)
624 if not os.path.exists(newMGCLHA+pdfname)
and not os.path.lexists(newMGCLHA+pdfname):
625 if not os.path.exists(LHADATAPATH+
'/'+pdfname):
626 mglog.warning(
'PDF not installed at '+LHADATAPATH+
'/'+pdfname)
628 mglog.info(
'linking '+LHADATAPATH+
'/'+pdfname+
' --> '+newMGCLHA+pdfname)
629 os.symlink(LHADATAPATH+
'/'+pdfname,newMGCLHA+pdfname)
631 mglog.info(
'copying '+LHADATAPATH+
'/'+pdfname+
' --> '+newMGCLHA+pdfname)
632 shutil.copytree(LHADATAPATH+
'/'+pdfname,newMGCLHA+pdfname)
635 mglog.info(
'linking '+LHADATAPATH+
'/pdfsets.index --> '+newMGCLHA+
'pdfsets.index')
636 os.symlink(LHADATAPATH+
'/pdfsets.index',newMGCLHA+
'pdfsets.index')
638 atlasLHADATAPATH=LHADATAPATH.replace(
'sft.cern.ch/lcg/external/lhapdfsets/current',
'atlas.cern.ch/repo/sw/Generators/lhapdfsets/current')
639 mglog.info(
'linking '+atlasLHADATAPATH+
'/lhapdf.conf --> '+newMGCLHA+
'lhapdf.conf')
640 os.symlink(atlasLHADATAPATH+
'/lhapdf.conf',newMGCLHA+
'lhapdf.conf')
642 mglog.info(
'copying '+LHADATAPATH+
'/pdfsets.index --> '+newMGCLHA+
'pdfsets.index')
643 shutil.copy2(LHADATAPATH+
'/pdfsets.index',newMGCLHA+
'pdfsets.index')
645 atlasLHADATAPATH=LHADATAPATH.replace(
'sft.cern.ch/lcg/external/lhapdfsets/current',
'atlas.cern.ch/repo/sw/Generators/lhapdfsets/current')
646 mglog.info(
'copying '+atlasLHADATAPATH+
'/lhapdf.conf -->'+newMGCLHA+
'lhapdf.conf')
647 shutil.copy2(atlasLHADATAPATH+
'/lhapdf.conf',newMGCLHA+
'lhapdf.conf')
650 LHADATAPATH=os.getcwd()+
'/MGC_LHAPDF'
653 mglog.info(
'Not using LHAPDF')
654 return (LHAPATH,origLHAPATH,origLHAPDF_DATA_PATH)
658 os.environ[
'LHAPDF_DATA_PATH']=LHADATAPATH
660 mglog.info(
'Path to LHAPDF install dir: '+LHAPATH)
661 mglog.info(
'Path to LHAPDF data dir: '+LHADATAPATH)
662 if not os.path.isdir(LHADATAPATH):
663 raise RuntimeError(
'LHAPDF data dir not accesible: '+LHADATAPATH)
664 if not os.path.isdir(LHAPATH):
665 raise RuntimeError(
'LHAPDF path dir not accesible: '+LHAPATH)
669 lhapdfconfig=extlhapath
670 if not os.access(lhapdfconfig,os.X_OK):
671 raise RuntimeError(
'Failed to find valid external lhapdf-config at '+lhapdfconfig)
672 LHADATAPATH=subprocess.Popen([lhapdfconfig,
'--datadir'],stdout = subprocess.PIPE).stdout.read().strip()
673 mglog.info(
'Changing LHAPDF_DATA_PATH to '+LHADATAPATH)
674 os.environ[
'LHAPDF_DATA_PATH']=LHADATAPATH
676 getlhaconfig = subprocess.Popen([
'get_files',
'-data',
'lhapdf-config'])
679 if not os.access(os.getcwd()+
'/lhapdf-config',os.X_OK):
680 mglog.error(
'Failed to get lhapdf-config from MadGraphControl')
682 lhapdfconfig = os.getcwd()+
'/lhapdf-config'
684 mglog.info(
'lhapdf-config --version: '+
str(subprocess.Popen([lhapdfconfig,
'--version'],stdout = subprocess.PIPE).stdout.read().strip()))
685 mglog.info(
'lhapdf-config --prefix: '+
str(subprocess.Popen([lhapdfconfig,
'--prefix'],stdout = subprocess.PIPE).stdout.read().strip()))
686 mglog.info(
'lhapdf-config --libdir: '+
str(subprocess.Popen([lhapdfconfig,
'--libdir'],stdout = subprocess.PIPE).stdout.read().strip()))
687 mglog.info(
'lhapdf-config --datadir: '+
str(subprocess.Popen([lhapdfconfig,
'--datadir'],stdout = subprocess.PIPE).stdout.read().strip()))
688 mglog.info(
'lhapdf-config --pdfsets-path: '+
str(subprocess.Popen([lhapdfconfig,
'--pdfsets-path'],stdout = subprocess.PIPE).stdout.read().strip()))
690 modify_config_card(process_dir=process_dir,settings={
'lhapdf':lhapdfconfig,
'lhapdf_py3':lhapdfconfig})
692 mglog.info(
'Creating links for LHAPDF')
693 if os.path.islink(process_dir+
'/lib/PDFsets'):
694 os.unlink(process_dir+
'/lib/PDFsets')
695 elif os.path.isdir(process_dir+
'/lib/PDFsets'):
696 shutil.rmtree(process_dir+
'/lib/PDFsets')
698 os.symlink(LHADATAPATH,process_dir+
'/lib/PDFsets')
700 shutil.copytree(LHADATAPATH,process_dir+
'/lib/PDFsets')
701 mglog.info(
'Available PDFs are:')
702 mglog.info(
sorted( [ x
for x
in os.listdir(process_dir+
'/lib/PDFsets')
if ".tar.gz" not in x ] ) )
704 global MADGRAPH_COMMAND_STACK
705 MADGRAPH_COMMAND_STACK += [
'# Copy the LHAPDF files locally' ]
706 MADGRAPH_COMMAND_STACK += [
'cp -r '+os.getcwd()+
'/MGC_LHAPDF .' ]
707 MADGRAPH_COMMAND_STACK += [
'cp -r '+process_dir+
'/lib/PDFsets ${MGaMC_PROCESS_DIR}/lib/' ]
709 return (LHAPATH,origLHAPATH,origLHAPDF_DATA_PATH)
715 my_runMode = 2
if 'ATHENA_CORE_NUMBER' in os.environ
else 0
716 if Ncores
is None and 'ATHENA_CORE_NUMBER' in os.environ
and int(os.environ[
'ATHENA_CORE_NUMBER'])>0:
717 my_Ncores =
int(os.environ[
'ATHENA_CORE_NUMBER'])
719 if my_Ncores
is None:
720 mglog.info(
'Setting up for serial run')
723 modify_config_card(process_dir=process_dir,settings={
'nb_core':my_Ncores,
'run_mode':my_runMode,
'automatic_html_opening':
'False'})
732 madpath=os.environ[
'MADPATH']
733 if not os.access(madpath+
'/bin/mg5_aMC',os.R_OK):
734 raise RuntimeError(
'mg5_aMC executable not found in '+madpath)
735 return madpath+
'/bin/mg5_aMC'
739 """ Add lifetimes to the generated LHE file. Should be
740 called after generate_events is called.
745 if len(glob.glob(process_dir+
'/Events/*'))<1:
746 mglog.error(
'Process dir '+process_dir+
' does not contain events?')
747 run = glob.glob(process_dir+
'/Events/*')[0].
split(
'/')[-1]
752 tof_c =
open(
'time_of_flight_exec_card',
'w')
753 tof_c.write(
'launch '+process_dir+
''' -i
754 add_time_of_flight '''+run+((
' --threshold='+
str(threshold))
if threshold
is not None else ''))
757 mglog.info(
'Started adding time of flight info '+
str(time.asctime()))
759 global MADGRAPH_CATCH_ERRORS
760 generate =
stack_subprocess([python,me_exec,
'time_of_flight_exec_card'],stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
761 (out,err) = generate.communicate()
764 mglog.info(
'Finished adding time of flight information at '+
str(time.asctime()))
767 lhe_gz = glob.glob(process_dir+
'/Events/*/*lhe.gz')[0]
768 if not os.access(lhe_gz,os.R_OK):
769 mglog.info(
'LHE file needs to be zipped')
770 lhe = glob.glob(process_dir+
'/Events/*/*lhe.gz')[0]
775 mglog.info(
'LHE file zipped by MadGraph automatically. Nothing to do')
780 def add_madspin(madspin_card=None,process_dir=MADGRAPH_GRIDPACK_LOCATION):
781 """ Run madspin on the generated LHE file. Should be
782 run when you have inputGeneratorFile set.
783 Only requires a simplified process with the same model that you are
784 interested in (needed to set up a process directory for MG5_aMC)
789 if madspin_card
is not None:
790 shutil.copyfile(madspin_card,process_dir+
'/Cards/madspin_card.dat')
792 if len(glob.glob(process_dir+
'/Events/*'))<1:
793 mglog.error(
'Process dir '+process_dir+
' does not contain events?')
794 proc_dir_list = glob.glob(process_dir+
'/Events/*')
796 for adir
in proc_dir_list:
797 if 'GridRun_' in adir:
798 run=adir.split(
'/')[-1]
801 run=proc_dir_list[0].
split(
'/')[-1]
806 ms_c =
open(
'madspin_exec_card',
'w')
807 ms_c.write(
'launch '+process_dir+
''' -i
808 decay_events '''+run)
811 mglog.info(
'Started running madspin at '+
str(time.asctime()))
813 global MADGRAPH_CATCH_ERRORS
814 generate =
stack_subprocess([python,me_exec,
'madspin_exec_card'],stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
815 (out,err) = generate.communicate()
817 if len(glob.glob(process_dir+
'/Events/'+run+
'_decayed_*/')) == 0:
818 mglog.error(
'No '+process_dir+
'/Events/'+run+
'_decayed_*/ can be found')
819 raise RuntimeError(
'Problem while running MadSpin')
821 mglog.info(
'Finished running madspin at '+
str(time.asctime()))
824 lhe_gz = glob.glob(process_dir+
'/Events/*/*lhe.gz')[0]
825 if not os.access(lhe_gz,os.R_OK):
826 mglog.info(
'LHE file needs to be zipped')
827 lhe = glob.glob(process_dir+
'/Events/*/*lhe.gz')[0]
832 mglog.info(
'LHE file zipped by MadGraph automatically. Nothing to do')
836 """ Run MadSpin on an input LHE file. Takes the process
837 from the LHE file, so you don't need to have a process directory
838 set up in advance. Runs MadSpin and packs the LHE file up appropriately
839 Needs runArgs for the file handling"""
840 if not os.access(input_LHE,os.R_OK):
841 raise RuntimeError(
'Could not find LHE file '+input_LHE)
842 if not os.access(madspin_card,os.R_OK):
843 raise RuntimeError(
'Could not find input MadSpin card '+madspin_card)
845 shutil.copy(input_LHE,input_LHE+
'.original')
846 mglog.info(
'Put backup copy of LHE file at '+input_LHE+
'.original')
848 madspin_exec_card =
open(
'madspin_exec_card',
'w')
849 madspin_exec_card.write(
'import '+input_LHE+
'\n')
851 input_madspin_card =
open(madspin_card,
'r')
853 for l
in input_madspin_card.readlines():
854 commands = l.split(
'#')[0].
split()
856 if len(commands)>1
and 'import'==commands[0]
and not 'model'==commands[1]:
859 if len(commands)>0
and 'launch' == commands[0]:
861 madspin_exec_card.write(l.strip()+
'\n')
863 madspin_exec_card.write(
'launch\n')
864 madspin_exec_card.close()
865 input_madspin_card.close()
867 madpath=os.environ[
'MADPATH']
868 if not os.access(madpath+
'/MadSpin/madspin',os.R_OK):
869 raise RuntimeError(
'madspin executable not found in '+madpath)
870 mglog.info(
'Starting madspin at '+
str(time.asctime()))
871 global MADGRAPH_CATCH_ERRORS
872 generate =
stack_subprocess([python,madpath+
'/MadSpin/madspin',
'madspin_exec_card'],stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
873 (out,err) = generate.communicate()
875 mglog.info(
'Done with madspin at '+
str(time.asctime()))
879 if os.path.exists(os.getcwd()+
'/events.lhe'):
880 os.remove(os.getcwd()+
'/events.lhe')
882 mglog.info(
'Unzipping generated events.')
886 mglog.info(
'Putting a copy in place for the transform.')
887 mod_output =
open(os.getcwd()+
'/events.lhe',
'w')
891 with open(input_LHE,
'r')
as fileobject:
892 for line
in fileobject:
894 mod_output.write(line)
899 mglog.info(
'Removed '+
str(nEmpty)+
' empty lines from LHEF')
903 raise RuntimeError(
'Must provide runArgs to madspin_on_lhe')
905 outputDS = runArgs.outputTXTFile
if hasattr(runArgs,
'outputTXTFile')
else 'tmp_LHE_events.tar.gz'
907 mglog.info(
'Moving file over to '+outputDS.split(
'.tar.gz')[0]+
'.events')
908 shutil.move(os.getcwd()+
'/events.lhe',outputDS.split(
'.tar.gz')[0]+
'.events')
910 mglog.info(
'Re-zipping into dataset name '+outputDS)
911 rezip =
stack_subprocess([
'tar',
'cvzf',outputDS,outputDS.split(
'.tar.gz')[0]+
'.events'])
915 if hasattr(runArgs,
'outputTXTFile')
and runArgs.outputTXTFile
is not None:
916 outputDS = outputDS.split(
'.TXT')[0]
918 if runArgs
is not None:
919 mglog.debug(
'Setting inputGenerator file to '+outputDS)
920 runArgs.inputGeneratorFile=outputDS
923 def arrange_output(process_dir=MADGRAPH_GRIDPACK_LOCATION,lhe_version=None,saveProcDir=False,runArgs=None,fixEventWeightsForBridgeMode=False):
928 if len(glob.glob(os.path.join(process_dir,
'Events',
'*')))<1:
929 mglog.error(
'Process dir '+process_dir+
' does not contain events?')
930 proc_dir_list = glob.glob(os.path.join(process_dir,
'Events',
'*'))
933 for adir
in proc_dir_list:
934 if 'decayed' in adir:
937 if 'GridRun_' in adir:
940 elif os.path.join(process_dir,
'Events',MADGRAPH_RUN_NAME)
in adir:
942 if not os.access(this_run_name,os.R_OK):
943 raise RuntimeError(
'Unable to locate run directory')
945 hasUnweighted = os.access(this_run_name+
'/unweighted_events.lhe.gz',os.R_OK)
948 madspinDirs=
sorted(glob.glob(this_run_name+
'_decayed_*/'))
951 if hasRunMadSpin
and not hasUnweighted:
953 hasUnweighted = os.access(madspinDirs[-1]+
'/unweighted_events.lhe.gz',os.R_OK)
955 global MADGRAPH_COMMAND_STACK
964 if os.path.exists(madspinDirs[-1]+
'/unweighted_events.lhe.gz'):
965 MADGRAPH_COMMAND_STACK += [
'mv '+madspinDirs[-1]+
'/unweighted_events.lhe.gz'+
' '+this_run_name+
'/unweighted_events.lhe.gz']
966 shutil.move(madspinDirs[-1]+
'/unweighted_events.lhe.gz',this_run_name+
'/unweighted_events.lhe.gz')
967 mglog.info(
'Moving MadSpin events from '+madspinDirs[-1]+
'/unweighted_events.lhe.gz to '+this_run_name+
'/unweighted_events.lhe.gz')
968 elif os.path.exists(madspinDirs[-1]+
'/events.lhe.gz'):
969 MADGRAPH_COMMAND_STACK += [
'mv '+madspinDirs[-1]+
'/events.lhe.gz'+
' '+this_run_name+
'/unweighted_events.lhe.gz']
970 shutil.move(madspinDirs[-1]+
'/events.lhe.gz',this_run_name+
'/unweighted_events.lhe.gz')
971 mglog.info(
'Moving MadSpin events from '+madspinDirs[-1]+
'/events.lhe.gz to '+this_run_name+
'/unweighted_events.lhe.gz')
973 raise RuntimeError(
'MadSpin was run but can\'t find files :(')
976 MADGRAPH_COMMAND_STACK += [
'mv '+madspinDirs[-1]+
'/events.lhe.gz '+this_run_name+
'/events.lhe.gz']
977 shutil.move(madspinDirs[-1]+
'/events.lhe.gz',this_run_name+
'/events.lhe.gz')
978 mglog.info(
'Moving MadSpin events from '+madspinDirs[-1]+
'/events.lhe.gz to '+this_run_name+
'/events.lhe.gz')
981 mglog.error(
'MadSpin was run but can\'t find output folder '+(this_run_name+
'_decayed_1/'))
982 raise RuntimeError(
'MadSpin was run but can\'t find output folder '+(this_run_name+
'_decayed_1/'))
984 if fixEventWeightsForBridgeMode:
985 mglog.info(
"Fixing event weights after MadSpin... initial checks.")
993 eventsfilename=
"unweighted_events"
995 eventsfilename=
"events"
996 unzip =
stack_subprocess([
'gunzip',
'-f',this_run_name+
'/%s.lhe.gz' % eventsfilename])
999 for line
in open(process_dir+
'/Events/'+MADGRAPH_RUN_NAME+
'/%s.lhe'%eventsfilename):
1000 if "Number of Events" in line:
1002 MGnumevents=
int(sline[-1])
1003 elif "Integrated weight (pb)" in line:
1005 MGintweight=
float(sline[-1])
1006 elif "set spinmode none" in line:
1008 elif "</header>" in line:
1011 if spinmodenone
and MGnumevents>0
and MGintweight>0:
1012 mglog.info(
"Fixing event weights after MadSpin... modifying LHE file.")
1013 newlhe=
open(this_run_name+
'/%s_fixXS.lhe'%eventsfilename,
'w')
1021 event_norm_setting=
"average"
1023 for line
in open(this_run_name+
'/%s.lhe'%eventsfilename):
1026 if "<init>" in line:
1029 elif "</init>" in line:
1031 elif inInit
and initlinecount==0:
1035 if abs(
int(sline[-2])) == 3:
1036 event_norm_setting=
"sum"
1037 elif abs(
int(sline[-2])) == 4:
1038 event_norm_setting=
"average"
1039 elif inInit
and initlinecount==1:
1043 sline[0]=
str(MGintweight)
1044 sline[1]=
str(
float(sline[0])*relunc)
1045 if event_norm_setting==
"sum":
1046 sline[2]=
str(MGintweight/MGnumevents)
1047 elif event_norm_setting==
"average":
1048 sline[2]=
str(MGintweight)
1049 newline=
' '.
join(sline)
1052 elif inInit
and initlinecount>1:
1054 elif "<event>" in line:
1057 elif "</event>" in line:
1059 elif inEvent
and eventlinecount==0:
1062 if event_norm_setting==
"sum":
1063 sline[2]=
str(MGintweight/MGnumevents)
1064 elif event_norm_setting==
"average":
1065 sline[2]=
str(MGintweight)
1066 newline=
' '.
join(sline)
1069 newlhe.write(newline)
1072 mglog.info(
"Fixing event weights after MadSpin... cleaning up.")
1073 shutil.copyfile(this_run_name+
'/%s.lhe' % eventsfilename,
1074 this_run_name+
'/%s_badXS.lhe' % eventsfilename)
1076 shutil.move(this_run_name+
'/%s_fixXS.lhe' % eventsfilename,
1077 this_run_name+
'/%s.lhe' % eventsfilename)
1079 rezip =
stack_subprocess([
'gzip',this_run_name+
'/%s.lhe' % eventsfilename])
1082 rezip =
stack_subprocess([
'gzip',this_run_name+
'/%s_badXS.lhe' % eventsfilename])
1086 if os.path.exists(os.getcwd()+
'/events.lhe'):
1087 os.remove(os.getcwd()+
'/events.lhe')
1089 mglog.info(
'Unzipping generated events.')
1091 unzip =
stack_subprocess([
'gunzip',
'-f',this_run_name+
'/unweighted_events.lhe.gz'])
1097 mglog.info(
'Putting a copy in place for the transform.')
1099 orig_input = this_run_name+
'/unweighted_events.lhe'
1100 mod_output =
open(os.getcwd()+
'/events.lhe',
'w')
1102 orig_input = this_run_name+
'/events.lhe'
1103 mod_output =
open(os.getcwd()+
'/events.lhe',
'w')
1110 with open(orig_input,
'r')
as fileobject:
1111 for line
in fileobject:
1115 if '#' not in newline:
1117 elif '>' not in newline[ newline.find(
'#'): ]:
1120 mglog.info(
'Found bad LHE line with an XML mark in a comment: "'+newline.strip()+
'"')
1121 newline=newline[:newline.find(
'#')]+
'#'+ (newline[newline.find(
'#'):].
replace(
'>',
'-'))
1123 if initrwgt
is False:
1125 elif "</initrwgt>" in newline:
1127 elif "<initrwgt>" in newline:
1129 elif initrwgt
is not None:
1130 newline=newline.replace(
'_DYNSCALE-1',
'')
1131 if '</weight>' in newline:
1132 iend=newline.find(
'</weight>')
1133 istart=newline[:iend].rfind(
'>')
1134 lhe_weights+=[newline[istart+1:iend].strip()]
1135 mod_output.write(newline)
1139 mglog.info(
'Removed '+
str(nEmpty)+
' empty lines from LHEF')
1141 mglog.info(
"The following "+
str(len(lhe_weights))+
" weights have been written to the LHE file: "+
",".
join(lhe_weights))
1144 mglog.info(
"Checking whether the following expected weights are in LHE file: "+
",".
join(expected_weights))
1145 for w
in expected_weights:
1146 if w
not in lhe_weights:
1147 raise RuntimeError(
"Did not find expected weight "+w+
" in lhe file. Did the reweight or systematics module crash?")
1148 mglog.info(
"Found all required weights!")
1151 mod_output2 =
open(os.getcwd()+
'/events.lhe',
'r')
1152 test=mod_output2.readline()
1153 if 'version="' in test:
1154 mglog.info(
'Applying LHE version hack')
1155 final_file =
open(os.getcwd()+
'/events.lhe.copy',
'w')
1156 final_file.write(
'<LesHouchesEvents version="%i.0">\n'%lhe_version)
1157 shutil.copyfileobj(mod_output2, final_file)
1159 shutil.copy(os.getcwd()+
'/events.lhe.copy',os.getcwd()+
'/events.lhe')
1161 os.remove(os.getcwd()+
'/events.lhe.copy')
1166 raise RuntimeError(
'Must provide runArgs to arrange_output')
1168 if hasattr(runArgs,
'outputTXTFile'):
1169 outputDS = runArgs.outputTXTFile
1171 outputDS =
'tmp_LHE_events.tar.gz'
1173 mglog.info(
'Moving file over to '+outputDS.split(
'.tar.gz')[0]+
'.events')
1175 shutil.move(os.getcwd()+
'/events.lhe',outputDS.split(
'.tar.gz')[0]+
'.events')
1177 mglog.info(
'Re-zipping into dataset name '+outputDS)
1178 rezip =
stack_subprocess([
'tar',
'cvzf',outputDS,outputDS.split(
'.tar.gz')[0]+
'.events'])
1182 mglog.info(
'Removing the process directory')
1183 shutil.rmtree(process_dir,ignore_errors=
True)
1185 if os.path.isdir(
'MGC_LHAPDF/'):
1186 shutil.rmtree(
'MGC_LHAPDF/',ignore_errors=
True)
1189 if hasattr(runArgs,
'outputTXTFile')
and runArgs.outputTXTFile
is not None:
1190 outputDS = outputDS.split(
'.TXT')[0]
1192 if runArgs
is not None:
1193 mglog.debug(
'Setting inputGenerator file to '+outputDS)
1194 runArgs.inputGeneratorFile=outputDS
1196 mglog.info(
'All done with output arranging!')
1200 if reweight_card_loc
is None:
1203 f_rw=
open(reweight_card_loc)
1205 if 'launch' not in line:
1207 match=re.match(
r'launch.*--rwgt_info\s*=\s*(\S+).*',line.strip())
1208 if len(match.groups())!=1:
1209 raise RuntimeError(
'Unexpected format of reweight card in line'+line)
1211 names+=[match.group(1)]
1217 if syst_setting
is None or 'central_pdf' not in syst_setting:
1218 mglog.warning(
"Systematics have not been defined via base fragment or 'MADGRAPH_PDFSETTING', cannot check for expected weights")
1220 if 'pdf_variations' in syst_setting
and isinstance(syst_setting[
'pdf_variations'],list):
1221 names+=[MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO%{
'mur':1.0,
'muf':1.0,
'pdf':syst_setting[
'central_pdf']}]
1222 for pdf
in syst_setting[
'pdf_variations']:
1223 names+=[MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO%{
'mur':1.0,
'muf':1.0,
'pdf':pdf+1}]
1224 if 'alternative_pdfs' in syst_setting
and isinstance(syst_setting[
'alternative_pdfs'],list):
1225 for pdf
in syst_setting[
'alternative_pdfs']:
1226 names+=[MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO%{
'mur':1.0,
'muf':1.0,
'pdf':pdf}]
1227 if 'scale_variations' in syst_setting
and isinstance(syst_setting[
'scale_variations'],list):
1228 for mur
in syst_setting[
'scale_variations']:
1229 for muf
in syst_setting[
'scale_variations']:
1230 names+=[MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO%{
'mur':mur,
'muf':muf,
'pdf':syst_setting[
'central_pdf']}]
1234 run_card = process_dir+
'/Cards/run_card.dat'
1235 if isinstance(bias_module,tuple):
1236 mglog.info(
'Using bias module '+bias_module[0])
1237 the_run_card =
open(run_card,
'r')
1238 for line
in the_run_card:
1239 if 'bias_module' in line
and not bias_module[0]
in line:
1240 raise RuntimeError(
'You need to add the bias module '+bias_module[0]+
' to the run card to actually run it')
1241 the_run_card.close()
1242 if len(bias_module)!=3:
1243 raise RuntimeError(
'Please give a 3-tuple of strings containing bias module name, bias module, and makefile. Alternatively, give path to bias module tarball.')
1244 bias_module_newpath=process_dir+
'/Source/BIAS/'+bias_module[0]
1245 os.makedirs(bias_module_newpath)
1246 bias_module_file=
open(bias_module_newpath+
'/'+bias_module[0]+
'.f',
'w')
1247 bias_module_file.write(bias_module[1])
1248 bias_module_file.close()
1249 bias_module_make_file=
open(bias_module_newpath+
'/Makefile',
'w')
1250 bias_module_make_file.write(bias_module[2])
1251 bias_module_make_file.close()
1253 mglog.info(
'Using bias module '+bias_module)
1254 bias_module_name=bias_module.split(
'/')[-1].
replace(
'.gz',
'')
1255 bias_module_name=bias_module_name.replace(
'.tar',
'')
1256 the_run_card =
open(run_card,
'r')
1257 for line
in the_run_card:
1258 if 'bias_module' in line
and bias_module_name
not in line:
1259 raise RuntimeError(
'You need to add the bias module '+bias_module_name+
' to the run card to actually run it')
1260 the_run_card.close()
1262 if os.path.exists(bias_module+
'.tar.gz'):
1263 bias_module_path=bias_module+
'.tar.gz'
1264 elif os.path.exists(bias_module+
'.gz'):
1265 bias_module_path=bias_module+
'.gz'
1266 elif os.path.exists(bias_module):
1267 bias_module_path=bias_module
1269 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')
1271 bias_module_newpath=process_dir+
'/Source/BIAS/'+bias_module_path.split(
'/')[-1]
1272 mglog.info(
'Copying bias module into place: '+bias_module_newpath)
1273 shutil.copy(bias_module_path,bias_module_newpath)
1274 mglog.info(
'Unpacking bias module')
1275 if bias_module_newpath.endswith(
'.tar.gz'):
1276 untar =
stack_subprocess([
'tar',
'xvzf',bias_module_newpath,
'--directory='+process_dir+
'/Source/BIAS/'])
1278 elif bias_module_path.endswith(
'.gz'):
1284 if os.access(process_dir+
'/Cards/reweight_card.dat',os.R_OK):
1285 return process_dir+
'/Cards/reweight_card.dat'
1291 shutil.move(reweight_card,reweight_card+
'.old')
1292 oldcard =
open(reweight_card+
'.old',
'r')
1293 newcard =
open(reweight_card,
'w')
1295 info_expression=
r'launch.*--rwgt_info\s*=\s*(\S+).*'
1296 name_expression=info_expression.replace(
'info',
'name')
1297 goodname_expression=
r'^[A-Za-z0-9_\-.]+$'
1298 for line
in oldcard:
1300 if not line.strip().startswith(
'launch') :
1303 rwgt_name_match=re.match(name_expression,line.strip())
1304 rwgt_info_match=re.match(info_expression,line.strip())
1305 if rwgt_name_match
is None and rwgt_info_match
is None:
1306 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)
1307 for match
in [rwgt_info_match,rwgt_name_match]:
1310 if len(match.groups())!=1:
1311 raise RuntimeError(
'Unexpected format of reweight card in line: '+line)
1312 if not re.match(goodname_expression,match.group(1)):
1313 raise RuntimeError(
'No special character in reweighting info/name, only allowing '+goodname_expression)
1314 if rwgt_info_match
is not None:
1316 elif rwgt_name_match
is not None:
1317 newcard.write(line.strip()+
' --rwgt_info={0}\n'.
format(rwgt_name_match.group(1)))
1320 mglog.info(
'Updated reweight_card')
1325 def update_lhe_file(lhe_file_old,param_card_old=None,lhe_file_new=None,masses={},delete_old_lhe=True):
1326 """Build a new LHE file from an old one and an updated param card.
1327 The masses of some particles can be changed via the masses dictionary. No particles that appear in the events
1328 may have their masses changed.
1329 If the param card is provided, the decay block in the LHE file will be replaced with the one in the param card.
1330 By default, the old LHE file is removed.
1331 If None is provided as a new LHE file name, the new file will replace the old one."""
1333 lhe_file_new_tmp = lhe_file_new
if lhe_file_new
is not None else lhe_file_old+
'.tmp'
1335 if not os.access(lhe_file_old,os.R_OK):
1336 raise RuntimeError(
'Could not access old LHE file at '+
str(lhe_file_old)+
'. Please check the file location.')
1338 if param_card_old
is not None:
1339 paramcard = subprocess.Popen([
'get_files',
'-data',param_card_old])
1341 if not os.access(param_card_old,os.R_OK):
1342 raise RuntimeError(
'Could not get param card '+param_card_old)
1344 if os.access(lhe_file_new_tmp,os.R_OK):
1345 raise RuntimeError(
'Old file at'+
str(lhe_file_new_tmp)+
' in the current directory. Dont want to clobber it. Please move it first.')
1347 newlhe =
open(lhe_file_new_tmp,
'w')
1351 particles_in_events = []
1354 with open(lhe_file_old,
'r')
as fileobject:
1355 for line
in fileobject:
1356 if decayEdit
and '</slha>' not in line:
1358 if decayEdit
and '</slha>' in line:
1360 if line.strip().
upper().startswith(
'BLOCK')
or line.strip().
upper().startswith(
'DECAY')\
1361 and len(line.strip().
split()) > 1:
1362 pos = 0
if line.strip().startswith(
'DECAY')
else 1
1363 blockName = line.strip().
upper().
split()[pos]
1366 if blockName !=
'DECAY' and len(line.strip().
split()) > 0:
1367 akey = line.strip().
split()[0]
1368 elif blockName ==
'DECAY' and len(line.strip().
split()) > 1:
1369 akey = line.strip().
split()[1]
1372 if akey
is not None and blockName ==
'MASS' and akey
in masses:
1373 newlhe.write(
' '+akey+
' '+
str(masses[akey])+
' # \n')
1374 mglog.info(
' '+akey+
' '+
str(masses[akey])+
' #')
1379 if blockName ==
'DECAY' and param_card_old
is not None:
1381 oldparam =
open(param_card_old,
'r')
1383 for old_line
in oldparam.readlines():
1385 if old_line.strip().
upper().startswith(
'DECAY')
and len(old_line.strip().
split()) > 1:
1386 newBlockName = line.strip().
upper().
split()[pos]
1388 newlhe.write(old_line)
1389 elif newBlockName ==
'DECAY':
1391 newlhe.write(old_line)
1399 if not eventRead
and '<event>' in line:
1402 if len(line.split())==11:
1403 aparticle = line.split()[0]
1404 if aparticle
not in particles_in_events:
1405 particles_in_events += [aparticle]
1412 if akey
in particles_in_events:
1413 mglog.error(
'Attempted to change mass of a particle that was in an LHE event! This is not allowed!')
1420 if lhe_file_new
is None:
1421 os.remove(lhe_file_old)
1422 shutil.move(lhe_file_new_tmp,lhe_file_old)
1423 lhe_file_new_tmp = lhe_file_old
1425 elif delete_old_lhe:
1426 os.remove(lhe_file_old)
1428 return lhe_file_new_tmp
1433 """ Helper function when looking at param cards
1434 In some cases it's tricky to match keys - they may differ
1435 only in white space. This tries to sort out when we have
1436 a match, and then uses the one in blockParams afterwards.
1437 In the case of no match, it returns the original key.
1440 for key
in dictionary:
1442 if mod_key==test_key:
1447 def modify_param_card(param_card_input=None,param_card_backup=None,process_dir=MADGRAPH_GRIDPACK_LOCATION,params={},output_location=None):
1448 """Build a new param_card.dat from an existing one.
1449 Params should be a dictionary of dictionaries. The first key is the block name, and the second in the param name.
1450 Keys can include MASS (for masses) and DECAY X (for decays of particle X)"""
1454 if param_card_input
is None:
1455 param_card_input=process_dir+
'/Cards/param_card.dat'
1456 elif param_card_input
is not None and not os.access(param_card_input,os.R_OK):
1457 paramcard = subprocess.Popen([
'get_files',
'-data',param_card_input])
1459 if not os.access(param_card_input,os.R_OK):
1460 raise RuntimeError(
'Could not get param card '+param_card_input)
1461 mglog.info(
'Using input param card at '+param_card_input)
1465 for blockName
in list(params.keys()):
1466 paramsUpper[blockName.upper()] = {}
1467 for paramName
in list(params[blockName].
keys()):
1468 paramsUpper[blockName.upper()][paramName.upper()] = params[blockName][paramName]
1470 if param_card_backup
is not None:
1471 mglog.info(
'Keeping backup of original param card at '+param_card_backup)
1472 param_card_old = param_card_backup
1474 param_card_old = param_card_input+
'.old_to_be_deleted'
1475 if os.path.isfile(param_card_old):
1476 os.unlink(param_card_old)
1477 os.rename(param_card_input, param_card_old)
1479 oldcard =
open(param_card_old,
'r')
1480 param_card_location= process_dir+
'/Cards/param_card.dat' if output_location
is None else output_location
1481 newcard =
open(param_card_location,
'w')
1485 for linewithcomment
in oldcard:
1486 line=linewithcomment.split(
'#')[0]
1487 if line.strip().
upper().startswith(
'BLOCK')
or line.strip().
upper().startswith(
'DECAY')\
1488 and len(line.strip().
split()) > 1:
1489 if decayEdit
and blockName ==
'DECAY':
1491 pos = 0
if line.strip().startswith(
'DECAY')
else 1
1492 if blockName==
'MASS' and 'MASS' in paramsUpper:
1494 if "MASS" in doneParams:
1495 leftOvers = [ x
for x
in paramsUpper[
'MASS']
if x
not in doneParams[
'MASS'] ]
1497 leftOvers = [ x
for x
in paramsUpper[
'MASS'] ]
1499 for pdg_id
in leftOvers:
1500 mglog.warning(
'Adding mass line for '+
str(pdg_id)+
' = '+
str(paramsUpper[
'MASS'][pdg_id])+
' which was not in original param card')
1501 newcard.write(
' '+
str(pdg_id)+
' '+
str(paramsUpper[
'MASS'][pdg_id])+
'\n')
1502 doneParams[
'MASS'][pdg_id]=
True
1503 if blockName==
'DECAY' and 'DECAY' not in line.strip().
upper()
and 'DECAY' in paramsUpper:
1505 leftOvers = [ x
for x
in paramsUpper[
'DECAY']
if x
not in doneParams[
'DECAY'] ]
1506 for pdg_id
in leftOvers:
1507 mglog.warning(
'Adding decay for pdg id '+
str(pdg_id)+
' which was not in the original param card')
1508 newcard.write( paramsUpper[
'DECAY'][pdg_id].strip()+
'\n' )
1509 doneParams[
'DECAY'][pdg_id]=
True
1510 blockName = line.strip().
upper().
split()[pos]
1515 if blockName !=
'DECAY' and len(line.strip().
split()) > 0:
1518 if len(line.split())==2:
1519 akey = line.upper().strip().
split()[0]
1522 akey = line.upper().strip()[:line.strip().rfind(
' ')].strip()
1523 elif blockName ==
'DECAY' and len(line.strip().
split()) > 1:
1524 akey = line.strip().
split()[1]
1526 newcard.write(linewithcomment)
1530 if blockName
not in paramsUpper:
1531 newcard.write(linewithcomment)
1533 blockParams = paramsUpper[blockName]
1539 if '#' in linewithcomment:
1540 stringkey = linewithcomment[linewithcomment.find(
'#')+1:].strip()
1541 if len(stringkey.split()) > 0:
1542 stringkey = stringkey.split()[0].
upper()
1544 if akey
not in blockParams
and not (stringkey
is not None and stringkey
in blockParams):
1545 newcard.write(linewithcomment)
1548 if akey
in blockParams
and (stringkey
is not None and stringkey
in blockParams):
1549 raise RuntimeError(
'Conflicting use of numeric and string keys '+akey+
' and '+stringkey)
1551 theParam = blockParams.get(akey,blockParams[stringkey]
if stringkey
in blockParams
else None)
1552 if blockName
not in doneParams:
1553 doneParams[blockName] = {}
1554 if akey
in blockParams:
1555 doneParams[blockName][akey]=
True
1556 elif stringkey
is not None and stringkey
in blockParams:
1557 doneParams[blockName][stringkey]=
True
1560 if blockName==
"DECAY":
1561 if theParam.splitlines()[0].
split()[0].
upper()==
"DECAY":
1563 for newline
in theParam.splitlines():
1564 newcard.write(newline+
'\n')
1568 newcard.write(
'DECAY '+akey+
' '+
str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1569 mglog.info(
'DECAY '+akey+
' '+
str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1571 elif blockName==
'QNUMBERS':
1573 for newline
in theParam.splitlines():
1574 newcard.write(newline+
'\n')
1578 newcard.write(
' '+akey+
' '+
str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1579 mglog.info(
' '+akey+
' '+
str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1583 for blockName
in paramsUpper:
1584 if blockName
not in doneParams
and len(paramsUpper[blockName].
keys())>0:
1585 raise RuntimeError(
'Did not find any of the parameters for block '+blockName+
' in param_card')
1586 for paramName
in paramsUpper[blockName]:
1587 if paramName
not in doneParams[blockName]:
1588 raise RuntimeError(
'Was not able to replace parameter '+paramName+
' in param_card')
1597 card_dir=process_dir+
'/Cards/'
1598 print_cards(proc_card=card_dir+
'proc_card_mg5.dat',run_card=card_dir+
'run_card.dat',param_card=card_dir+
'param_card.dat',\
1599 madspin_card=card_dir+
'madspin_card.dat',reweight_card=card_dir+
'reweight_card.dat',warn_on_missing=
False)
1602 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):
1603 if os.access(proc_card,os.R_OK):
1604 mglog.info(
"proc_card:")
1605 procCard = subprocess.Popen([
'cat',proc_card])
1607 elif warn_on_missing:
1608 mglog.warning(
'No proc_card: '+proc_card+
' found')
1610 if run_card
is not None and os.access(run_card,os.R_OK):
1611 mglog.info(
"run_card:")
1612 runCard = subprocess.Popen([
'cat',run_card])
1614 elif run_card
is not None and warn_on_missing:
1615 mglog.warning(
'No run_card: '+run_card+
' found')
1617 mglog.info(
'Default run card in use')
1619 if param_card
is not None and os.access(param_card,os.R_OK):
1620 mglog.info(
"param_card:")
1621 paramCard = subprocess.Popen([
'cat',param_card])
1623 elif param_card
is not None and warn_on_missing:
1624 mglog.warning(
'No param_card: '+param_card+
' found')
1626 mglog.info(
'Default param card in use')
1628 if madspin_card
is not None and os.access(madspin_card,os.R_OK):
1629 mglog.info(
"madspin_card:")
1630 madspinCard = subprocess.Popen([
'cat',madspin_card])
1632 elif madspin_card
is not None and warn_on_missing:
1633 mglog.warning(
'No madspin_card: '+madspin_card+
' found')
1635 mglog.info(
'No madspin card in use')
1637 if reweight_card
is not None and os.access(reweight_card,os.R_OK):
1638 mglog.info(
"reweight_card:")
1639 madspinCard = subprocess.Popen([
'cat',reweight_card])
1641 elif reweight_card
is not None and warn_on_missing:
1642 mglog.warning(
'No reweight_card: '+reweight_card+
' found')
1644 mglog.info(
'No reweight card in use')
1648 """ Simple function for checking if there is a grid pack.
1649 Relies on the specific location of the unpacked gridpack (madevent)
1650 which is here set as a global variable. The gridpack is untarred by
1651 the transform (Gen_tf.py) and no sign is sent to the job itself
1652 that there is a gridpack in use except the file's existence"""
1653 if os.access(MADGRAPH_GRIDPACK_LOCATION,os.R_OK):
1654 mglog.info(
'Located input grid pack area')
1660 def modify_run_card(run_card_input=None,run_card_backup=None,process_dir=MADGRAPH_GRIDPACK_LOCATION,runArgs=None,settings={},skipBaseFragment=False):
1661 """Build a new run_card.dat from an existing one.
1662 This function can get a fresh runcard from DATAPATH or start from the process directory.
1663 Settings is a dictionary of keys (no spaces needed) and values to replace.
1668 for s
in list(settings.keys()):
1669 settings_lower[s.lower()] = settings[s]
1672 if run_card_input
is None:
1674 elif run_card_input
is not None and not os.access(run_card_input,os.R_OK):
1675 runcard = subprocess.Popen([
'get_files',
'-data',run_card_input])
1677 if not os.access(run_card_input,os.R_OK):
1678 raise RuntimeError(
'Could not get run card '+run_card_input)
1683 if not skipBaseFragment:
1684 MadGraphControl.MadGraphSystematicsUtils.setup_pdf_and_systematic_weights(MADGRAPH_PDFSETTING,settings_lower,isNLO)
1687 if runArgs
is not None:
1689 if 'iseed' not in settings_lower:
1690 settings_lower[
'iseed']=rand_seed
1691 if not isNLO
and 'python_seed' not in settings_lower:
1692 settings_lower[
'python_seed']=rand_seed
1693 if 'beamenergy' in settings_lower:
1694 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']))
1695 beamEnergy=settings_lower[
'beamenergy']
1696 settings_lower.pop(
'beamenergy')
1697 if 'ebeam1' not in settings_lower:
1698 settings_lower[
'ebeam1']=beamEnergy
1699 if 'ebeam2' not in settings_lower:
1700 settings_lower[
'ebeam2']=beamEnergy
1702 if 'nevents' in settings_lower:
1703 settings_lower[
'nevents'] =
int(settings_lower[
'nevents'])
1706 if 'custom_fcts' in settings_lower
and settings_lower[
'custom_fcts']:
1707 raw_name =
str(settings_lower[
'custom_fcts']).
split()[0]
1709 if runArgs
is not None and hasattr(runArgs,
'jobConfig'):
1710 cfgdir = runArgs.jobConfig[0]
if isinstance(runArgs.jobConfig, (list, tuple))
else runArgs.jobConfig
1712 full_path = os.path.join(cfgdir, raw_name)
1713 settings_lower[
'custom_fcts'] = os.path.abspath(full_path)
1714 print(f
"Using custom function(s), specified in custom_fcts with path: {settings_lower['custom_fcts']}")
1717 settings_lower[
'custom_fcts'] = os.path.abspath(raw_name)
1719 mglog.info(
'Modifying run card located at '+run_card_input)
1720 if run_card_backup
is not None:
1721 mglog.info(
'Keeping backup of original run card at '+run_card_backup)
1722 run_card_old = run_card_backup
1724 run_card_old = run_card_input+
'.old_to_be_deleted'
1725 mglog.debug(
'Modifying runcard settings: '+
str(settings_lower))
1726 if os.path.isfile(run_card_old):
1727 os.unlink(run_card_old)
1728 os.rename(run_card_input, run_card_old)
1730 oldCard =
open(run_card_old,
'r')
1731 newCard =
open(process_dir+
'/Cards/run_card.dat',
'w')
1733 for line
in iter(oldCard):
1734 if not line.strip().startswith(
'#'):
1735 command = line.split(
'!', 1)[0]
1736 comment = line.split(
'!', 1)[1]
if '!' in line
else ''
1738 setting = command.split(
'=')[-1]
1739 stripped_setting = setting.strip()
1740 oldValue =
'='.
join(command.split(
'=')[:-1])
1741 if stripped_setting.lower()
in settings_lower:
1743 if settings_lower[stripped_setting.lower()]
is None:
1745 mglog.info(
'Removing '+stripped_setting+
'.')
1746 used_settings += [ stripped_setting.lower() ]
1748 if stripped_setting.lower() ==
'custom_fcts':
1750 line =
' '+
str(settings_lower[stripped_setting.lower()])+
' = '+setting
1752 line +=
' !'+comment
1754 line = oldValue.replace(oldValue.strip(),
str(settings_lower[stripped_setting.lower()]))+
'='+setting
1756 line +=
' !' + comment
1757 mglog.info(
'Setting '+stripped_setting+
' = '+
str(settings_lower[stripped_setting.lower()]))
1758 used_settings += [ stripped_setting.lower() ]
1759 newCard.write(line.strip()+
'\n')
1762 if 'mcatnlo_delta' in settings_lower:
1763 if settings_lower[
'mcatnlo_delta'] ==
'True':
1764 modify_config_card(process_dir=process_dir,settings={
'pythia8_path':os.getenv(
"PY8PATH")})
1767 for asetting
in settings_lower:
1768 if asetting
in used_settings:
1770 if settings_lower[asetting]
is None:
1772 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]) )
1773 newCard.write(
' '+
str(settings_lower[asetting])+
' = '+
str(asetting)+
'\n')
1777 mglog.info(
'Finished modification of run card.')
1778 if run_card_backup
is None:
1779 os.unlink(run_card_old)
1782 def modify_config_card(config_card_backup=None,process_dir=MADGRAPH_GRIDPACK_LOCATION,settings={},set_commented=True):
1783 """Build a new configuration from an existing one.
1784 This function can get a fresh runcard from DATAPATH or start from the process directory.
1785 Settings is a dictionary of keys (no spaces needed) and values to replace.
1791 mglog.info(
'Modifying config card located at '+config_card)
1792 if config_card_backup
is not None:
1793 mglog.info(
'Keeping backup of original config card at '+config_card_backup)
1794 config_card_old = config_card_backup
1796 config_card_old = config_card+
'.old_to_be_deleted'
1797 mglog.debug(
'Modifying config card settings: '+
str(settings))
1798 if os.path.isfile(config_card_old):
1799 os.unlink(config_card_old)
1800 os.rename(config_card, config_card_old)
1802 oldCard =
open(config_card_old,
'r')
1803 newCard =
open(config_card,
'w')
1805 for line
in iter(oldCard):
1806 lmod = line
if set_commented
else line.split(
'#')[0]
1809 for setting
in settings:
1810 if setting
not in lmod:
1813 mglog.info(
'Setting '+setting.strip()+
' to '+
str(settings[setting]))
1814 newCard.write(
' '+
str(setting.strip())+
' = '+
str(settings[setting])+
'\n')
1815 used_settings += [ setting.strip() ]
1823 for asetting
in settings:
1824 if asetting
in used_settings:
1826 if settings[asetting]
is None:
1828 mglog.warning(
'Option '+asetting+
' was not in the default config card. Adding by hand a setting to '+
str(settings[asetting]) )
1829 newCard.write(
' '+
str(asetting)+
' = '+
str(settings[asetting])+
'\n')
1833 mglog.info(
'Finished modification of config card.')
1834 if config_card_backup
is None:
1835 os.unlink(config_card_old)
1841 for l
in card_in.readlines():
1842 if 'cluster_type' not in l.split(
'#')[0]:
1844 cluster_type = l.split(
'#')[0].
split(
'=')[1]
1845 mglog.info(
'Returning cluster type: '+cluster_type)
1852 cardpath=process_dir+
'/Cards/run_card.dat'
1854 global my_MGC_instance
1858 modify_run_card(process_dir=process_dir,settings={
'event_norm':
'average'},skipBaseFragment=
True)
1859 mglog.warning(
"setting event_norm to average, there is basically no use case where event_norm=sum is a good idea")
1863 if 'ktdurham' in mydict
and float(mydict[
'ktdurham']) > 0
and int(mydict[
'ickkw']) != 0:
1864 log=
'Bad combination of settings for CKKW-L merging! ktdurham=%s and ickkw=%s.'%(mydict[
'ktdurham'],mydict[
'ickkw'])
1866 raise RuntimeError(log)
1869 if 'systematics_program' not in mydict
or mydict[
'systematics_program']==
'systematics':
1870 syscalc_settings=[
'sys_pdf',
'sys_scalefact',
'sys_alpsfact',
'sys_matchscale']
1871 found_syscalc_setting=
False
1872 for s
in syscalc_settings:
1874 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)')
1875 found_syscalc_setting=
True
1876 if found_syscalc_setting:
1877 syst_arguments=MadGraphControl.MadGraphSystematicsUtils.convertSysCalcArguments(mydict)
1878 mglog.info(
'Converted syscalc arguments to systematics arguments: '+syst_arguments)
1879 syst_settings_update={
'systematics_arguments':syst_arguments}
1880 for s
in syscalc_settings:
1881 syst_settings_update[s]=
None
1882 modify_run_card(process_dir=process_dir,settings=syst_settings_update,skipBaseFragment=
True)
1887 mglog.info(
'Checking PDF and systematics settings')
1888 if not MadGraphControl.MadGraphSystematicsUtils.base_fragment_setup_check(MADGRAPH_PDFSETTING,mydict,isNLO):
1890 syst_settings=MadGraphControl.MadGraphSystematicsUtils.get_pdf_and_systematic_settings(MADGRAPH_PDFSETTING,isNLO)
1891 modify_run_card(process_dir=process_dir,settings=syst_settings,skipBaseFragment=
True)
1894 if 'systematics_arguments' in mydict_new:
1895 systematics_arguments=MadGraphControl.MadGraphSystematicsUtils.parse_systematics_arguments(mydict_new[
'systematics_arguments'])
1896 if 'weight_info' not in systematics_arguments:
1897 mglog.info(
'Enforcing systematic weight name convention')
1899 if '--dyn' in systematics_arguments
or ' dyn' in systematics_arguments:
1900 if '--dyn' in systematics_arguments:
1901 dyn = systematics_arguments.split(
'--dyn')[1]
1902 if ' dyn' in systematics_arguments:
1903 dyn = systematics_arguments.split(
' dyn')[1]
1904 dyn = dyn.replace(
'\'',
' ').
replace(
'=',
' ').
split()[0]
1905 if dyn
is not None and len(dyn.split(
','))>1:
1906 systematics_arguments[
'weight_info']=MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO_ALTDYNSCALES
1908 systematics_arguments[
'weight_info']=MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO
1909 modify_run_card(process_dir=process_dir,settings={
'systematics_arguments':MadGraphControl.MadGraphSystematicsUtils.write_systematics_arguments(systematics_arguments)},skipBaseFragment=
True)
1912 if 'python_seed' not in mydict:
1913 mglog.warning(
'No python seed set in run_card -- adding one with same value as iseed')
1914 modify_run_card(process_dir=process_dir,settings={
'python_seed':mydict[
'iseed']},skipBaseFragment=
True)
1918 proton_5flav =
False
1920 with open(process_dir+
'/Cards/proc_card_mg5.dat',
'r')
as file:
1921 content = file.readlines()
1922 for rawline
in content:
1923 line = rawline.split(
'#')[0]
1924 if line.startswith(
"define p"):
1925 if (
'b' in line.split()
and 'b~' in line.split())
or (
'5' in line.split()
and '-5' in line.split()):
1927 if 'j' in line.split()
and jet_5flav:
1929 if line.startswith(
"define j"):
1930 if (
'b' in line.split()
and 'b~' in line.split())
or (
'5' in line.split()
and '-5' in line.split()):
1932 if 'p' in line.split()
and proton_5flav:
1934 if proton_5flav
or jet_5flav:
1935 FS_updates[
'asrwgtflavor'] = 5
1936 if not proton_5flav:
1937 mglog.warning(
'Found 5-flavour jets but 4-flavour proton. This is inconsistent - please pick one.')
1938 mglog.warning(
'Will proceed assuming 5-flavour scheme.')
1940 mglog.warning(
'Found 5-flavour protons but 4-flavour jets. This is inconsistent - please pick one.')
1941 mglog.warning(
'Will proceed assuming 5-flavour scheme.')
1943 FS_updates[
'asrwgtflavor'] = 4
1945 if len(FS_updates)==0:
1946 mglog.warning(f
'Could not identify 4- or 5-flavor scheme from process card {process_dir}/Cards/proc_card_mg5.dat')
1948 if 'asrwgtflavor' in mydict
or 'maxjetflavor' in mydict
or 'pdgs_for_merging_cut' in mydict:
1949 if FS_updates[
'asrwgtflavor'] == 5:
1951 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']):
1953 mglog.warning(
'b and b~ included in p and j for 5-flavor scheme but run card settings are inconsistent; adjusting run card')
1954 run_card_updates = {
'asrwgtflavor': 5,
'maxjetflavor': 5,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 5, 21'}
1955 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1956 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'0.000000e+00'}})
1958 mglog.debug(
'Consistent 5-flavor scheme setup detected.')
1959 if FS_updates[
'asrwgtflavor'] == 4:
1961 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']):
1963 mglog.warning(
'b and b~ not included in p and j (4-flavor scheme) but run card settings are inconsistent; adjusting run card')
1964 run_card_updates = {
'asrwgtflavor': 4,
'maxjetflavor': 4,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 21'}
1965 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1966 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'4.700000e+00'}})
1968 mglog.debug(
'Consistent 4-flavor scheme setup detected.')
1971 if FS_updates[
'asrwgtflavor'] == 4:
1973 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.')
1974 run_card_updates = {
'asrwgtflavor': 4,
'maxjetflavor': 4,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 21'}
1975 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1976 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'4.700000e+00'}})
1977 elif FS_updates[
'asrwgtflavor'] == 5:
1978 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.')
1979 run_card_updates = {
'asrwgtflavor': 5,
'maxjetflavor': 5,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 5, 21'}
1980 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1981 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'0.000000e+00'}})
1983 mglog.info(
'Finished checking run card - All OK!')
1986 mglog.info(
'Running reweighting module on existing events')
1987 if reweight_card
is not None:
1988 mglog.info(
'Copying new reweight card from '+reweight_card)
1989 shutil.move(reweight_card,process_dir+
'/Cards/reweight_card.dat')
1990 reweight_cmd=
'{}/bin/madevent reweight {} -f'.
format(process_dir,run_name)
1991 global MADGRAPH_CATCH_ERRORS
1992 reweight =
stack_subprocess([python]+reweight_cmd.split(),stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
1993 (out,err) = reweight.communicate()
1995 mglog.info(
'Finished reweighting')
2001 mglog.info(
'For your information, ls of '+directory+
':')
2002 mglog.info(
sorted( os.listdir( directory ) ) )
2005 import MadGraphControl.MadGraphSystematicsUtils
2009 makefile_fks=process_dir+
'/SubProcesses/makefile_fks_dir'
2010 mglog.info(
'Fixing '+makefile_fks)
2011 shutil.move(makefile_fks,makefile_fks+
'_orig')
2012 fin=
open(makefile_fks+
'_orig')
2013 fout=
open(makefile_fks,
'w')
2016 if 'FKSParams.mod' in line:
2017 fout.write(line.replace(
'FKSParams.mod',
'FKSParams.o'))
2019 elif edit
and 'driver_mintFO' in line:
2020 fout.write(
'driver_mintFO.o: weight_lines.o mint_module.o FKSParams.o\n')
2021 elif edit
and 'genps_fks.o' in line:
2022 fout.write(
'genps_fks.o: mint_module.o FKSParams.o\n')
2023 elif edit
and 'test_soft_col_limits' in line:
2025 fout.write(
'madfks_plot.o: mint_module.o\n')
2026 fout.write(
'cluster.o: weight_lines.o\n')