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'}
168 my_settings[
'req_acc']=
str(required_accuracy)
171 LO_has_madspin =
False
172 if os.access(f
'{process_dir}/Cards/madspin_card.dat',os.R_OK):
173 MADGRAPH_COMMAND_STACK += [f
'mv {process_dir}/Cards/madspin_card.dat {process_dir}/Cards/madspin_card.tmp.dat']
174 os.rename(f
'{process_dir}/Cards/madspin_card.dat',f
'{process_dir}/Cards/madspin_card.tmp.dat')
175 LO_has_madspin =
True
176 my_settings = {
'gridpack':
'true'}
177 modify_run_card(process_dir=process_dir,settings=my_settings,skipBaseFragment=
True)
181 mglog.info(
'Started generating at '+
str(time.asctime()))
183 mglog.info(
'Run '+MADGRAPH_RUN_NAME+
' will be performed in mode '+
str(mode)+
' with '+
str(njobs)+
' jobs in parallel.')
186 if not os.access(process_dir,os.R_OK):
187 raise RuntimeError(
'No process directory found at '+process_dir)
188 if not os.access(process_dir+
'/bin/generate_events',os.R_OK):
189 raise RuntimeError(
'No generate_events module found in '+process_dir)
191 mglog.info(
'For your information, the libraries available are (should include LHAPDF):')
192 ls_dir(process_dir+
'/lib')
195 if bias_module
is not None:
198 mglog.info(
'Now I will hack the make files a bit. Apologies, but there seems to be no good way around this.')
199 shutil.copyfile(process_dir+
'/Source/make_opts',process_dir+
'/Source/make_opts_old')
200 old_opts =
open(process_dir+
'/Source/make_opts_old',
'r')
201 new_opts =
open(process_dir+
'/Source/make_opts',
'w')
202 for aline
in old_opts:
204 mglog.info(
'Configuring the fancy gfortran compiler instead of g77 / f77')
205 new_opts.write(
' FC=gfortran\n')
207 new_opts.write(aline)
210 mglog.info(
'Make file hacking complete.')
214 os.chdir(process_dir)
216 MADGRAPH_COMMAND_STACK += [
'cd ${MGaMC_PROCESS_DIR}' ]
223 original_systematics_program =
None if 'systematics_program' not in my_MGC_instance.runCardDict
else my_MGC_instance.runCardDict[
'systematics_program']
224 modify_run_card(process_dir=process_dir,settings={
'systematics_program':
'None'},skipBaseFragment=
True)
231 if requirePMGSettings
and code!=0:
232 raise RuntimeError(
'Settings are not compliant with PMG defaults! Please use do_PMG_updates function to get PMG default params.')
236 command = [python,
'bin/generate_events']
238 command += [
'--name='+MADGRAPH_RUN_NAME]
239 mglog.info(
'Removing Cards/shower_card.dat to ensure we get parton level events only')
240 os.unlink(
'Cards/shower_card.dat')
242 command += [MADGRAPH_RUN_NAME]
244 setNCores(process_dir=os.getcwd(), Ncores=njobs)
247 mglog.info(
'Setting up cluster running')
249 if cluster_type==
'pbs':
250 mglog.info(
'Modifying bin/internal/cluster.py for PBS cluster running')
251 os.system(
"sed -i \"s:text += prog:text += './'+prog:g\" bin/internal/cluster.py")
253 mglog.info(
'Setting up multi-core running on '+os.environ[
'ATHENA_CORE_NUMBER']+
' cores')
255 mglog.info(
'Setting up serial generation.')
258 global MADGRAPH_CATCH_ERRORS
259 generate =
stack_subprocess(command,stdin=subprocess.PIPE, stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
260 (out,err) = generate.communicate()
265 MADGRAPH_COMMAND_STACK += [
'cd -' ]
269 energy =
'%1.1f'%(beamEnergy*2./1000.)
270 energy = energy.replace(
'.0',
'').
replace(
'.',
'p')
272 mglog.info(
'Tidying up gridpack '+gridpack_name)
275 modify_run_card(process_dir=process_dir,settings={
'systematics_program':original_systematics_program})
280 MADGRAPH_COMMAND_STACK += [f
'mv {process_dir}/Cards/madspin_card.tmp.dat {process_dir}/Cards/madspin_card.dat']
281 os.rename(f
'{process_dir}/Cards/madspin_card.tmp.dat',f
'{process_dir}/Cards/madspin_card.dat')
284 MADGRAPH_COMMAND_STACK += [
'cp '+glob.glob(process_dir+
'/'+MADGRAPH_RUN_NAME+
'_*gridpack.tar.gz')[0]+
' '+gridpack_name]
285 shutil.copy(glob.glob(process_dir+
'/'+MADGRAPH_RUN_NAME+
'_*gridpack.tar.gz')[0],gridpack_name)
288 MADGRAPH_COMMAND_STACK += [
'mkdir tmp%i/'%os.getpid(),
'cd tmp%i/'%os.getpid()]
289 os.mkdir(
'tmp%i/'%os.getpid())
290 os.chdir(
'tmp%i/'%os.getpid())
291 mglog.info(
'untar gridpack')
294 mglog.info(
'compile and clean up')
295 MADGRAPH_COMMAND_STACK += [
'cd madevent']
296 os.chdir(
'madevent/')
297 compilep =
stack_subprocess([
'./bin/compile'],stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
298 (out,err) = compilep.communicate()
300 clean =
stack_subprocess([
'./bin/clean4grid'],stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
301 (out,err) = clean.communicate()
304 MADGRAPH_COMMAND_STACK += [
'cd ..',
'rm ../'+gridpack_name]
306 mglog.info(
'remove old tarball')
307 os.unlink(
'../'+gridpack_name)
308 mglog.info(
'Package up new tarball')
309 tar =
stack_subprocess([
'tar',
'--exclude=SubProcesses/P*/G*/*_results.dat',
'--exclude=SubProcesses/P*/G*/*.log',
'--exclude=SubProcesses/P*/G*/*.txt',
'-cvsf',
'../'+gridpack_name,
'.'])
311 MADGRAPH_COMMAND_STACK += [
'cd ..',
'rm -r tmp%i/'%os.getpid()]
313 mglog.info(
'Remove temporary directory')
314 shutil.rmtree(
'tmp%i/'%os.getpid())
315 mglog.info(
'Tidying up complete!')
320 mglog.info(
'Package up process_dir')
321 MADGRAPH_COMMAND_STACK += [
'mv '+process_dir+
' '+MADGRAPH_GRIDPACK_LOCATION]
322 os.rename(process_dir,MADGRAPH_GRIDPACK_LOCATION)
323 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])
325 MADGRAPH_COMMAND_STACK += [
'mv '+MADGRAPH_GRIDPACK_LOCATION+
' '+process_dir]
326 os.rename(MADGRAPH_GRIDPACK_LOCATION,process_dir)
328 mglog.info(
'Gridpack sucessfully created, exiting the transform')
329 if hasattr(runArgs,
'outputTXTFile'):
330 mglog.info(
'Touching output TXT (LHE) file for the transform')
331 open(runArgs.outputTXTFile,
'w').close()
332 from AthenaCommon.AppMgr
import theApp
336 mglog.info(
'Finished at '+
str(time.asctime()))
341 global my_MGC_instance
348 isNLO=
is_NLO_run(process_dir=MADGRAPH_GRIDPACK_LOCATION)
353 gridpack_run_name =
'GridRun_'+
str(random_seed)
356 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/madspin_card.dat',os.R_OK):
357 os.rename(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/madspin_card.dat',MADGRAPH_GRIDPACK_LOCATION+
'/Cards/backup_madspin_card.dat')
367 if requirePMGSettings
and code!=0:
368 raise RuntimeError(
'Settings are not compliant with PMG defaults! Please use do_PMG_updates function to get PMG default params.')
371 settings={
'iseed':
str(random_seed)}
373 settings[
'python_seed']=
str(random_seed)
374 modify_run_card(process_dir=MADGRAPH_GRIDPACK_LOCATION,settings=settings,skipBaseFragment=
True)
376 mglog.info(
'Generating events from gridpack')
379 if not os.path.exists(MADGRAPH_GRIDPACK_LOCATION):
380 raise RuntimeError(
'Gridpack directory not found at '+MADGRAPH_GRIDPACK_LOCATION)
382 nevents =
getDictFromCard(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/run_card.dat')[
'nevents']
383 mglog.info(
'>>>> FOUND GRIDPACK <<<< <- This will be used for generation')
384 mglog.info(
'Generation of '+
str(
int(nevents))+
' events will be performed using the supplied gridpack with random seed '+
str(random_seed))
385 mglog.info(
'Started generating events at '+
str(time.asctime()))
388 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/bin/internal/addmasses.py',os.R_OK):
389 os.remove(MADGRAPH_GRIDPACK_LOCATION+
'/bin/internal/addmasses.py')
394 setNCores(process_dir=MADGRAPH_GRIDPACK_LOCATION)
395 global MADGRAPH_CATCH_ERRORS
399 ls_dir(MADGRAPH_GRIDPACK_LOCATION)
409 run_card_dict=
getDictFromCard(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/run_card.dat')
410 systematics_settings=
None
411 if checkSetting(
'systematics_program',
'systematics',run_card_dict):
413 raise RuntimeError(
'Trying to run NLO systematics but reweight info not stored')
415 systematics_settings=MadGraphControl.MadGraphSystematicsUtils.parse_systematics_arguments(run_card_dict[
'systematics_arguments'])
417 systematics_settings={}
418 mglog.info(
'Turning off systematics for now, running standalone later')
419 modify_run_card(process_dir=MADGRAPH_GRIDPACK_LOCATION,settings={
'systematics_program':
'none'},skipBaseFragment=
True)
421 global MADGRAPH_COMMAND_STACK
424 if not os.access(MADGRAPH_GRIDPACK_LOCATION+
'/bin/gridrun',os.R_OK):
425 mglog.error(
'/bin/gridrun not found at '+MADGRAPH_GRIDPACK_LOCATION)
426 raise RuntimeError(
'Could not find gridrun executable')
428 mglog.info(
'Found '+MADGRAPH_GRIDPACK_LOCATION+
'/bin/gridrun, starting generation.')
431 mglog.info(
"Now generating {} events with random seed {} and granularity {}".
format(
int(nevents),
int(random_seed),granularity))
433 new_ld_path=
":".
join([os.environ[
'LD_LIBRARY_PATH'],os.getcwd()+
'/'+MADGRAPH_GRIDPACK_LOCATION+
'/madevent/lib',os.getcwd()+
'/'+MADGRAPH_GRIDPACK_LOCATION+
'/HELAS/lib'])
434 os.environ[
'LD_LIBRARY_PATH']=new_ld_path
435 MADGRAPH_COMMAND_STACK+=[
"export LD_LIBRARY_PATH="+
":".
join([
'${LD_LIBRARY_PATH}',new_ld_path])]
436 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)
437 (out,err) = generate.communicate()
439 gp_events=MADGRAPH_GRIDPACK_LOCATION+
"/Events/GridRun_{}/unweighted_events.lhe.gz".
format(
int(random_seed))
440 if not os.path.exists(gp_events):
441 mglog.error(
'Error in gp generation, did not find events at '+gp_events)
445 if reweight_card
is not None:
446 pythonpath_backup=os.environ[
'PYTHONPATH']
448 os.environ[
'PYTHONPATH']=
':'.
join([p
for p
in pythonpath_backup.split(
':')
if 'madgraph5amc' not in p])
450 os.environ[
'PYTHONPATH']=pythonpath_backup
452 shutil.move(gp_events,
'events.lhe.gz')
456 if not os.access(MADGRAPH_GRIDPACK_LOCATION+
'/bin/generate_events',os.R_OK):
457 raise RuntimeError(
'Could not find generate_events executable at '+MADGRAPH_GRIDPACK_LOCATION)
459 mglog.info(
'Found '+MADGRAPH_GRIDPACK_LOCATION+
'/bin/generate_events, starting generation.')
461 ls_dir(MADGRAPH_GRIDPACK_LOCATION+
'/Events/')
462 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name, os.F_OK):
463 mglog.info(
'Removing '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
' directory from gridpack generation')
464 MADGRAPH_COMMAND_STACK += [
'rm -rf '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name]
465 shutil.rmtree(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name)
468 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1', os.F_OK):
469 mglog.info(
'Removing '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1 directory from gridpack generation')
470 MADGRAPH_COMMAND_STACK += [
'rm -rf '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1']
471 shutil.rmtree(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1')
473 ls_dir(MADGRAPH_GRIDPACK_LOCATION+
'/Events/')
475 if not gridpack_compile:
476 mglog.info(
'Copying make_opts from Template')
477 shutil.copy(os.environ[
'MADPATH']+
'/Template/LO/Source/make_opts',MADGRAPH_GRIDPACK_LOCATION+
'/Source/')
480 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)
481 (out,err) = generate.communicate()
484 mglog.info(
'Allowing recompilation of gridpack')
485 if os.path.islink(MADGRAPH_GRIDPACK_LOCATION+
'/lib/libLHAPDF.a'):
486 mglog.info(
'Unlinking '+MADGRAPH_GRIDPACK_LOCATION+
'/lib/libLHAPDF.a')
487 os.unlink(MADGRAPH_GRIDPACK_LOCATION+
'/lib/libLHAPDF.a')
490 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)
491 (out,err) = generate.communicate()
493 if isNLO
and systematics_settings
is not None:
495 mglog.info(
'Running systematics standalone')
496 systematics_path=MADGRAPH_GRIDPACK_LOCATION+
'/bin/internal/systematics.py'
497 events_location=MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/events.lhe.gz'
498 syst_cmd=[python,systematics_path]+[events_location]*2+[
"--"+k+
"="+systematics_settings[k]
for k
in systematics_settings]
499 mglog.info(
'running: '+
' '.
join(syst_cmd))
505 if not os.access(
'events.lhe.gz',os.R_OK):
506 mglog.info(
'Copying generated events to '+currdir)
507 if not os.path.exists(MADGRAPH_GRIDPACK_LOCATION+
'Events/'+gridpack_run_name):
508 shutil.copy(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/events.lhe.gz',
'events.lhe.gz')
510 mglog.info(
'Events were already in place')
514 mglog.info(
'Moving generated events to be in correct format for arrange_output().')
515 mglog.info(
'Unzipping generated events.')
519 mglog.info(
'Moving file over to '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe')
520 mkdir =
stack_subprocess([
'mkdir',
'-p',(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name)])
522 shutil.move(
'events.lhe',MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe')
524 mglog.info(
'Re-zipping into dataset name '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe.gz')
525 rezip =
stack_subprocess([
'gzip',MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe'])
533 os.rename(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/backup_madspin_card.dat',MADGRAPH_GRIDPACK_LOCATION+
'/Cards/madspin_card.dat')
534 mglog.info(
'Decaying with MadSpin.')
535 add_madspin(process_dir=MADGRAPH_GRIDPACK_LOCATION)
537 mglog.info(
'Finished at '+
str(time.asctime()))
546 mglog.info(
'Path to fastjet install dir: '+os.environ[
'FASTJETPATH'])
547 fastjetconfig = os.environ[
'FASTJETPATH']+
'/bin/fastjet-config'
549 mglog.info(
'fastjet-config --version: '+
str(subprocess.Popen([fastjetconfig,
'--version'],stdout = subprocess.PIPE).stdout.read().strip()))
550 mglog.info(
'fastjet-config --prefix: '+
str(subprocess.Popen([fastjetconfig,
'--prefix'],stdout = subprocess.PIPE).stdout.read().strip()))
553 config_card=process_dir+
'/Cards/me5_configuration.txt'
555 config_card=process_dir+
'/Cards/amcatnlo_configuration.txt'
557 oldcard =
open(config_card,
'r')
558 newcard =
open(config_card+
'.tmp',
'w')
561 if 'fastjet = ' in line:
562 newcard.write(
'fastjet = '+fastjetconfig+
'\n')
563 mglog.info(
'Setting fastjet = '+fastjetconfig+
' in '+config_card)
568 shutil.move(config_card+
'.tmp',config_card)
574 def setupLHAPDF(process_dir=None, extlhapath=None, allow_links=True):
575 global my_MGC_instance
579 origLHAPATH=os.environ[
'LHAPATH']
580 origLHAPDF_DATA_PATH=os.environ[
'LHAPDF_DATA_PATH']
588 run_card=process_dir+
'/Cards/run_card.dat'
591 if mydict[
"pdlabel"].
replace(
"'",
"") ==
'lhapdf':
593 mglog.info(
'creating local LHAPDF dir: MGC_LHAPDF/')
594 if os.path.islink(
'MGC_LHAPDF/'):
595 os.unlink(
'MGC_LHAPDF/')
596 elif os.path.isdir(
'MGC_LHAPDF/'):
597 shutil.rmtree(
'MGC_LHAPDF/')
599 newMGCLHA=
'MGC_LHAPDF/'
601 mkdir = subprocess.Popen([
'mkdir',
'-p',newMGCLHA])
604 pdfs_used=[
int(x)
for x
in mydict[
'lhaid'].
replace(
' ',
',').
split(
',') ]
606 if 'sys_pdf' in mydict:
612 pdfs_used.append(idx)
615 if 'systematics_arguments' in mydict:
616 systematics_arguments=MadGraphControl.MadGraphSystematicsUtils.parse_systematics_arguments(mydict[
'systematics_arguments'])
617 if 'pdf' in systematics_arguments:
623 pdfs_used.append(idx)
626 for pdf
in pdfs_used:
627 if isinstance(pdf,str)
and (pdf.lower()==
'errorset' or pdf.lower()==
'central'):
631 mglog.info(
"Found LHAPDF ID="+
str(pdfid)+
", name="+pdfname)
633 if not os.path.exists(newMGCLHA+pdfname)
and not os.path.lexists(newMGCLHA+pdfname):
634 if not os.path.exists(LHADATAPATH+
'/'+pdfname):
635 mglog.warning(
'PDF not installed at '+LHADATAPATH+
'/'+pdfname)
637 mglog.info(
'linking '+LHADATAPATH+
'/'+pdfname+
' --> '+newMGCLHA+pdfname)
638 os.symlink(LHADATAPATH+
'/'+pdfname,newMGCLHA+pdfname)
640 mglog.info(
'copying '+LHADATAPATH+
'/'+pdfname+
' --> '+newMGCLHA+pdfname)
641 shutil.copytree(LHADATAPATH+
'/'+pdfname,newMGCLHA+pdfname)
644 mglog.info(
'linking '+LHADATAPATH+
'/pdfsets.index --> '+newMGCLHA+
'pdfsets.index')
645 os.symlink(LHADATAPATH+
'/pdfsets.index',newMGCLHA+
'pdfsets.index')
647 atlasLHADATAPATH=LHADATAPATH.replace(
'sft.cern.ch/lcg/external/lhapdfsets/current',
'atlas.cern.ch/repo/sw/Generators/lhapdfsets/current')
648 mglog.info(
'linking '+atlasLHADATAPATH+
'/lhapdf.conf --> '+newMGCLHA+
'lhapdf.conf')
649 os.symlink(atlasLHADATAPATH+
'/lhapdf.conf',newMGCLHA+
'lhapdf.conf')
651 mglog.info(
'copying '+LHADATAPATH+
'/pdfsets.index --> '+newMGCLHA+
'pdfsets.index')
652 shutil.copy2(LHADATAPATH+
'/pdfsets.index',newMGCLHA+
'pdfsets.index')
654 atlasLHADATAPATH=LHADATAPATH.replace(
'sft.cern.ch/lcg/external/lhapdfsets/current',
'atlas.cern.ch/repo/sw/Generators/lhapdfsets/current')
655 mglog.info(
'copying '+atlasLHADATAPATH+
'/lhapdf.conf -->'+newMGCLHA+
'lhapdf.conf')
656 shutil.copy2(atlasLHADATAPATH+
'/lhapdf.conf',newMGCLHA+
'lhapdf.conf')
659 LHADATAPATH=os.getcwd()+
'/MGC_LHAPDF'
662 mglog.info(
'Not using LHAPDF')
663 return (LHAPATH,origLHAPATH,origLHAPDF_DATA_PATH)
667 os.environ[
'LHAPDF_DATA_PATH']=LHADATAPATH
669 mglog.info(
'Path to LHAPDF install dir: '+LHAPATH)
670 mglog.info(
'Path to LHAPDF data dir: '+LHADATAPATH)
671 if not os.path.isdir(LHADATAPATH):
672 raise RuntimeError(
'LHAPDF data dir not accesible: '+LHADATAPATH)
673 if not os.path.isdir(LHAPATH):
674 raise RuntimeError(
'LHAPDF path dir not accesible: '+LHAPATH)
678 lhapdfconfig=extlhapath
679 if not os.access(lhapdfconfig,os.X_OK):
680 raise RuntimeError(
'Failed to find valid external lhapdf-config at '+lhapdfconfig)
681 LHADATAPATH=subprocess.Popen([lhapdfconfig,
'--datadir'],stdout = subprocess.PIPE).stdout.read().strip()
682 mglog.info(
'Changing LHAPDF_DATA_PATH to '+LHADATAPATH)
683 os.environ[
'LHAPDF_DATA_PATH']=LHADATAPATH
685 getlhaconfig = subprocess.Popen([
'get_files',
'-data',
'lhapdf-config'])
688 if not os.access(os.getcwd()+
'/lhapdf-config',os.X_OK):
689 mglog.error(
'Failed to get lhapdf-config from MadGraphControl')
691 lhapdfconfig = os.getcwd()+
'/lhapdf-config'
693 mglog.info(
'lhapdf-config --version: '+
str(subprocess.Popen([lhapdfconfig,
'--version'],stdout = subprocess.PIPE).stdout.read().strip()))
694 mglog.info(
'lhapdf-config --prefix: '+
str(subprocess.Popen([lhapdfconfig,
'--prefix'],stdout = subprocess.PIPE).stdout.read().strip()))
695 mglog.info(
'lhapdf-config --libdir: '+
str(subprocess.Popen([lhapdfconfig,
'--libdir'],stdout = subprocess.PIPE).stdout.read().strip()))
696 mglog.info(
'lhapdf-config --datadir: '+
str(subprocess.Popen([lhapdfconfig,
'--datadir'],stdout = subprocess.PIPE).stdout.read().strip()))
697 mglog.info(
'lhapdf-config --pdfsets-path: '+
str(subprocess.Popen([lhapdfconfig,
'--pdfsets-path'],stdout = subprocess.PIPE).stdout.read().strip()))
699 modify_config_card(process_dir=process_dir,settings={
'lhapdf':lhapdfconfig,
'lhapdf_py3':lhapdfconfig})
701 mglog.info(
'Creating links for LHAPDF')
702 if os.path.islink(process_dir+
'/lib/PDFsets'):
703 os.unlink(process_dir+
'/lib/PDFsets')
704 elif os.path.isdir(process_dir+
'/lib/PDFsets'):
705 shutil.rmtree(process_dir+
'/lib/PDFsets')
707 os.symlink(LHADATAPATH,process_dir+
'/lib/PDFsets')
709 shutil.copytree(LHADATAPATH,process_dir+
'/lib/PDFsets')
710 mglog.info(
'Available PDFs are:')
711 mglog.info(
sorted( [ x
for x
in os.listdir(process_dir+
'/lib/PDFsets')
if ".tar.gz" not in x ] ) )
713 global MADGRAPH_COMMAND_STACK
714 MADGRAPH_COMMAND_STACK += [
'# Copy the LHAPDF files locally' ]
715 MADGRAPH_COMMAND_STACK += [
'cp -r '+os.getcwd()+
'/MGC_LHAPDF .' ]
716 MADGRAPH_COMMAND_STACK += [
'cp -r '+process_dir+
'/lib/PDFsets ${MGaMC_PROCESS_DIR}/lib/' ]
718 return (LHAPATH,origLHAPATH,origLHAPDF_DATA_PATH)
724 my_runMode = 2
if 'ATHENA_CORE_NUMBER' in os.environ
else 0
725 if Ncores
is None and 'ATHENA_CORE_NUMBER' in os.environ
and int(os.environ[
'ATHENA_CORE_NUMBER'])>0:
726 my_Ncores =
int(os.environ[
'ATHENA_CORE_NUMBER'])
728 if my_Ncores
is None:
729 mglog.info(
'Setting up for serial run')
732 modify_config_card(process_dir=process_dir,settings={
'nb_core':my_Ncores,
'run_mode':my_runMode,
'automatic_html_opening':
'False'})
741 madpath=os.environ[
'MADPATH']
742 if not os.access(madpath+
'/bin/mg5_aMC',os.R_OK):
743 raise RuntimeError(
'mg5_aMC executable not found in '+madpath)
744 return madpath+
'/bin/mg5_aMC'
748 """ Add lifetimes to the generated LHE file. Should be
749 called after generate_events is called.
754 if len(glob.glob(process_dir+
'/Events/*'))<1:
755 mglog.error(
'Process dir '+process_dir+
' does not contain events?')
756 run = glob.glob(process_dir+
'/Events/*')[0].
split(
'/')[-1]
761 tof_c =
open(
'time_of_flight_exec_card',
'w')
762 tof_c.write(
'launch '+process_dir+
''' -i
763 add_time_of_flight '''+run+((
' --threshold='+
str(threshold))
if threshold
is not None else ''))
766 mglog.info(
'Started adding time of flight info '+
str(time.asctime()))
768 global MADGRAPH_CATCH_ERRORS
769 generate =
stack_subprocess([python,me_exec,
'time_of_flight_exec_card'],stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
770 (out,err) = generate.communicate()
773 mglog.info(
'Finished adding time of flight information at '+
str(time.asctime()))
776 lhe_gz = glob.glob(process_dir+
'/Events/*/*lhe.gz')[0]
777 if not os.access(lhe_gz,os.R_OK):
778 mglog.info(
'LHE file needs to be zipped')
779 lhe = glob.glob(process_dir+
'/Events/*/*lhe.gz')[0]
784 mglog.info(
'LHE file zipped by MadGraph automatically. Nothing to do')
789 def add_madspin(madspin_card=None,process_dir=MADGRAPH_GRIDPACK_LOCATION):
790 """ Run madspin on the generated LHE file. Should be
791 run when you have inputGeneratorFile set.
792 Only requires a simplified process with the same model that you are
793 interested in (needed to set up a process directory for MG5_aMC)
798 if madspin_card
is not None:
799 shutil.copyfile(madspin_card,process_dir+
'/Cards/madspin_card.dat')
801 if len(glob.glob(process_dir+
'/Events/*'))<1:
802 mglog.error(
'Process dir '+process_dir+
' does not contain events?')
803 proc_dir_list = glob.glob(process_dir+
'/Events/*')
805 for adir
in proc_dir_list:
806 if 'GridRun_' in adir:
807 run=adir.split(
'/')[-1]
810 run=proc_dir_list[0].
split(
'/')[-1]
815 ms_c =
open(
'madspin_exec_card',
'w')
816 ms_c.write(
'launch '+process_dir+
''' -i
817 decay_events '''+run)
820 mglog.info(
'Started running madspin at '+
str(time.asctime()))
822 global MADGRAPH_CATCH_ERRORS
823 generate =
stack_subprocess([python,me_exec,
'madspin_exec_card'],stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
824 (out,err) = generate.communicate()
826 if len(glob.glob(process_dir+
'/Events/'+run+
'_decayed_*/')) == 0:
827 mglog.error(
'No '+process_dir+
'/Events/'+run+
'_decayed_*/ can be found')
828 raise RuntimeError(
'Problem while running MadSpin')
830 mglog.info(
'Finished running madspin at '+
str(time.asctime()))
833 lhe_gz = glob.glob(process_dir+
'/Events/*/*lhe.gz')[0]
834 if not os.access(lhe_gz,os.R_OK):
835 mglog.info(
'LHE file needs to be zipped')
836 lhe = glob.glob(process_dir+
'/Events/*/*lhe.gz')[0]
841 mglog.info(
'LHE file zipped by MadGraph automatically. Nothing to do')
845 """ Run MadSpin on an input LHE file. Takes the process
846 from the LHE file, so you don't need to have a process directory
847 set up in advance. Runs MadSpin and packs the LHE file up appropriately
848 Needs runArgs for the file handling"""
849 if not os.access(input_LHE,os.R_OK):
850 raise RuntimeError(
'Could not find LHE file '+input_LHE)
851 if not os.access(madspin_card,os.R_OK):
852 raise RuntimeError(
'Could not find input MadSpin card '+madspin_card)
854 shutil.copy(input_LHE,input_LHE+
'.original')
855 mglog.info(
'Put backup copy of LHE file at '+input_LHE+
'.original')
857 madspin_exec_card =
open(
'madspin_exec_card',
'w')
858 madspin_exec_card.write(
'import '+input_LHE+
'\n')
860 input_madspin_card =
open(madspin_card,
'r')
862 for l
in input_madspin_card.readlines():
863 commands = l.split(
'#')[0].
split()
865 if len(commands)>1
and 'import'==commands[0]
and not 'model'==commands[1]:
868 if len(commands)>0
and 'launch' == commands[0]:
870 madspin_exec_card.write(l.strip()+
'\n')
872 madspin_exec_card.write(
'launch\n')
873 madspin_exec_card.close()
874 input_madspin_card.close()
876 madpath=os.environ[
'MADPATH']
877 if not os.access(madpath+
'/MadSpin/madspin',os.R_OK):
878 raise RuntimeError(
'madspin executable not found in '+madpath)
879 mglog.info(
'Starting madspin at '+
str(time.asctime()))
880 global MADGRAPH_CATCH_ERRORS
881 generate =
stack_subprocess([python,madpath+
'/MadSpin/madspin',
'madspin_exec_card'],stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
882 (out,err) = generate.communicate()
884 mglog.info(
'Done with madspin at '+
str(time.asctime()))
888 if os.path.exists(os.getcwd()+
'/events.lhe'):
889 os.remove(os.getcwd()+
'/events.lhe')
891 mglog.info(
'Unzipping generated events.')
895 mglog.info(
'Putting a copy in place for the transform.')
896 mod_output =
open(os.getcwd()+
'/events.lhe',
'w')
900 with open(input_LHE,
'r')
as fileobject:
901 for line
in fileobject:
903 mod_output.write(line)
908 mglog.info(
'Removed '+
str(nEmpty)+
' empty lines from LHEF')
912 raise RuntimeError(
'Must provide runArgs to madspin_on_lhe')
914 outputDS = runArgs.outputTXTFile
if hasattr(runArgs,
'outputTXTFile')
else 'tmp_LHE_events.tar.gz'
916 mglog.info(
'Moving file over to '+outputDS.split(
'.tar.gz')[0]+
'.events')
917 shutil.move(os.getcwd()+
'/events.lhe',outputDS.split(
'.tar.gz')[0]+
'.events')
919 mglog.info(
'Re-zipping into dataset name '+outputDS)
920 rezip =
stack_subprocess([
'tar',
'cvzf',outputDS,outputDS.split(
'.tar.gz')[0]+
'.events'])
924 if hasattr(runArgs,
'outputTXTFile')
and runArgs.outputTXTFile
is not None:
925 outputDS = outputDS.split(
'.TXT')[0]
927 if runArgs
is not None:
928 mglog.debug(
'Setting inputGenerator file to '+outputDS)
929 runArgs.inputGeneratorFile=outputDS
932 def arrange_output(process_dir=MADGRAPH_GRIDPACK_LOCATION,lhe_version=None,saveProcDir=False,runArgs=None,fixEventWeightsForBridgeMode=False):
937 if len(glob.glob(os.path.join(process_dir,
'Events',
'*')))<1:
938 mglog.error(
'Process dir '+process_dir+
' does not contain events?')
939 proc_dir_list = glob.glob(os.path.join(process_dir,
'Events',
'*'))
942 for adir
in proc_dir_list:
943 if 'decayed' in adir:
946 if 'GridRun_' in adir:
949 elif os.path.join(process_dir,
'Events',MADGRAPH_RUN_NAME)
in adir:
951 if not os.access(this_run_name,os.R_OK):
952 raise RuntimeError(
'Unable to locate run directory')
954 hasUnweighted = os.access(this_run_name+
'/unweighted_events.lhe.gz',os.R_OK)
957 madspinDirs=
sorted(glob.glob(this_run_name+
'_decayed_*/'))
960 if hasRunMadSpin
and not hasUnweighted:
962 hasUnweighted = os.access(madspinDirs[-1]+
'/unweighted_events.lhe.gz',os.R_OK)
964 global MADGRAPH_COMMAND_STACK
973 if os.path.exists(madspinDirs[-1]+
'/unweighted_events.lhe.gz'):
974 MADGRAPH_COMMAND_STACK += [
'mv '+madspinDirs[-1]+
'/unweighted_events.lhe.gz'+
' '+this_run_name+
'/unweighted_events.lhe.gz']
975 shutil.move(madspinDirs[-1]+
'/unweighted_events.lhe.gz',this_run_name+
'/unweighted_events.lhe.gz')
976 mglog.info(
'Moving MadSpin events from '+madspinDirs[-1]+
'/unweighted_events.lhe.gz to '+this_run_name+
'/unweighted_events.lhe.gz')
977 elif os.path.exists(madspinDirs[-1]+
'/events.lhe.gz'):
978 MADGRAPH_COMMAND_STACK += [
'mv '+madspinDirs[-1]+
'/events.lhe.gz'+
' '+this_run_name+
'/unweighted_events.lhe.gz']
979 shutil.move(madspinDirs[-1]+
'/events.lhe.gz',this_run_name+
'/unweighted_events.lhe.gz')
980 mglog.info(
'Moving MadSpin events from '+madspinDirs[-1]+
'/events.lhe.gz to '+this_run_name+
'/unweighted_events.lhe.gz')
982 raise RuntimeError(
'MadSpin was run but can\'t find files :(')
985 MADGRAPH_COMMAND_STACK += [
'mv '+madspinDirs[-1]+
'/events.lhe.gz '+this_run_name+
'/events.lhe.gz']
986 shutil.move(madspinDirs[-1]+
'/events.lhe.gz',this_run_name+
'/events.lhe.gz')
987 mglog.info(
'Moving MadSpin events from '+madspinDirs[-1]+
'/events.lhe.gz to '+this_run_name+
'/events.lhe.gz')
990 mglog.error(
'MadSpin was run but can\'t find output folder '+(this_run_name+
'_decayed_1/'))
991 raise RuntimeError(
'MadSpin was run but can\'t find output folder '+(this_run_name+
'_decayed_1/'))
993 if fixEventWeightsForBridgeMode:
994 mglog.info(
"Fixing event weights after MadSpin... initial checks.")
1002 eventsfilename=
"unweighted_events"
1004 eventsfilename=
"events"
1005 unzip =
stack_subprocess([
'gunzip',
'-f',this_run_name+
'/%s.lhe.gz' % eventsfilename])
1008 for line
in open(process_dir+
'/Events/'+MADGRAPH_RUN_NAME+
'/%s.lhe'%eventsfilename):
1009 if "Number of Events" in line:
1011 MGnumevents=
int(sline[-1])
1012 elif "Integrated weight (pb)" in line:
1014 MGintweight=
float(sline[-1])
1015 elif "set spinmode none" in line:
1017 elif "</header>" in line:
1020 if spinmodenone
and MGnumevents>0
and MGintweight>0:
1021 mglog.info(
"Fixing event weights after MadSpin... modifying LHE file.")
1022 newlhe=
open(this_run_name+
'/%s_fixXS.lhe'%eventsfilename,
'w')
1030 event_norm_setting=
"average"
1032 for line
in open(this_run_name+
'/%s.lhe'%eventsfilename):
1035 if "<init>" in line:
1038 elif "</init>" in line:
1040 elif inInit
and initlinecount==0:
1044 if abs(
int(sline[-2])) == 3:
1045 event_norm_setting=
"sum"
1046 elif abs(
int(sline[-2])) == 4:
1047 event_norm_setting=
"average"
1048 elif inInit
and initlinecount==1:
1052 sline[0]=
str(MGintweight)
1053 sline[1]=
str(
float(sline[0])*relunc)
1054 if event_norm_setting==
"sum":
1055 sline[2]=
str(MGintweight/MGnumevents)
1056 elif event_norm_setting==
"average":
1057 sline[2]=
str(MGintweight)
1058 newline=
' '.
join(sline)
1061 elif inInit
and initlinecount>1:
1063 elif "<event>" in line:
1066 elif "</event>" in line:
1068 elif inEvent
and eventlinecount==0:
1071 if event_norm_setting==
"sum":
1072 sline[2]=
str(MGintweight/MGnumevents)
1073 elif event_norm_setting==
"average":
1074 sline[2]=
str(MGintweight)
1075 newline=
' '.
join(sline)
1078 newlhe.write(newline)
1081 mglog.info(
"Fixing event weights after MadSpin... cleaning up.")
1082 shutil.copyfile(this_run_name+
'/%s.lhe' % eventsfilename,
1083 this_run_name+
'/%s_badXS.lhe' % eventsfilename)
1085 shutil.move(this_run_name+
'/%s_fixXS.lhe' % eventsfilename,
1086 this_run_name+
'/%s.lhe' % eventsfilename)
1088 rezip =
stack_subprocess([
'gzip',this_run_name+
'/%s.lhe' % eventsfilename])
1091 rezip =
stack_subprocess([
'gzip',this_run_name+
'/%s_badXS.lhe' % eventsfilename])
1095 if os.path.exists(os.getcwd()+
'/events.lhe'):
1096 os.remove(os.getcwd()+
'/events.lhe')
1098 mglog.info(
'Unzipping generated events.')
1100 unzip =
stack_subprocess([
'gunzip',
'-f',this_run_name+
'/unweighted_events.lhe.gz'])
1106 mglog.info(
'Putting a copy in place for the transform.')
1108 orig_input = this_run_name+
'/unweighted_events.lhe'
1109 mod_output =
open(os.getcwd()+
'/events.lhe',
'w')
1111 orig_input = this_run_name+
'/events.lhe'
1112 mod_output =
open(os.getcwd()+
'/events.lhe',
'w')
1119 with open(orig_input,
'r')
as fileobject:
1120 for line
in fileobject:
1124 if '#' not in newline:
1126 elif '>' not in newline[ newline.find(
'#'): ]:
1129 mglog.info(
'Found bad LHE line with an XML mark in a comment: "'+newline.strip()+
'"')
1130 newline=newline[:newline.find(
'#')]+
'#'+ (newline[newline.find(
'#'):].
replace(
'>',
'-'))
1132 if initrwgt
is False:
1134 elif "</initrwgt>" in newline:
1136 elif "<initrwgt>" in newline:
1138 elif initrwgt
is not None:
1139 newline=newline.replace(
'_DYNSCALE-1',
'')
1140 if '</weight>' in newline:
1141 iend=newline.find(
'</weight>')
1142 istart=newline[:iend].rfind(
'>')
1143 lhe_weights+=[newline[istart+1:iend].strip()]
1144 mod_output.write(newline)
1148 mglog.info(
'Removed '+
str(nEmpty)+
' empty lines from LHEF')
1150 mglog.info(
"The following "+
str(len(lhe_weights))+
" weights have been written to the LHE file: "+
",".
join(lhe_weights))
1153 mglog.info(
"Checking whether the following expected weights are in LHE file: "+
",".
join(expected_weights))
1154 for w
in expected_weights:
1155 if w
not in lhe_weights:
1156 raise RuntimeError(
"Did not find expected weight "+w+
" in lhe file. Did the reweight or systematics module crash?")
1157 mglog.info(
"Found all required weights!")
1160 mod_output2 =
open(os.getcwd()+
'/events.lhe',
'r')
1161 test=mod_output2.readline()
1162 if 'version="' in test:
1163 mglog.info(
'Applying LHE version hack')
1164 final_file =
open(os.getcwd()+
'/events.lhe.copy',
'w')
1165 final_file.write(
'<LesHouchesEvents version="%i.0">\n'%lhe_version)
1166 shutil.copyfileobj(mod_output2, final_file)
1168 shutil.copy(os.getcwd()+
'/events.lhe.copy',os.getcwd()+
'/events.lhe')
1170 os.remove(os.getcwd()+
'/events.lhe.copy')
1175 raise RuntimeError(
'Must provide runArgs to arrange_output')
1177 if hasattr(runArgs,
'outputTXTFile'):
1178 outputDS = runArgs.outputTXTFile
1180 outputDS =
'tmp_LHE_events.tar.gz'
1182 mglog.info(
'Moving file over to '+outputDS.split(
'.tar.gz')[0]+
'.events')
1184 shutil.move(os.getcwd()+
'/events.lhe',outputDS.split(
'.tar.gz')[0]+
'.events')
1186 mglog.info(
'Re-zipping into dataset name '+outputDS)
1187 rezip =
stack_subprocess([
'tar',
'cvzf',outputDS,outputDS.split(
'.tar.gz')[0]+
'.events'])
1191 mglog.info(
'Removing the process directory')
1192 shutil.rmtree(process_dir,ignore_errors=
True)
1194 if os.path.isdir(
'MGC_LHAPDF/'):
1195 shutil.rmtree(
'MGC_LHAPDF/',ignore_errors=
True)
1198 if hasattr(runArgs,
'outputTXTFile')
and runArgs.outputTXTFile
is not None:
1199 outputDS = outputDS.split(
'.TXT')[0]
1201 if runArgs
is not None:
1202 mglog.debug(
'Setting inputGenerator file to '+outputDS)
1203 runArgs.inputGeneratorFile=outputDS
1205 mglog.info(
'All done with output arranging!')
1209 if reweight_card_loc
is None:
1212 f_rw=
open(reweight_card_loc)
1214 if 'launch' not in line:
1216 match=re.match(
r'launch.*--rwgt_info\s*=\s*(\S+).*',line.strip())
1217 if len(match.groups())!=1:
1218 raise RuntimeError(
'Unexpected format of reweight card in line'+line)
1220 names+=[match.group(1)]
1226 if syst_setting
is None or 'central_pdf' not in syst_setting:
1227 mglog.warning(
"Systematics have not been defined via base fragment or 'MADGRAPH_PDFSETTING', cannot check for expected weights")
1229 if 'pdf_variations' in syst_setting
and isinstance(syst_setting[
'pdf_variations'],list):
1230 names+=[MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO%{
'mur':1.0,
'muf':1.0,
'pdf':syst_setting[
'central_pdf']}]
1231 for pdf
in syst_setting[
'pdf_variations']:
1232 names+=[MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO%{
'mur':1.0,
'muf':1.0,
'pdf':pdf+1}]
1233 if 'alternative_pdfs' in syst_setting
and isinstance(syst_setting[
'alternative_pdfs'],list):
1234 for pdf
in syst_setting[
'alternative_pdfs']:
1235 names+=[MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO%{
'mur':1.0,
'muf':1.0,
'pdf':pdf}]
1236 if 'scale_variations' in syst_setting
and isinstance(syst_setting[
'scale_variations'],list):
1237 for mur
in syst_setting[
'scale_variations']:
1238 for muf
in syst_setting[
'scale_variations']:
1239 names+=[MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO%{
'mur':mur,
'muf':muf,
'pdf':syst_setting[
'central_pdf']}]
1243 run_card = process_dir+
'/Cards/run_card.dat'
1244 if isinstance(bias_module,tuple):
1245 mglog.info(
'Using bias module '+bias_module[0])
1246 the_run_card =
open(run_card,
'r')
1247 for line
in the_run_card:
1248 if 'bias_module' in line
and not bias_module[0]
in line:
1249 raise RuntimeError(
'You need to add the bias module '+bias_module[0]+
' to the run card to actually run it')
1250 the_run_card.close()
1251 if len(bias_module)!=3:
1252 raise RuntimeError(
'Please give a 3-tuple of strings containing bias module name, bias module, and makefile. Alternatively, give path to bias module tarball.')
1253 bias_module_newpath=process_dir+
'/Source/BIAS/'+bias_module[0]
1254 os.makedirs(bias_module_newpath)
1255 bias_module_file=
open(bias_module_newpath+
'/'+bias_module[0]+
'.f',
'w')
1256 bias_module_file.write(bias_module[1])
1257 bias_module_file.close()
1258 bias_module_make_file=
open(bias_module_newpath+
'/Makefile',
'w')
1259 bias_module_make_file.write(bias_module[2])
1260 bias_module_make_file.close()
1262 mglog.info(
'Using bias module '+bias_module)
1263 bias_module_name=bias_module.split(
'/')[-1].
replace(
'.gz',
'')
1264 bias_module_name=bias_module_name.replace(
'.tar',
'')
1265 the_run_card =
open(run_card,
'r')
1266 for line
in the_run_card:
1267 if 'bias_module' in line
and bias_module_name
not in line:
1268 raise RuntimeError(
'You need to add the bias module '+bias_module_name+
' to the run card to actually run it')
1269 the_run_card.close()
1271 if os.path.exists(bias_module+
'.tar.gz'):
1272 bias_module_path=bias_module+
'.tar.gz'
1273 elif os.path.exists(bias_module+
'.gz'):
1274 bias_module_path=bias_module+
'.gz'
1275 elif os.path.exists(bias_module):
1276 bias_module_path=bias_module
1278 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')
1280 bias_module_newpath=process_dir+
'/Source/BIAS/'+bias_module_path.split(
'/')[-1]
1281 mglog.info(
'Copying bias module into place: '+bias_module_newpath)
1282 shutil.copy(bias_module_path,bias_module_newpath)
1283 mglog.info(
'Unpacking bias module')
1284 if bias_module_newpath.endswith(
'.tar.gz'):
1285 untar =
stack_subprocess([
'tar',
'xvzf',bias_module_newpath,
'--directory='+process_dir+
'/Source/BIAS/'])
1287 elif bias_module_path.endswith(
'.gz'):
1293 if os.access(process_dir+
'/Cards/reweight_card.dat',os.R_OK):
1294 return process_dir+
'/Cards/reweight_card.dat'
1300 shutil.move(reweight_card,reweight_card+
'.old')
1301 oldcard =
open(reweight_card+
'.old',
'r')
1302 newcard =
open(reweight_card,
'w')
1304 info_expression=
r'launch.*--rwgt_info\s*=\s*(\S+).*'
1305 name_expression=info_expression.replace(
'info',
'name')
1306 goodname_expression=
r'^[A-Za-z0-9_\-.]+$'
1307 for line
in oldcard:
1309 if not line.strip().startswith(
'launch') :
1312 rwgt_name_match=re.match(name_expression,line.strip())
1313 rwgt_info_match=re.match(info_expression,line.strip())
1314 if rwgt_name_match
is None and rwgt_info_match
is None:
1315 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)
1316 for match
in [rwgt_info_match,rwgt_name_match]:
1319 if len(match.groups())!=1:
1320 raise RuntimeError(
'Unexpected format of reweight card in line: '+line)
1321 if not re.match(goodname_expression,match.group(1)):
1322 raise RuntimeError(
'No special character in reweighting info/name, only allowing '+goodname_expression)
1323 if rwgt_info_match
is not None:
1325 elif rwgt_name_match
is not None:
1326 newcard.write(line.strip()+
' --rwgt_info={0}\n'.
format(rwgt_name_match.group(1)))
1329 mglog.info(
'Updated reweight_card')
1334 def update_lhe_file(lhe_file_old,param_card_old=None,lhe_file_new=None,masses={},delete_old_lhe=True):
1335 """Build a new LHE file from an old one and an updated param card.
1336 The masses of some particles can be changed via the masses dictionary. No particles that appear in the events
1337 may have their masses changed.
1338 If the param card is provided, the decay block in the LHE file will be replaced with the one in the param card.
1339 By default, the old LHE file is removed.
1340 If None is provided as a new LHE file name, the new file will replace the old one."""
1342 lhe_file_new_tmp = lhe_file_new
if lhe_file_new
is not None else lhe_file_old+
'.tmp'
1344 if not os.access(lhe_file_old,os.R_OK):
1345 raise RuntimeError(
'Could not access old LHE file at '+
str(lhe_file_old)+
'. Please check the file location.')
1347 if param_card_old
is not None:
1348 paramcard = subprocess.Popen([
'get_files',
'-data',param_card_old])
1350 if not os.access(param_card_old,os.R_OK):
1351 raise RuntimeError(
'Could not get param card '+param_card_old)
1353 if os.access(lhe_file_new_tmp,os.R_OK):
1354 raise RuntimeError(
'Old file at'+
str(lhe_file_new_tmp)+
' in the current directory. Dont want to clobber it. Please move it first.')
1356 newlhe =
open(lhe_file_new_tmp,
'w')
1360 particles_in_events = []
1363 with open(lhe_file_old,
'r')
as fileobject:
1364 for line
in fileobject:
1365 if decayEdit
and '</slha>' not in line:
1367 if decayEdit
and '</slha>' in line:
1369 if line.strip().
upper().startswith(
'BLOCK')
or line.strip().
upper().startswith(
'DECAY')\
1370 and len(line.strip().
split()) > 1:
1371 pos = 0
if line.strip().startswith(
'DECAY')
else 1
1372 blockName = line.strip().
upper().
split()[pos]
1375 if blockName !=
'DECAY' and len(line.strip().
split()) > 0:
1376 akey = line.strip().
split()[0]
1377 elif blockName ==
'DECAY' and len(line.strip().
split()) > 1:
1378 akey = line.strip().
split()[1]
1381 if akey
is not None and blockName ==
'MASS' and akey
in masses:
1382 newlhe.write(
' '+akey+
' '+
str(masses[akey])+
' # \n')
1383 mglog.info(
' '+akey+
' '+
str(masses[akey])+
' #')
1388 if blockName ==
'DECAY' and param_card_old
is not None:
1390 oldparam =
open(param_card_old,
'r')
1392 for old_line
in oldparam.readlines():
1394 if old_line.strip().
upper().startswith(
'DECAY')
and len(old_line.strip().
split()) > 1:
1395 newBlockName = line.strip().
upper().
split()[pos]
1397 newlhe.write(old_line)
1398 elif newBlockName ==
'DECAY':
1400 newlhe.write(old_line)
1408 if not eventRead
and '<event>' in line:
1411 if len(line.split())==11:
1412 aparticle = line.split()[0]
1413 if aparticle
not in particles_in_events:
1414 particles_in_events += [aparticle]
1421 if akey
in particles_in_events:
1422 mglog.error(
'Attempted to change mass of a particle that was in an LHE event! This is not allowed!')
1429 if lhe_file_new
is None:
1430 os.remove(lhe_file_old)
1431 shutil.move(lhe_file_new_tmp,lhe_file_old)
1432 lhe_file_new_tmp = lhe_file_old
1434 elif delete_old_lhe:
1435 os.remove(lhe_file_old)
1437 return lhe_file_new_tmp
1442 """ Helper function when looking at param cards
1443 In some cases it's tricky to match keys - they may differ
1444 only in white space. This tries to sort out when we have
1445 a match, and then uses the one in blockParams afterwards.
1446 In the case of no match, it returns the original key.
1449 for key
in dictionary:
1451 if mod_key==test_key:
1456 def modify_param_card(param_card_input=None,param_card_backup=None,process_dir=MADGRAPH_GRIDPACK_LOCATION,params={},output_location=None):
1457 """Build a new param_card.dat from an existing one.
1458 Params should be a dictionary of dictionaries. The first key is the block name, and the second in the param name.
1459 Keys can include MASS (for masses) and DECAY X (for decays of particle X)"""
1463 if param_card_input
is None:
1464 param_card_input=process_dir+
'/Cards/param_card.dat'
1465 elif param_card_input
is not None and not os.access(param_card_input,os.R_OK):
1466 paramcard = subprocess.Popen([
'get_files',
'-data',param_card_input])
1468 if not os.access(param_card_input,os.R_OK):
1469 raise RuntimeError(
'Could not get param card '+param_card_input)
1470 mglog.info(
'Using input param card at '+param_card_input)
1474 for blockName
in list(params.keys()):
1475 paramsUpper[blockName.upper()] = {}
1476 for paramName
in list(params[blockName].
keys()):
1477 paramsUpper[blockName.upper()][paramName.upper()] = params[blockName][paramName]
1479 if param_card_backup
is not None:
1480 mglog.info(
'Keeping backup of original param card at '+param_card_backup)
1481 param_card_old = param_card_backup
1483 param_card_old = param_card_input+
'.old_to_be_deleted'
1484 if os.path.isfile(param_card_old):
1485 os.unlink(param_card_old)
1486 os.rename(param_card_input, param_card_old)
1488 oldcard =
open(param_card_old,
'r')
1489 param_card_location= process_dir+
'/Cards/param_card.dat' if output_location
is None else output_location
1490 newcard =
open(param_card_location,
'w')
1494 for linewithcomment
in oldcard:
1495 line=linewithcomment.split(
'#')[0]
1496 if line.strip().
upper().startswith(
'BLOCK')
or line.strip().
upper().startswith(
'DECAY')\
1497 and len(line.strip().
split()) > 1:
1498 if decayEdit
and blockName ==
'DECAY':
1500 pos = 0
if line.strip().startswith(
'DECAY')
else 1
1501 if blockName==
'MASS' and 'MASS' in paramsUpper:
1503 if "MASS" in doneParams:
1504 leftOvers = [ x
for x
in paramsUpper[
'MASS']
if x
not in doneParams[
'MASS'] ]
1506 leftOvers = [ x
for x
in paramsUpper[
'MASS'] ]
1508 for pdg_id
in leftOvers:
1509 mglog.warning(
'Adding mass line for '+
str(pdg_id)+
' = '+
str(paramsUpper[
'MASS'][pdg_id])+
' which was not in original param card')
1510 newcard.write(
' '+
str(pdg_id)+
' '+
str(paramsUpper[
'MASS'][pdg_id])+
'\n')
1511 doneParams[
'MASS'][pdg_id]=
True
1512 if blockName==
'DECAY' and 'DECAY' not in line.strip().
upper()
and 'DECAY' in paramsUpper:
1514 leftOvers = [ x
for x
in paramsUpper[
'DECAY']
if x
not in doneParams[
'DECAY'] ]
1515 for pdg_id
in leftOvers:
1516 mglog.warning(
'Adding decay for pdg id '+
str(pdg_id)+
' which was not in the original param card')
1517 newcard.write( paramsUpper[
'DECAY'][pdg_id].strip()+
'\n' )
1518 doneParams[
'DECAY'][pdg_id]=
True
1519 blockName = line.strip().
upper().
split()[pos]
1524 if blockName !=
'DECAY' and len(line.strip().
split()) > 0:
1527 if len(line.split())==2:
1528 akey = line.upper().strip().
split()[0]
1531 akey = line.upper().strip()[:line.strip().rfind(
' ')].strip()
1532 elif blockName ==
'DECAY' and len(line.strip().
split()) > 1:
1533 akey = line.strip().
split()[1]
1535 newcard.write(linewithcomment)
1539 if blockName
not in paramsUpper:
1540 newcard.write(linewithcomment)
1542 blockParams = paramsUpper[blockName]
1548 if '#' in linewithcomment:
1549 stringkey = linewithcomment[linewithcomment.find(
'#')+1:].strip()
1550 if len(stringkey.split()) > 0:
1551 stringkey = stringkey.split()[0].
upper()
1553 if akey
not in blockParams
and not (stringkey
is not None and stringkey
in blockParams):
1554 newcard.write(linewithcomment)
1557 if akey
in blockParams
and (stringkey
is not None and stringkey
in blockParams):
1558 raise RuntimeError(
'Conflicting use of numeric and string keys '+akey+
' and '+stringkey)
1560 theParam = blockParams.get(akey,blockParams[stringkey]
if stringkey
in blockParams
else None)
1561 if blockName
not in doneParams:
1562 doneParams[blockName] = {}
1563 if akey
in blockParams:
1564 doneParams[blockName][akey]=
True
1565 elif stringkey
is not None and stringkey
in blockParams:
1566 doneParams[blockName][stringkey]=
True
1569 if blockName==
"DECAY":
1570 if theParam.splitlines()[0].
split()[0].
upper()==
"DECAY":
1572 for newline
in theParam.splitlines():
1573 newcard.write(newline+
'\n')
1577 newcard.write(
'DECAY '+akey+
' '+
str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1578 mglog.info(
'DECAY '+akey+
' '+
str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1580 elif blockName==
'QNUMBERS':
1582 for newline
in theParam.splitlines():
1583 newcard.write(newline+
'\n')
1587 newcard.write(
' '+akey+
' '+
str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1588 mglog.info(
' '+akey+
' '+
str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1592 for blockName
in paramsUpper:
1593 if blockName
not in doneParams
and len(paramsUpper[blockName].
keys())>0:
1594 raise RuntimeError(
'Did not find any of the parameters for block '+blockName+
' in param_card')
1595 for paramName
in paramsUpper[blockName]:
1596 if paramName
not in doneParams[blockName]:
1597 raise RuntimeError(
'Was not able to replace parameter '+paramName+
' in param_card')
1606 card_dir=process_dir+
'/Cards/'
1607 print_cards(proc_card=card_dir+
'proc_card_mg5.dat',run_card=card_dir+
'run_card.dat',param_card=card_dir+
'param_card.dat',\
1608 madspin_card=card_dir+
'madspin_card.dat',reweight_card=card_dir+
'reweight_card.dat',warn_on_missing=
False)
1611 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):
1612 if os.access(proc_card,os.R_OK):
1613 mglog.info(
"proc_card:")
1614 procCard = subprocess.Popen([
'cat',proc_card])
1616 elif warn_on_missing:
1617 mglog.warning(
'No proc_card: '+proc_card+
' found')
1619 if run_card
is not None and os.access(run_card,os.R_OK):
1620 mglog.info(
"run_card:")
1621 runCard = subprocess.Popen([
'cat',run_card])
1623 elif run_card
is not None and warn_on_missing:
1624 mglog.warning(
'No run_card: '+run_card+
' found')
1626 mglog.info(
'Default run card in use')
1628 if param_card
is not None and os.access(param_card,os.R_OK):
1629 mglog.info(
"param_card:")
1630 paramCard = subprocess.Popen([
'cat',param_card])
1632 elif param_card
is not None and warn_on_missing:
1633 mglog.warning(
'No param_card: '+param_card+
' found')
1635 mglog.info(
'Default param card in use')
1637 if madspin_card
is not None and os.access(madspin_card,os.R_OK):
1638 mglog.info(
"madspin_card:")
1639 madspinCard = subprocess.Popen([
'cat',madspin_card])
1641 elif madspin_card
is not None and warn_on_missing:
1642 mglog.warning(
'No madspin_card: '+madspin_card+
' found')
1644 mglog.info(
'No madspin card in use')
1646 if reweight_card
is not None and os.access(reweight_card,os.R_OK):
1647 mglog.info(
"reweight_card:")
1648 madspinCard = subprocess.Popen([
'cat',reweight_card])
1650 elif reweight_card
is not None and warn_on_missing:
1651 mglog.warning(
'No reweight_card: '+reweight_card+
' found')
1653 mglog.info(
'No reweight card in use')
1657 """ Simple function for checking if there is a grid pack.
1658 Relies on the specific location of the unpacked gridpack (madevent)
1659 which is here set as a global variable. The gridpack is untarred by
1660 the transform (Gen_tf.py) and no sign is sent to the job itself
1661 that there is a gridpack in use except the file's existence"""
1662 if os.access(MADGRAPH_GRIDPACK_LOCATION,os.R_OK):
1663 mglog.info(
'Located input grid pack area')
1669 def modify_run_card(run_card_input=None,run_card_backup=None,process_dir=MADGRAPH_GRIDPACK_LOCATION,runArgs=None,settings={},skipBaseFragment=False):
1670 """Build a new run_card.dat from an existing one.
1671 This function can get a fresh runcard from DATAPATH or start from the process directory.
1672 Settings is a dictionary of keys (no spaces needed) and values to replace.
1677 for s
in list(settings.keys()):
1678 settings_lower[s.lower()] = settings[s]
1681 if run_card_input
is None:
1683 elif run_card_input
is not None and not os.access(run_card_input,os.R_OK):
1684 runcard = subprocess.Popen([
'get_files',
'-data',run_card_input])
1686 if not os.access(run_card_input,os.R_OK):
1687 raise RuntimeError(
'Could not get run card '+run_card_input)
1692 if not skipBaseFragment:
1693 MadGraphControl.MadGraphSystematicsUtils.setup_pdf_and_systematic_weights(MADGRAPH_PDFSETTING,settings_lower,isNLO)
1696 if runArgs
is not None:
1698 if 'iseed' not in settings_lower:
1699 settings_lower[
'iseed']=rand_seed
1700 if not isNLO
and 'python_seed' not in settings_lower:
1701 settings_lower[
'python_seed']=rand_seed
1702 if 'beamenergy' in settings_lower:
1703 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']))
1704 beamEnergy=settings_lower[
'beamenergy']
1705 settings_lower.pop(
'beamenergy')
1706 if 'ebeam1' not in settings_lower:
1707 settings_lower[
'ebeam1']=beamEnergy
1708 if 'ebeam2' not in settings_lower:
1709 settings_lower[
'ebeam2']=beamEnergy
1711 if 'nevents' in settings_lower:
1712 settings_lower[
'nevents'] =
int(settings_lower[
'nevents'])
1715 if 'custom_fcts' in settings_lower
and settings_lower[
'custom_fcts']:
1716 raw_name =
str(settings_lower[
'custom_fcts']).
split()[0]
1718 if runArgs
is not None and hasattr(runArgs,
'jobConfig'):
1719 cfgdir = runArgs.jobConfig[0]
if isinstance(runArgs.jobConfig, (list, tuple))
else runArgs.jobConfig
1721 full_path = os.path.join(cfgdir, raw_name)
1722 settings_lower[
'custom_fcts'] = os.path.abspath(full_path)
1723 print(f
"Using custom function(s), specified in custom_fcts with path: {settings_lower['custom_fcts']}")
1726 settings_lower[
'custom_fcts'] = os.path.abspath(raw_name)
1728 mglog.info(
'Modifying run card located at '+run_card_input)
1729 if run_card_backup
is not None:
1730 mglog.info(
'Keeping backup of original run card at '+run_card_backup)
1731 run_card_old = run_card_backup
1733 run_card_old = run_card_input+
'.old_to_be_deleted'
1734 mglog.debug(
'Modifying runcard settings: '+
str(settings_lower))
1735 if os.path.isfile(run_card_old):
1736 os.unlink(run_card_old)
1737 os.rename(run_card_input, run_card_old)
1739 oldCard =
open(run_card_old,
'r')
1740 newCard =
open(process_dir+
'/Cards/run_card.dat',
'w')
1742 for line
in iter(oldCard):
1743 if not line.strip().startswith(
'#'):
1744 command = line.split(
'!', 1)[0]
1745 comment = line.split(
'!', 1)[1]
if '!' in line
else ''
1747 setting = command.split(
'=')[-1]
1748 stripped_setting = setting.strip()
1749 oldValue =
'='.
join(command.split(
'=')[:-1])
1750 if stripped_setting.lower()
in settings_lower:
1752 if settings_lower[stripped_setting.lower()]
is None:
1754 mglog.info(
'Removing '+stripped_setting+
'.')
1755 used_settings += [ stripped_setting.lower() ]
1757 if stripped_setting.lower() ==
'custom_fcts':
1759 line =
' '+
str(settings_lower[stripped_setting.lower()])+
' = '+setting
1761 line +=
' !'+comment
1763 line = oldValue.replace(oldValue.strip(),
str(settings_lower[stripped_setting.lower()]))+
'='+setting
1765 line +=
' !' + comment
1766 mglog.info(
'Setting '+stripped_setting+
' = '+
str(settings_lower[stripped_setting.lower()]))
1767 used_settings += [ stripped_setting.lower() ]
1768 newCard.write(line.strip()+
'\n')
1771 if 'mcatnlo_delta' in settings_lower:
1772 if settings_lower[
'mcatnlo_delta'] ==
'True':
1773 modify_config_card(process_dir=process_dir,settings={
'pythia8_path':os.getenv(
"PY8PATH")})
1776 for asetting
in settings_lower:
1777 if asetting
in used_settings:
1779 if settings_lower[asetting]
is None:
1781 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]) )
1782 newCard.write(
' '+
str(settings_lower[asetting])+
' = '+
str(asetting)+
'\n')
1786 mglog.info(
'Finished modification of run card.')
1787 if run_card_backup
is None:
1788 os.unlink(run_card_old)
1791 def modify_config_card(config_card_backup=None,process_dir=MADGRAPH_GRIDPACK_LOCATION,settings={},set_commented=True):
1792 """Build a new configuration from an existing one.
1793 This function can get a fresh runcard from DATAPATH or start from the process directory.
1794 Settings is a dictionary of keys (no spaces needed) and values to replace.
1800 mglog.info(
'Modifying config card located at '+config_card)
1801 if config_card_backup
is not None:
1802 mglog.info(
'Keeping backup of original config card at '+config_card_backup)
1803 config_card_old = config_card_backup
1805 config_card_old = config_card+
'.old_to_be_deleted'
1806 mglog.debug(
'Modifying config card settings: '+
str(settings))
1807 if os.path.isfile(config_card_old):
1808 os.unlink(config_card_old)
1809 os.rename(config_card, config_card_old)
1811 oldCard =
open(config_card_old,
'r')
1812 newCard =
open(config_card,
'w')
1814 for line
in iter(oldCard):
1815 lmod = line
if set_commented
else line.split(
'#')[0]
1818 for setting
in settings:
1819 if setting
not in lmod:
1822 mglog.info(
'Setting '+setting.strip()+
' to '+
str(settings[setting]))
1823 newCard.write(
' '+
str(setting.strip())+
' = '+
str(settings[setting])+
'\n')
1824 used_settings += [ setting.strip() ]
1832 for asetting
in settings:
1833 if asetting
in used_settings:
1835 if settings[asetting]
is None:
1837 mglog.warning(
'Option '+asetting+
' was not in the default config card. Adding by hand a setting to '+
str(settings[asetting]) )
1838 newCard.write(
' '+
str(asetting)+
' = '+
str(settings[asetting])+
'\n')
1842 mglog.info(
'Finished modification of config card.')
1843 if config_card_backup
is None:
1844 os.unlink(config_card_old)
1850 for l
in card_in.readlines():
1851 if 'cluster_type' not in l.split(
'#')[0]:
1853 cluster_type = l.split(
'#')[0].
split(
'=')[1]
1854 mglog.info(
'Returning cluster type: '+cluster_type)
1861 cardpath=process_dir+
'/Cards/run_card.dat'
1863 global my_MGC_instance
1867 modify_run_card(process_dir=process_dir,settings={
'event_norm':
'average'},skipBaseFragment=
True)
1868 mglog.warning(
"setting event_norm to average, there is basically no use case where event_norm=sum is a good idea")
1872 if 'ktdurham' in mydict
and float(mydict[
'ktdurham']) > 0
and int(mydict[
'ickkw']) != 0:
1873 log=
'Bad combination of settings for CKKW-L merging! ktdurham=%s and ickkw=%s.'%(mydict[
'ktdurham'],mydict[
'ickkw'])
1875 raise RuntimeError(log)
1878 if 'systematics_program' not in mydict
or mydict[
'systematics_program']==
'systematics':
1879 syscalc_settings=[
'sys_pdf',
'sys_scalefact',
'sys_alpsfact',
'sys_matchscale']
1880 found_syscalc_setting=
False
1881 for s
in syscalc_settings:
1883 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)')
1884 found_syscalc_setting=
True
1885 if found_syscalc_setting:
1886 syst_arguments=MadGraphControl.MadGraphSystematicsUtils.convertSysCalcArguments(mydict)
1887 mglog.info(
'Converted syscalc arguments to systematics arguments: '+syst_arguments)
1888 syst_settings_update={
'systematics_arguments':syst_arguments}
1889 for s
in syscalc_settings:
1890 syst_settings_update[s]=
None
1891 modify_run_card(process_dir=process_dir,settings=syst_settings_update,skipBaseFragment=
True)
1896 mglog.info(
'Checking PDF and systematics settings')
1897 if not MadGraphControl.MadGraphSystematicsUtils.base_fragment_setup_check(MADGRAPH_PDFSETTING,mydict,isNLO):
1899 syst_settings=MadGraphControl.MadGraphSystematicsUtils.get_pdf_and_systematic_settings(MADGRAPH_PDFSETTING,isNLO)
1900 modify_run_card(process_dir=process_dir,settings=syst_settings,skipBaseFragment=
True)
1903 if 'systematics_arguments' in mydict_new:
1904 systematics_arguments=MadGraphControl.MadGraphSystematicsUtils.parse_systematics_arguments(mydict_new[
'systematics_arguments'])
1905 if 'weight_info' not in systematics_arguments:
1906 mglog.info(
'Enforcing systematic weight name convention')
1908 if '--dyn' in systematics_arguments
or ' dyn' in systematics_arguments:
1909 if '--dyn' in systematics_arguments:
1910 dyn = systematics_arguments.split(
'--dyn')[1]
1911 if ' dyn' in systematics_arguments:
1912 dyn = systematics_arguments.split(
' dyn')[1]
1913 dyn = dyn.replace(
'\'',
' ').
replace(
'=',
' ').
split()[0]
1914 if dyn
is not None and len(dyn.split(
','))>1:
1915 systematics_arguments[
'weight_info']=MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO_ALTDYNSCALES
1917 systematics_arguments[
'weight_info']=MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO
1918 modify_run_card(process_dir=process_dir,settings={
'systematics_arguments':MadGraphControl.MadGraphSystematicsUtils.write_systematics_arguments(systematics_arguments)},skipBaseFragment=
True)
1921 if 'python_seed' not in mydict:
1922 mglog.warning(
'No python seed set in run_card -- adding one with same value as iseed')
1923 modify_run_card(process_dir=process_dir,settings={
'python_seed':mydict[
'iseed']},skipBaseFragment=
True)
1927 proton_5flav =
False
1929 with open(process_dir+
'/Cards/proc_card_mg5.dat',
'r')
as file:
1930 content = file.readlines()
1931 for rawline
in content:
1932 line = rawline.split(
'#')[0]
1933 if line.startswith(
"define p"):
1934 if (
'b' in line.split()
and 'b~' in line.split())
or (
'5' in line.split()
and '-5' in line.split()):
1936 if 'j' in line.split()
and jet_5flav:
1938 if line.startswith(
"define j"):
1939 if (
'b' in line.split()
and 'b~' in line.split())
or (
'5' in line.split()
and '-5' in line.split()):
1941 if 'p' in line.split()
and proton_5flav:
1943 if proton_5flav
or jet_5flav:
1944 FS_updates[
'asrwgtflavor'] = 5
1945 if not proton_5flav:
1946 mglog.warning(
'Found 5-flavour jets but 4-flavour proton. This is inconsistent - please pick one.')
1947 mglog.warning(
'Will proceed assuming 5-flavour scheme.')
1949 mglog.warning(
'Found 5-flavour protons but 4-flavour jets. This is inconsistent - please pick one.')
1950 mglog.warning(
'Will proceed assuming 5-flavour scheme.')
1952 FS_updates[
'asrwgtflavor'] = 4
1954 if len(FS_updates)==0:
1955 mglog.warning(f
'Could not identify 4- or 5-flavor scheme from process card {process_dir}/Cards/proc_card_mg5.dat')
1957 if 'asrwgtflavor' in mydict
or 'maxjetflavor' in mydict
or 'pdgs_for_merging_cut' in mydict:
1958 if FS_updates[
'asrwgtflavor'] == 5:
1960 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']):
1962 mglog.warning(
'b and b~ included in p and j for 5-flavor scheme but run card settings are inconsistent; adjusting run card')
1963 run_card_updates = {
'asrwgtflavor': 5,
'maxjetflavor': 5,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 5, 21'}
1964 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1965 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'0.000000e+00'}})
1967 mglog.debug(
'Consistent 5-flavor scheme setup detected.')
1968 if FS_updates[
'asrwgtflavor'] == 4:
1970 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']):
1972 mglog.warning(
'b and b~ not included in p and j (4-flavor scheme) but run card settings are inconsistent; adjusting run card')
1973 run_card_updates = {
'asrwgtflavor': 4,
'maxjetflavor': 4,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 21'}
1974 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1975 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'4.700000e+00'}})
1977 mglog.debug(
'Consistent 4-flavor scheme setup detected.')
1980 if FS_updates[
'asrwgtflavor'] == 4:
1982 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.')
1983 run_card_updates = {
'asrwgtflavor': 4,
'maxjetflavor': 4,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 21'}
1984 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1985 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'4.700000e+00'}})
1986 elif FS_updates[
'asrwgtflavor'] == 5:
1987 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.')
1988 run_card_updates = {
'asrwgtflavor': 5,
'maxjetflavor': 5,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 5, 21'}
1989 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1990 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'0.000000e+00'}})
1992 mglog.info(
'Finished checking run card - All OK!')
1995 mglog.info(
'Running reweighting module on existing events')
1996 if reweight_card
is not None:
1997 mglog.info(
'Copying new reweight card from '+reweight_card)
1998 shutil.move(reweight_card,process_dir+
'/Cards/reweight_card.dat')
1999 reweight_cmd=
'{}/bin/madevent reweight {} -f'.
format(process_dir,run_name)
2000 global MADGRAPH_CATCH_ERRORS
2001 reweight =
stack_subprocess([python]+reweight_cmd.split(),stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
2002 (out,err) = reweight.communicate()
2004 mglog.info(
'Finished reweighting')
2010 mglog.info(
'For your information, ls of '+directory+
':')
2011 mglog.info(
sorted( os.listdir( directory ) ) )
2014 import MadGraphControl.MadGraphSystematicsUtils
2018 makefile_fks=process_dir+
'/SubProcesses/makefile_fks_dir'
2019 mglog.info(
'Fixing '+makefile_fks)
2020 shutil.move(makefile_fks,makefile_fks+
'_orig')
2021 fin=
open(makefile_fks+
'_orig')
2022 fout=
open(makefile_fks,
'w')
2025 if 'FKSParams.mod' in line:
2026 fout.write(line.replace(
'FKSParams.mod',
'FKSParams.o'))
2028 elif edit
and 'driver_mintFO' in line:
2029 fout.write(
'driver_mintFO.o: weight_lines.o mint_module.o FKSParams.o\n')
2030 elif edit
and 'genps_fks.o' in line:
2031 fout.write(
'genps_fks.o: mint_module.o FKSParams.o\n')
2032 elif edit
and 'test_soft_col_limits' in line:
2034 fout.write(
'madfks_plot.o: mint_module.o\n')
2035 fout.write(
'cluster.o: weight_lines.o\n')