112def 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):
114 setup_path_protection()
119 if 'ATHENA_CORE_NUMBER' in os.environ
and int(os.environ[
'ATHENA_CORE_NUMBER'])>0:
120 njobs = int(os.environ[
'ATHENA_CORE_NUMBER'])
121 mglog.info(
'Lucky you - you are running on a full node queue. Will re-configure for '+str(njobs)+
' jobs.')
125 if cluster_type
is not None:
129 mglog.info(
'Running event generation from gridpack (using smarter mode from generate() function)')
130 generate_from_gridpack(runArgs=runArgs,extlhapath=extlhapath,gridpack_compile=gridpack_compile,requirePMGSettings=requirePMGSettings)
133 mglog.info(
'Did not identify an input gridpack.')
135 mglog.info(
'The grid_pack flag is set, so I am expecting to create a gridpack in this job')
138 beamEnergy,random_seed = get_runArgs_info(runArgs)
141 isNLO=is_NLO_run(process_dir=process_dir)
149 if shutil.which(
'f2py')
is not None:
150 mglog.info(
'Found f2py, will use it for reweighting')
152 raise RuntimeError(
'Could not find f2py, needed for reweighting')
155 global MADGRAPH_COMMAND_STACK
159 mglog.info(
'Started generating gridpack at '+str(time.asctime()))
160 mglog.warning(
' >>>>>> THIS KIND OF JOB SHOULD ONLY BE RUN LOCALLY - NOT IN GRID JOBS <<<<<<')
163 my_settings = {
'nevents':
'1000'}
166 my_settings[
'req_acc']=str(required_accuracy)
169 LO_has_madspin =
False
170 if os.access(f
'{process_dir}/Cards/madspin_card.dat',os.R_OK):
171 MADGRAPH_COMMAND_STACK += [f
'mv {process_dir}/Cards/madspin_card.dat {process_dir}/Cards/madspin_card.tmp.dat']
172 os.rename(f
'{process_dir}/Cards/madspin_card.dat',f
'{process_dir}/Cards/madspin_card.tmp.dat')
173 LO_has_madspin =
True
174 my_settings = {
'gridpack':
'true'}
175 modify_run_card(process_dir=process_dir,settings=my_settings,skipBaseFragment=
True)
179 mglog.info(
'Started generating at '+str(time.asctime()))
181 mglog.info(
'Run '+MADGRAPH_RUN_NAME+
' will be performed in mode '+str(mode)+
' with '+str(njobs)+
' jobs in parallel.')
184 if not os.access(process_dir,os.R_OK):
185 raise RuntimeError(
'No process directory found at '+process_dir)
186 if not os.access(process_dir+
'/bin/generate_events',os.R_OK):
187 raise RuntimeError(
'No generate_events module found in '+process_dir)
189 mglog.info(
'For your information, the libraries available are (should include LHAPDF):')
190 ls_dir(process_dir+
'/lib')
193 if bias_module
is not None:
196 mglog.info(
'Now I will hack the make files a bit. Apologies, but there seems to be no good way around this.')
197 shutil.copyfile(process_dir+
'/Source/make_opts',process_dir+
'/Source/make_opts_old')
198 old_opts = open(process_dir+
'/Source/make_opts_old',
'r')
199 new_opts = open(process_dir+
'/Source/make_opts',
'w')
200 for aline
in old_opts:
202 mglog.info(
'Configuring the fancy gfortran compiler instead of g77 / f77')
203 new_opts.write(
' FC=gfortran\n')
205 new_opts.write(aline)
208 mglog.info(
'Make file hacking complete.')
212 os.chdir(process_dir)
214 MADGRAPH_COMMAND_STACK += [
'cd ${MGaMC_PROCESS_DIR}' ]
221 original_systematics_program =
None if 'systematics_program' not in my_MGC_instance.runCardDict
else my_MGC_instance.runCardDict[
'systematics_program']
222 modify_run_card(process_dir=process_dir,settings={
'systematics_program':
'None'},skipBaseFragment=
True)
228 code = check_PMG_updates(process_dir=os.getcwd())
229 if requirePMGSettings
and code!=0:
230 raise RuntimeError(
'Settings are not compliant with PMG defaults! Please use do_PMG_updates function to get PMG default params.')
234 command = [python,
'bin/generate_events']
236 command += [
'--name='+MADGRAPH_RUN_NAME]
237 mglog.info(
'Removing Cards/shower_card.dat to ensure we get parton level events only')
238 os.unlink(
'Cards/shower_card.dat')
240 command += [MADGRAPH_RUN_NAME]
242 setNCores(process_dir=os.getcwd(), Ncores=njobs)
245 mglog.info(
'Setting up cluster running')
247 if cluster_type==
'pbs':
248 mglog.info(
'Modifying bin/internal/cluster.py for PBS cluster running')
249 os.system(
"sed -i \"s:text += prog:text += './'+prog:g\" bin/internal/cluster.py")
251 mglog.info(
'Setting up multi-core running on '+os.environ[
'ATHENA_CORE_NUMBER']+
' cores')
253 mglog.info(
'Setting up serial generation.')
256 generate =
stack_subprocess(command,stdin=subprocess.PIPE, stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
257 (out,err) = generate.communicate()
258 error_check(err,generate.returncode)
262 MADGRAPH_COMMAND_STACK += [
'cd -' ]
266 energy =
'%1.1f'%(beamEnergy*2./1000.)
267 energy = energy.replace(
'.0',
'').
replace(
'.',
'p')
268 gridpack_name=
'mc_'+energy+
'TeV.'+get_physics_short()+
'.GRID.tar.gz'
269 mglog.info(
'Tidying up gridpack '+gridpack_name)
272 modify_run_card(process_dir=process_dir,settings={
'systematics_program':original_systematics_program})
277 MADGRAPH_COMMAND_STACK += [f
'mv {process_dir}/Cards/madspin_card.tmp.dat {process_dir}/Cards/madspin_card.dat']
278 os.rename(f
'{process_dir}/Cards/madspin_card.tmp.dat',f
'{process_dir}/Cards/madspin_card.dat')
281 MADGRAPH_COMMAND_STACK += [
'cp '+glob.glob(process_dir+
'/'+MADGRAPH_RUN_NAME+
'_*gridpack.tar.gz')[0]+
' '+gridpack_name]
282 shutil.copy(glob.glob(process_dir+
'/'+MADGRAPH_RUN_NAME+
'_*gridpack.tar.gz')[0],gridpack_name)
285 MADGRAPH_COMMAND_STACK += [
'mkdir tmp%i/'%os.getpid(),
'cd tmp%i/'%os.getpid()]
286 os.mkdir(
'tmp%i/'%os.getpid())
287 os.chdir(
'tmp%i/'%os.getpid())
288 mglog.info(
'untar gridpack')
291 mglog.info(
'compile and clean up')
292 MADGRAPH_COMMAND_STACK += [
'cd madevent']
293 os.chdir(
'madevent/')
294 compilep =
stack_subprocess([
'./bin/compile'],stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
295 (out,err) = compilep.communicate()
296 error_check(err,compilep.returncode)
297 clean =
stack_subprocess([
'./bin/clean4grid'],stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
298 (out,err) = clean.communicate()
299 error_check(err,clean.returncode)
301 MADGRAPH_COMMAND_STACK += [
'cd ..',
'rm ../'+gridpack_name]
303 mglog.info(
'remove old tarball')
304 os.unlink(
'../'+gridpack_name)
305 mglog.info(
'Package up new tarball')
306 tar =
stack_subprocess([
'tar',
'--exclude=SubProcesses/P*/G*/*_results.dat',
'--exclude=SubProcesses/P*/G*/*.log',
'--exclude=SubProcesses/P*/G*/*.txt',
'-cvsf',
'../'+gridpack_name,
'.'])
308 MADGRAPH_COMMAND_STACK += [
'cd ..',
'rm -r tmp%i/'%os.getpid()]
310 mglog.info(
'Remove temporary directory')
311 shutil.rmtree(
'tmp%i/'%os.getpid())
312 mglog.info(
'Tidying up complete!')
317 mglog.info(
'Package up process_dir')
318 MADGRAPH_COMMAND_STACK += [
'mv '+process_dir+
' '+MADGRAPH_GRIDPACK_LOCATION]
319 os.rename(process_dir,MADGRAPH_GRIDPACK_LOCATION)
320 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])
322 MADGRAPH_COMMAND_STACK += [
'mv '+MADGRAPH_GRIDPACK_LOCATION+
' '+process_dir]
323 os.rename(MADGRAPH_GRIDPACK_LOCATION,process_dir)
325 mglog.info(
'Gridpack sucessfully created, exiting the transform')
326 if hasattr(runArgs,
'outputTXTFile'):
327 mglog.info(
'Touching output TXT (LHE) file for the transform')
328 open(runArgs.outputTXTFile,
'w').close()
329 from AthenaCommon.AppMgr
import theApp
333 mglog.info(
'Finished at '+str(time.asctime()))
339 beamEnergy,random_seed = get_runArgs_info(runArgs)
342 setup_path_protection()
344 isNLO=is_NLO_run(process_dir=MADGRAPH_GRIDPACK_LOCATION)
349 gridpack_run_name =
'GridRun_'+str(random_seed)
352 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/madspin_card.dat',os.R_OK):
353 os.rename(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/madspin_card.dat',MADGRAPH_GRIDPACK_LOCATION+
'/Cards/backup_madspin_card.dat')
362 code = check_PMG_updates(process_dir=MADGRAPH_GRIDPACK_LOCATION)
363 if requirePMGSettings
and code!=0:
364 raise RuntimeError(
'Settings are not compliant with PMG defaults! Please use do_PMG_updates function to get PMG default params.')
367 settings={
'iseed':str(random_seed)}
369 settings[
'python_seed']=str(random_seed)
370 modify_run_card(process_dir=MADGRAPH_GRIDPACK_LOCATION,settings=settings,skipBaseFragment=
True)
372 mglog.info(
'Generating events from gridpack')
375 if not os.path.exists(MADGRAPH_GRIDPACK_LOCATION):
376 raise RuntimeError(
'Gridpack directory not found at '+MADGRAPH_GRIDPACK_LOCATION)
378 nevents = getDictFromCard(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/run_card.dat')[
'nevents']
379 mglog.info(
'>>>> FOUND GRIDPACK <<<< <- This will be used for generation')
380 mglog.info(
'Generation of '+str(int(nevents))+
' events will be performed using the supplied gridpack with random seed '+str(random_seed))
381 mglog.info(
'Started generating events at '+str(time.asctime()))
384 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/bin/internal/addmasses.py',os.R_OK):
385 os.remove(MADGRAPH_GRIDPACK_LOCATION+
'/bin/internal/addmasses.py')
390 setNCores(process_dir=MADGRAPH_GRIDPACK_LOCATION)
394 ls_dir(MADGRAPH_GRIDPACK_LOCATION)
404 run_card_dict=getDictFromCard(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/run_card.dat')
405 systematics_settings=
None
406 if checkSetting(
'systematics_program',
'systematics',run_card_dict):
407 if not checkSettingIsTrue(
'store_rwgt_info',run_card_dict):
408 raise RuntimeError(
'Trying to run NLO systematics but reweight info not stored')
409 if checkSettingExists(
'systematics_arguments',run_card_dict):
410 systematics_settings=MadGraphControl.MadGraphSystematicsUtils.parse_systematics_arguments(run_card_dict[
'systematics_arguments'])
412 systematics_settings={}
413 mglog.info(
'Turning off systematics for now, running standalone later')
414 modify_run_card(process_dir=MADGRAPH_GRIDPACK_LOCATION,settings={
'systematics_program':
'none'},skipBaseFragment=
True)
416 global MADGRAPH_COMMAND_STACK
419 if not os.access(MADGRAPH_GRIDPACK_LOCATION+
'/bin/gridrun',os.R_OK):
420 mglog.error(
'/bin/gridrun not found at '+MADGRAPH_GRIDPACK_LOCATION)
421 raise RuntimeError(
'Could not find gridrun executable')
423 mglog.info(
'Found '+MADGRAPH_GRIDPACK_LOCATION+
'/bin/gridrun, starting generation.')
426 mglog.info(
"Now generating {} events with random seed {} and granularity {}".format(int(nevents),int(random_seed),granularity))
428 new_ld_path=
":".join([os.environ[
'LD_LIBRARY_PATH'],os.getcwd()+
'/'+MADGRAPH_GRIDPACK_LOCATION+
'/madevent/lib',os.getcwd()+
'/'+MADGRAPH_GRIDPACK_LOCATION+
'/HELAS/lib'])
429 os.environ[
'LD_LIBRARY_PATH']=new_ld_path
430 MADGRAPH_COMMAND_STACK+=[
"export LD_LIBRARY_PATH="+
":".join([
'${LD_LIBRARY_PATH}',new_ld_path])]
431 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)
432 (out,err) = generate.communicate()
433 error_check(err,generate.returncode)
434 gp_events=MADGRAPH_GRIDPACK_LOCATION+
"/Events/GridRun_{}/unweighted_events.lhe.gz".format(int(random_seed))
435 if not os.path.exists(gp_events):
436 mglog.error(
'Error in gp generation, did not find events at '+gp_events)
440 if reweight_card
is not None:
441 pythonpath_backup=os.environ[
'PYTHONPATH']
443 os.environ[
'PYTHONPATH']=
':'.join([p
for p
in pythonpath_backup.split(
':')
if 'madgraph5amc' not in p])
445 os.environ[
'PYTHONPATH']=pythonpath_backup
447 shutil.move(gp_events,
'events.lhe.gz')
451 if not os.access(MADGRAPH_GRIDPACK_LOCATION+
'/bin/generate_events',os.R_OK):
452 raise RuntimeError(
'Could not find generate_events executable at '+MADGRAPH_GRIDPACK_LOCATION)
454 mglog.info(
'Found '+MADGRAPH_GRIDPACK_LOCATION+
'/bin/generate_events, starting generation.')
456 ls_dir(MADGRAPH_GRIDPACK_LOCATION+
'/Events/')
457 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name, os.F_OK):
458 mglog.info(
'Removing '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
' directory from gridpack generation')
459 MADGRAPH_COMMAND_STACK += [
'rm -rf '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name]
460 shutil.rmtree(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name)
463 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1', os.F_OK):
464 mglog.info(
'Removing '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1 directory from gridpack generation')
465 MADGRAPH_COMMAND_STACK += [
'rm -rf '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1']
466 shutil.rmtree(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1')
468 ls_dir(MADGRAPH_GRIDPACK_LOCATION+
'/Events/')
470 if not gridpack_compile:
471 mglog.info(
'Copying make_opts from Template')
472 shutil.copy(os.environ[
'MADPATH']+
'/Template/LO/Source/make_opts',MADGRAPH_GRIDPACK_LOCATION+
'/Source/')
475 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)
476 (out,err) = generate.communicate()
477 error_check(err,generate.returncode)
479 mglog.info(
'Allowing recompilation of gridpack')
480 if os.path.islink(MADGRAPH_GRIDPACK_LOCATION+
'/lib/libLHAPDF.a'):
481 mglog.info(
'Unlinking '+MADGRAPH_GRIDPACK_LOCATION+
'/lib/libLHAPDF.a')
482 os.unlink(MADGRAPH_GRIDPACK_LOCATION+
'/lib/libLHAPDF.a')
485 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)
486 (out,err) = generate.communicate()
487 error_check(err,generate.returncode)
488 if isNLO
and systematics_settings
is not None:
490 mglog.info(
'Running systematics standalone')
491 systematics_path=MADGRAPH_GRIDPACK_LOCATION+
'/bin/internal/systematics.py'
492 events_location=MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/events.lhe.gz'
493 syst_cmd=[python,systematics_path]+[events_location]*2+[
"--"+k+
"="+systematics_settings[k]
for k
in systematics_settings]
494 mglog.info(
'running: '+
' '.join(syst_cmd))
500 if not os.access(
'events.lhe.gz',os.R_OK):
501 mglog.info(
'Copying generated events to '+currdir)
502 if not os.path.exists(MADGRAPH_GRIDPACK_LOCATION+
'Events/'+gridpack_run_name):
503 shutil.copy(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/events.lhe.gz',
'events.lhe.gz')
505 mglog.info(
'Events were already in place')
509 mglog.info(
'Moving generated events to be in correct format for arrange_output().')
510 mglog.info(
'Unzipping generated events.')
514 mglog.info(
'Moving file over to '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe')
515 mkdir =
stack_subprocess([
'mkdir',
'-p',(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name)])
517 shutil.move(
'events.lhe',MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe')
519 mglog.info(
'Re-zipping into dataset name '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe.gz')
520 rezip =
stack_subprocess([
'gzip',MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe'])
528 os.rename(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/backup_madspin_card.dat',MADGRAPH_GRIDPACK_LOCATION+
'/Cards/madspin_card.dat')
529 mglog.info(
'Decaying with MadSpin.')
530 add_madspin(process_dir=MADGRAPH_GRIDPACK_LOCATION)
532 mglog.info(
'Finished at '+str(time.asctime()))
569def setupLHAPDF(process_dir=None, extlhapath=None, allow_links=True):
570 isNLO=is_NLO_run(process_dir=process_dir)
572 origLHAPATH=os.environ[
'LHAPATH']
573 origLHAPDF_DATA_PATH=os.environ[
'LHAPDF_DATA_PATH']
575 LHAPATH,LHADATAPATH=get_LHAPDF_PATHS()
581 run_card=process_dir+
'/Cards/run_card.dat'
582 mydict=getDictFromCard(run_card)
584 if mydict[
"pdlabel"].
replace(
"'",
"") ==
'lhapdf':
586 mglog.info(
'creating local LHAPDF dir: MGC_LHAPDF/')
587 if os.path.islink(
'MGC_LHAPDF/'):
588 os.unlink(
'MGC_LHAPDF/')
589 elif os.path.isdir(
'MGC_LHAPDF/'):
590 shutil.rmtree(
'MGC_LHAPDF/')
592 newMGCLHA=
'MGC_LHAPDF/'
594 mkdir = subprocess.Popen([
'mkdir',
'-p',newMGCLHA])
597 pdfs_used=[ int(x)
for x
in mydict[
'lhaid'].
replace(
' ',
',').
split(
',') ]
599 if 'sys_pdf' in mydict:
605 pdfs_used.append(idx)
608 if 'systematics_arguments' in mydict:
609 systematics_arguments=MadGraphControl.MadGraphSystematicsUtils.parse_systematics_arguments(mydict[
'systematics_arguments'])
610 if 'pdf' in systematics_arguments:
616 pdfs_used.append(idx)
619 for pdf
in pdfs_used:
620 if isinstance(pdf,str)
and (pdf.lower()==
'errorset' or pdf.lower()==
'central'):
623 pdfid,pdfname=get_lhapdf_id_and_name(pdf)
624 mglog.info(
"Found LHAPDF ID="+str(pdfid)+
", name="+pdfname)
626 if not os.path.exists(newMGCLHA+pdfname)
and not os.path.lexists(newMGCLHA+pdfname):
627 if not os.path.exists(LHADATAPATH+
'/'+pdfname):
628 mglog.warning(
'PDF not installed at '+LHADATAPATH+
'/'+pdfname)
630 mglog.info(
'linking '+LHADATAPATH+
'/'+pdfname+
' --> '+newMGCLHA+pdfname)
631 os.symlink(LHADATAPATH+
'/'+pdfname,newMGCLHA+pdfname)
633 mglog.info(
'copying '+LHADATAPATH+
'/'+pdfname+
' --> '+newMGCLHA+pdfname)
634 shutil.copytree(LHADATAPATH+
'/'+pdfname,newMGCLHA+pdfname)
637 mglog.info(
'linking '+LHADATAPATH+
'/pdfsets.index --> '+newMGCLHA+
'pdfsets.index')
638 os.symlink(LHADATAPATH+
'/pdfsets.index',newMGCLHA+
'pdfsets.index')
640 atlasLHADATAPATH=LHADATAPATH.replace(
'sft.cern.ch/lcg/external/lhapdfsets/current',
'atlas.cern.ch/repo/sw/Generators/lhapdfsets/current')
641 mglog.info(
'linking '+atlasLHADATAPATH+
'/lhapdf.conf --> '+newMGCLHA+
'lhapdf.conf')
642 os.symlink(atlasLHADATAPATH+
'/lhapdf.conf',newMGCLHA+
'lhapdf.conf')
644 mglog.info(
'copying '+LHADATAPATH+
'/pdfsets.index --> '+newMGCLHA+
'pdfsets.index')
645 shutil.copy2(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(
'copying '+atlasLHADATAPATH+
'/lhapdf.conf -->'+newMGCLHA+
'lhapdf.conf')
649 shutil.copy2(atlasLHADATAPATH+
'/lhapdf.conf',newMGCLHA+
'lhapdf.conf')
652 LHADATAPATH=os.getcwd()+
'/MGC_LHAPDF'
655 mglog.info(
'Not using LHAPDF')
656 return (LHAPATH,origLHAPATH,origLHAPDF_DATA_PATH)
660 os.environ[
'LHAPDF_DATA_PATH']=LHADATAPATH
662 mglog.info(
'Path to LHAPDF install dir: '+LHAPATH)
663 mglog.info(
'Path to LHAPDF data dir: '+LHADATAPATH)
664 if not os.path.isdir(LHADATAPATH):
665 raise RuntimeError(
'LHAPDF data dir not accesible: '+LHADATAPATH)
666 if not os.path.isdir(LHAPATH):
667 raise RuntimeError(
'LHAPDF path dir not accesible: '+LHAPATH)
671 lhapdfconfig=extlhapath
672 if not os.access(lhapdfconfig,os.X_OK):
673 raise RuntimeError(
'Failed to find valid external lhapdf-config at '+lhapdfconfig)
674 LHADATAPATH=subprocess.Popen([lhapdfconfig,
'--datadir'],stdout = subprocess.PIPE).stdout.read().
strip()
675 mglog.info(
'Changing LHAPDF_DATA_PATH to '+LHADATAPATH)
676 os.environ[
'LHAPDF_DATA_PATH']=LHADATAPATH
678 getlhaconfig = subprocess.Popen([
'get_files',
'-data',
'lhapdf-config'])
681 if not os.access(os.getcwd()+
'/lhapdf-config',os.X_OK):
682 mglog.error(
'Failed to get lhapdf-config from MadGraphControl')
684 lhapdfconfig = os.getcwd()+
'/lhapdf-config'
686 mglog.info(
'lhapdf-config --version: '+str(subprocess.Popen([lhapdfconfig,
'--version'],stdout = subprocess.PIPE).stdout.read().
strip()))
687 mglog.info(
'lhapdf-config --prefix: '+str(subprocess.Popen([lhapdfconfig,
'--prefix'],stdout = subprocess.PIPE).stdout.read().
strip()))
688 mglog.info(
'lhapdf-config --libdir: '+str(subprocess.Popen([lhapdfconfig,
'--libdir'],stdout = subprocess.PIPE).stdout.read().
strip()))
689 mglog.info(
'lhapdf-config --datadir: '+str(subprocess.Popen([lhapdfconfig,
'--datadir'],stdout = subprocess.PIPE).stdout.read().
strip()))
690 mglog.info(
'lhapdf-config --pdfsets-path: '+str(subprocess.Popen([lhapdfconfig,
'--pdfsets-path'],stdout = subprocess.PIPE).stdout.read().
strip()))
692 modify_config_card(process_dir=process_dir,settings={
'lhapdf':lhapdfconfig,
'lhapdf_py3':lhapdfconfig})
694 mglog.info(
'Creating links for LHAPDF')
695 if os.path.islink(process_dir+
'/lib/PDFsets'):
696 os.unlink(process_dir+
'/lib/PDFsets')
697 elif os.path.isdir(process_dir+
'/lib/PDFsets'):
698 shutil.rmtree(process_dir+
'/lib/PDFsets')
700 os.symlink(LHADATAPATH,process_dir+
'/lib/PDFsets')
702 shutil.copytree(LHADATAPATH,process_dir+
'/lib/PDFsets')
703 mglog.info(
'Available PDFs are:')
704 mglog.info( sorted( [ x
for x
in os.listdir(process_dir+
'/lib/PDFsets')
if ".tar.gz" not in x ] ) )
706 global MADGRAPH_COMMAND_STACK
707 MADGRAPH_COMMAND_STACK += [
'# Copy the LHAPDF files locally' ]
708 MADGRAPH_COMMAND_STACK += [
'cp -r '+os.getcwd()+
'/MGC_LHAPDF .' ]
709 MADGRAPH_COMMAND_STACK += [
'cp -r '+process_dir+
'/lib/PDFsets ${MGaMC_PROCESS_DIR}/lib/' ]
711 return (LHAPATH,origLHAPATH,origLHAPDF_DATA_PATH)
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 generate =
stack_subprocess([python,madpath+
'/MadSpin/madspin',
'madspin_exec_card'],stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
872 (out,err) = generate.communicate()
873 error_check(err,generate.returncode)
874 mglog.info(
'Done with madspin at '+str(time.asctime()))
878 if os.path.exists(os.getcwd()+
'/events.lhe'):
879 os.remove(os.getcwd()+
'/events.lhe')
881 mglog.info(
'Unzipping generated events.')
885 mglog.info(
'Putting a copy in place for the transform.')
886 mod_output = open(os.getcwd()+
'/events.lhe',
'w')
890 with open(input_LHE,
'r')
as fileobject:
891 for line
in fileobject:
893 mod_output.write(line)
898 mglog.info(
'Removed '+str(nEmpty)+
' empty lines from LHEF')
902 raise RuntimeError(
'Must provide runArgs to madspin_on_lhe')
904 outputDS = runArgs.outputTXTFile
if hasattr(runArgs,
'outputTXTFile')
else 'tmp_LHE_events.tar.gz'
906 mglog.info(
'Moving file over to '+outputDS.split(
'.tar.gz')[0]+
'.events')
907 shutil.move(os.getcwd()+
'/events.lhe',outputDS.split(
'.tar.gz')[0]+
'.events')
909 mglog.info(
'Re-zipping into dataset name '+outputDS)
910 rezip =
stack_subprocess([
'tar',
'cvzf',outputDS,outputDS.split(
'.tar.gz')[0]+
'.events'])
914 if hasattr(runArgs,
'outputTXTFile')
and runArgs.outputTXTFile
is not None:
915 outputDS = outputDS.split(
'.TXT')[0]
917 if runArgs
is not None:
918 mglog.debug(
'Setting inputGenerator file to '+outputDS)
919 runArgs.inputGeneratorFile=outputDS
922def arrange_output(process_dir=MADGRAPH_GRIDPACK_LOCATION,lhe_version=None,saveProcDir=False,runArgs=None,fixEventWeightsForBridgeMode=False):
927 if len(glob.glob(os.path.join(process_dir,
'Events',
'*')))<1:
928 mglog.error(
'Process dir '+process_dir+
' does not contain events?')
929 proc_dir_list = glob.glob(os.path.join(process_dir,
'Events',
'*'))
932 for adir
in proc_dir_list:
933 if 'decayed' in adir:
936 if 'GridRun_' in adir:
939 elif os.path.join(process_dir,
'Events',MADGRAPH_RUN_NAME)
in adir:
941 if not os.access(this_run_name,os.R_OK):
942 raise RuntimeError(
'Unable to locate run directory')
944 hasUnweighted = os.access(this_run_name+
'/unweighted_events.lhe.gz',os.R_OK)
947 madspinDirs=sorted(glob.glob(this_run_name+
'_decayed_*/'))
950 if hasRunMadSpin
and not hasUnweighted:
952 hasUnweighted = os.access(madspinDirs[-1]+
'/unweighted_events.lhe.gz',os.R_OK)
954 global MADGRAPH_COMMAND_STACK
963 if os.path.exists(madspinDirs[-1]+
'/unweighted_events.lhe.gz'):
964 MADGRAPH_COMMAND_STACK += [
'mv '+madspinDirs[-1]+
'/unweighted_events.lhe.gz'+
' '+this_run_name+
'/unweighted_events.lhe.gz']
965 shutil.move(madspinDirs[-1]+
'/unweighted_events.lhe.gz',this_run_name+
'/unweighted_events.lhe.gz')
966 mglog.info(
'Moving MadSpin events from '+madspinDirs[-1]+
'/unweighted_events.lhe.gz to '+this_run_name+
'/unweighted_events.lhe.gz')
967 elif os.path.exists(madspinDirs[-1]+
'/events.lhe.gz'):
968 MADGRAPH_COMMAND_STACK += [
'mv '+madspinDirs[-1]+
'/events.lhe.gz'+
' '+this_run_name+
'/unweighted_events.lhe.gz']
969 shutil.move(madspinDirs[-1]+
'/events.lhe.gz',this_run_name+
'/unweighted_events.lhe.gz')
970 mglog.info(
'Moving MadSpin events from '+madspinDirs[-1]+
'/events.lhe.gz to '+this_run_name+
'/unweighted_events.lhe.gz')
972 raise RuntimeError(
'MadSpin was run but can\'t find files :(')
975 MADGRAPH_COMMAND_STACK += [
'mv '+madspinDirs[-1]+
'/events.lhe.gz '+this_run_name+
'/events.lhe.gz']
976 shutil.move(madspinDirs[-1]+
'/events.lhe.gz',this_run_name+
'/events.lhe.gz')
977 mglog.info(
'Moving MadSpin events from '+madspinDirs[-1]+
'/events.lhe.gz to '+this_run_name+
'/events.lhe.gz')
980 mglog.error(
'MadSpin was run but can\'t find output folder '+(this_run_name+
'_decayed_1/'))
981 raise RuntimeError(
'MadSpin was run but can\'t find output folder '+(this_run_name+
'_decayed_1/'))
983 if fixEventWeightsForBridgeMode:
984 mglog.info(
"Fixing event weights after MadSpin... initial checks.")
992 eventsfilename=
"unweighted_events"
994 eventsfilename=
"events"
995 unzip =
stack_subprocess([
'gunzip',
'-f',this_run_name+
'/%s.lhe.gz' % eventsfilename])
998 for line
in open(process_dir+
'/Events/'+MADGRAPH_RUN_NAME+
'/%s.lhe'%eventsfilename):
999 if "Number of Events" in line:
1001 MGnumevents=int(sline[-1])
1002 elif "Integrated weight (pb)" in line:
1004 MGintweight=float(sline[-1])
1005 elif "set spinmode none" in line:
1007 elif "</header>" in line:
1010 if spinmodenone
and MGnumevents>0
and MGintweight>0:
1011 mglog.info(
"Fixing event weights after MadSpin... modifying LHE file.")
1012 newlhe=open(this_run_name+
'/%s_fixXS.lhe'%eventsfilename,
'w')
1020 event_norm_setting=
"average"
1022 for line
in open(this_run_name+
'/%s.lhe'%eventsfilename):
1025 if "<init>" in line:
1028 elif "</init>" in line:
1030 elif inInit
and initlinecount==0:
1034 if abs(int(sline[-2])) == 3:
1035 event_norm_setting=
"sum"
1036 elif abs(int(sline[-2])) == 4:
1037 event_norm_setting=
"average"
1038 elif inInit
and initlinecount==1:
1041 relunc=float(sline[1])/float(sline[0])
1042 sline[0]=str(MGintweight)
1043 sline[1]=str(float(sline[0])*relunc)
1044 if event_norm_setting==
"sum":
1045 sline[2]=str(MGintweight/MGnumevents)
1046 elif event_norm_setting==
"average":
1047 sline[2]=str(MGintweight)
1048 newline=
' '.join(sline)
1051 elif inInit
and initlinecount>1:
1053 elif "<event>" in line:
1056 elif "</event>" in line:
1058 elif inEvent
and eventlinecount==0:
1061 if event_norm_setting==
"sum":
1062 sline[2]=str(MGintweight/MGnumevents)
1063 elif event_norm_setting==
"average":
1064 sline[2]=str(MGintweight)
1065 newline=
' '.join(sline)
1068 newlhe.write(newline)
1071 mglog.info(
"Fixing event weights after MadSpin... cleaning up.")
1072 shutil.copyfile(this_run_name+
'/%s.lhe' % eventsfilename,
1073 this_run_name+
'/%s_badXS.lhe' % eventsfilename)
1075 shutil.move(this_run_name+
'/%s_fixXS.lhe' % eventsfilename,
1076 this_run_name+
'/%s.lhe' % eventsfilename)
1078 rezip =
stack_subprocess([
'gzip',this_run_name+
'/%s.lhe' % eventsfilename])
1081 rezip =
stack_subprocess([
'gzip',this_run_name+
'/%s_badXS.lhe' % eventsfilename])
1085 if os.path.exists(os.getcwd()+
'/events.lhe'):
1086 os.remove(os.getcwd()+
'/events.lhe')
1088 mglog.info(
'Unzipping generated events.')
1090 unzip =
stack_subprocess([
'gunzip',
'-f',this_run_name+
'/unweighted_events.lhe.gz'])
1096 mglog.info(
'Putting a copy in place for the transform.')
1098 orig_input = this_run_name+
'/unweighted_events.lhe'
1099 mod_output = open(os.getcwd()+
'/events.lhe',
'w')
1101 orig_input = this_run_name+
'/events.lhe'
1102 mod_output = open(os.getcwd()+
'/events.lhe',
'w')
1109 with open(orig_input,
'r')
as fileobject:
1110 for line
in fileobject:
1114 if '#' not in newline:
1116 elif '>' not in newline[ newline.find(
'#'): ]:
1119 mglog.info(
'Found bad LHE line with an XML mark in a comment: "'+newline.strip()+
'"')
1120 newline=newline[:newline.find(
'#')]+
'#'+ (newline[newline.find(
'#'):].
replace(
'>',
'-'))
1122 if initrwgt
is False:
1124 elif "</initrwgt>" in newline:
1126 elif "<initrwgt>" in newline:
1128 elif initrwgt
is not None:
1129 newline=newline.replace(
'_DYNSCALE-1',
'')
1130 if '</weight>' in newline:
1131 iend=newline.find(
'</weight>')
1132 istart=newline[:iend].rfind(
'>')
1133 lhe_weights+=[newline[istart+1:iend].
strip()]
1134 mod_output.write(newline)
1138 mglog.info(
'Removed '+str(nEmpty)+
' empty lines from LHEF')
1140 mglog.info(
"The following "+str(len(lhe_weights))+
" weights have been written to the LHE file: "+
",".join(lhe_weights))
1143 mglog.info(
"Checking whether the following expected weights are in LHE file: "+
",".join(expected_weights))
1144 for w
in expected_weights:
1145 if w
not in lhe_weights:
1146 raise RuntimeError(
"Did not find expected weight "+w+
" in lhe file. Did the reweight or systematics module crash?")
1147 mglog.info(
"Found all required weights!")
1150 mod_output2 = open(os.getcwd()+
'/events.lhe',
'r')
1151 test=mod_output2.readline()
1152 if 'version="' in test:
1153 mglog.info(
'Applying LHE version hack')
1154 final_file = open(os.getcwd()+
'/events.lhe.copy',
'w')
1155 final_file.write(
'<LesHouchesEvents version="%i.0">\n'%lhe_version)
1156 shutil.copyfileobj(mod_output2, final_file)
1158 shutil.copy(os.getcwd()+
'/events.lhe.copy',os.getcwd()+
'/events.lhe')
1160 os.remove(os.getcwd()+
'/events.lhe.copy')
1165 raise RuntimeError(
'Must provide runArgs to arrange_output')
1167 if hasattr(runArgs,
'outputTXTFile'):
1168 outputDS = runArgs.outputTXTFile
1170 outputDS =
'tmp_LHE_events.tar.gz'
1172 mglog.info(
'Moving file over to '+outputDS.split(
'.tar.gz')[0]+
'.events')
1174 shutil.move(os.getcwd()+
'/events.lhe',outputDS.split(
'.tar.gz')[0]+
'.events')
1176 mglog.info(
'Re-zipping into dataset name '+outputDS)
1177 rezip =
stack_subprocess([
'tar',
'cvzf',outputDS,outputDS.split(
'.tar.gz')[0]+
'.events'])
1181 mglog.info(
'Removing the process directory')
1182 shutil.rmtree(process_dir,ignore_errors=
True)
1184 if os.path.isdir(
'MGC_LHAPDF/'):
1185 shutil.rmtree(
'MGC_LHAPDF/',ignore_errors=
True)
1188 if hasattr(runArgs,
'outputTXTFile')
and runArgs.outputTXTFile
is not None:
1189 outputDS = outputDS.split(
'.TXT')[0]
1191 if runArgs
is not None:
1192 mglog.debug(
'Setting inputGenerator file to '+outputDS)
1193 runArgs.inputGeneratorFile=outputDS
1195 mglog.info(
'All done with output arranging!')
1233 run_card = process_dir+
'/Cards/run_card.dat'
1234 if isinstance(bias_module,tuple):
1235 mglog.info(
'Using bias module '+bias_module[0])
1236 the_run_card = open(run_card,
'r')
1237 for line
in the_run_card:
1238 if 'bias_module' in line
and not bias_module[0]
in line:
1239 raise RuntimeError(
'You need to add the bias module '+bias_module[0]+
' to the run card to actually run it')
1240 the_run_card.close()
1241 if len(bias_module)!=3:
1242 raise RuntimeError(
'Please give a 3-tuple of strings containing bias module name, bias module, and makefile. Alternatively, give path to bias module tarball.')
1243 bias_module_newpath=process_dir+
'/Source/BIAS/'+bias_module[0]
1244 os.makedirs(bias_module_newpath)
1245 bias_module_file=open(bias_module_newpath+
'/'+bias_module[0]+
'.f',
'w')
1246 bias_module_file.write(bias_module[1])
1247 bias_module_file.close()
1248 bias_module_make_file=open(bias_module_newpath+
'/Makefile',
'w')
1249 bias_module_make_file.write(bias_module[2])
1250 bias_module_make_file.close()
1252 mglog.info(
'Using bias module '+bias_module)
1253 bias_module_name=bias_module.split(
'/')[-1].
replace(
'.gz',
'')
1254 bias_module_name=bias_module_name.replace(
'.tar',
'')
1255 the_run_card = open(run_card,
'r')
1256 for line
in the_run_card:
1257 if 'bias_module' in line
and bias_module_name
not in line:
1258 raise RuntimeError(
'You need to add the bias module '+bias_module_name+
' to the run card to actually run it')
1259 the_run_card.close()
1261 if os.path.exists(bias_module+
'.tar.gz'):
1262 bias_module_path=bias_module+
'.tar.gz'
1263 elif os.path.exists(bias_module+
'.gz'):
1264 bias_module_path=bias_module+
'.gz'
1265 elif os.path.exists(bias_module):
1266 bias_module_path=bias_module
1268 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')
1270 bias_module_newpath=process_dir+
'/Source/BIAS/'+bias_module_path.split(
'/')[-1]
1271 mglog.info(
'Copying bias module into place: '+bias_module_newpath)
1272 shutil.copy(bias_module_path,bias_module_newpath)
1273 mglog.info(
'Unpacking bias module')
1274 if bias_module_newpath.endswith(
'.tar.gz'):
1275 untar =
stack_subprocess([
'tar',
'xvzf',bias_module_newpath,
'--directory='+process_dir+
'/Source/BIAS/'])
1277 elif bias_module_path.endswith(
'.gz'):
1324def update_lhe_file(lhe_file_old,param_card_old=None,lhe_file_new=None,masses={},delete_old_lhe=True):
1325 """Build a new LHE file from an old one and an updated param card.
1326 The masses of some particles can be changed via the masses dictionary. No particles that appear in the events
1327 may have their masses changed.
1328 If the param card is provided, the decay block in the LHE file will be replaced with the one in the param card.
1329 By default, the old LHE file is removed.
1330 If None is provided as a new LHE file name, the new file will replace the old one."""
1332 lhe_file_new_tmp = lhe_file_new
if lhe_file_new
is not None else lhe_file_old+
'.tmp'
1334 if not os.access(lhe_file_old,os.R_OK):
1335 raise RuntimeError(
'Could not access old LHE file at '+str(lhe_file_old)+
'. Please check the file location.')
1337 if param_card_old
is not None:
1338 paramcard = subprocess.Popen([
'get_files',
'-data',param_card_old])
1340 if not os.access(param_card_old,os.R_OK):
1341 raise RuntimeError(
'Could not get param card '+param_card_old)
1343 if os.access(lhe_file_new_tmp,os.R_OK):
1344 raise RuntimeError(
'Old file at'+str(lhe_file_new_tmp)+
' in the current directory. Dont want to clobber it. Please move it first.')
1346 newlhe = open(lhe_file_new_tmp,
'w')
1350 particles_in_events = []
1353 with open(lhe_file_old,
'r')
as fileobject:
1354 for line
in fileobject:
1355 if decayEdit
and '</slha>' not in line:
1357 if decayEdit
and '</slha>' in line:
1359 if line.strip().
upper().startswith(
'BLOCK')
or line.strip().
upper().startswith(
'DECAY')\
1360 and len(line.strip().
split()) > 1:
1361 pos = 0
if line.strip().startswith(
'DECAY')
else 1
1362 blockName = line.strip().
upper().
split()[pos]
1365 if blockName !=
'DECAY' and len(line.strip().
split()) > 0:
1366 akey = line.strip().
split()[0]
1367 elif blockName ==
'DECAY' and len(line.strip().
split()) > 1:
1368 akey = line.strip().
split()[1]
1371 if akey
is not None and blockName ==
'MASS' and akey
in masses:
1372 newlhe.write(
' '+akey+
' '+str(masses[akey])+
' # \n')
1373 mglog.info(
' '+akey+
' '+str(masses[akey])+
' #')
1378 if blockName ==
'DECAY' and param_card_old
is not None:
1380 oldparam = open(param_card_old,
'r')
1382 for old_line
in oldparam.readlines():
1384 if old_line.strip().
upper().startswith(
'DECAY')
and len(old_line.strip().
split()) > 1:
1385 newBlockName = line.strip().
upper().
split()[pos]
1387 newlhe.write(old_line)
1388 elif newBlockName ==
'DECAY':
1390 newlhe.write(old_line)
1398 if not eventRead
and '<event>' in line:
1401 if len(line.split())==11:
1402 aparticle = line.split()[0]
1403 if aparticle
not in particles_in_events:
1404 particles_in_events += [aparticle]
1411 if akey
in particles_in_events:
1412 mglog.error(
'Attempted to change mass of a particle that was in an LHE event! This is not allowed!')
1419 if lhe_file_new
is None:
1420 os.remove(lhe_file_old)
1421 shutil.move(lhe_file_new_tmp,lhe_file_old)
1422 lhe_file_new_tmp = lhe_file_old
1424 elif delete_old_lhe:
1425 os.remove(lhe_file_old)
1427 return lhe_file_new_tmp
1446def modify_param_card(param_card_input=None,param_card_backup=None,process_dir=MADGRAPH_GRIDPACK_LOCATION,params={},output_location=None):
1447 """Build a new param_card.dat from an existing one.
1448 Params should be a dictionary of dictionaries. The first key is the block name, and the second in the param name.
1449 Keys can include MASS (for masses) and DECAY X (for decays of particle X)"""
1453 if param_card_input
is None:
1454 param_card_input=process_dir+
'/Cards/param_card.dat'
1455 elif param_card_input
is not None and not os.access(param_card_input,os.R_OK):
1456 paramcard = subprocess.Popen([
'get_files',
'-data',param_card_input])
1458 if not os.access(param_card_input,os.R_OK):
1459 raise RuntimeError(
'Could not get param card '+param_card_input)
1460 mglog.info(
'Using input param card at '+param_card_input)
1464 for blockName
in list(params.keys()):
1465 paramsUpper[blockName.upper()] = {}
1466 for paramName
in list(params[blockName].keys()):
1467 paramsUpper[blockName.upper()][paramName.upper()] = params[blockName][paramName]
1469 if param_card_backup
is not None:
1470 mglog.info(
'Keeping backup of original param card at '+param_card_backup)
1471 param_card_old = param_card_backup
1473 param_card_old = param_card_input+
'.old_to_be_deleted'
1474 if os.path.isfile(param_card_old):
1475 os.unlink(param_card_old)
1476 os.rename(param_card_input, param_card_old)
1478 oldcard = open(param_card_old,
'r')
1479 param_card_location= process_dir+
'/Cards/param_card.dat' if output_location
is None else output_location
1480 newcard = open(param_card_location,
'w')
1484 for linewithcomment
in oldcard:
1485 line=linewithcomment.split(
'#')[0]
1486 if line.strip().
upper().startswith(
'BLOCK')
or line.strip().
upper().startswith(
'DECAY')\
1487 and len(line.strip().
split()) > 1:
1488 if decayEdit
and blockName ==
'DECAY':
1490 pos = 0
if line.strip().startswith(
'DECAY')
else 1
1491 if blockName==
'MASS' and 'MASS' in paramsUpper:
1493 if "MASS" in doneParams:
1494 leftOvers = [ x
for x
in paramsUpper[
'MASS']
if x
not in doneParams[
'MASS'] ]
1496 leftOvers = [ x
for x
in paramsUpper[
'MASS'] ]
1498 for pdg_id
in leftOvers:
1499 mglog.warning(
'Adding mass line for '+str(pdg_id)+
' = '+str(paramsUpper[
'MASS'][pdg_id])+
' which was not in original param card')
1500 newcard.write(
' '+str(pdg_id)+
' '+str(paramsUpper[
'MASS'][pdg_id])+
'\n')
1501 doneParams[
'MASS'][pdg_id]=
True
1502 if blockName==
'DECAY' and 'DECAY' not in line.strip().
upper()
and 'DECAY' in paramsUpper:
1504 leftOvers = [ x
for x
in paramsUpper[
'DECAY']
if x
not in doneParams[
'DECAY'] ]
1505 for pdg_id
in leftOvers:
1506 mglog.warning(
'Adding decay for pdg id '+str(pdg_id)+
' which was not in the original param card')
1507 newcard.write( paramsUpper[
'DECAY'][pdg_id].
strip()+
'\n' )
1508 doneParams[
'DECAY'][pdg_id]=
True
1509 blockName = line.strip().
upper().
split()[pos]
1514 if blockName !=
'DECAY' and len(line.strip().
split()) > 0:
1517 if len(line.split())==2:
1521 akey = line.upper().
strip()[:line.strip().rfind(
' ')].
strip()
1522 elif blockName ==
'DECAY' and len(line.strip().
split()) > 1:
1523 akey = line.strip().
split()[1]
1525 newcard.write(linewithcomment)
1529 if blockName
not in paramsUpper:
1530 newcard.write(linewithcomment)
1532 blockParams = paramsUpper[blockName]
1538 if '#' in linewithcomment:
1539 stringkey = linewithcomment[linewithcomment.find(
'#')+1:].
strip()
1540 if len(stringkey.split()) > 0:
1541 stringkey = stringkey.split()[0].
upper()
1543 if akey
not in blockParams
and not (stringkey
is not None and stringkey
in blockParams):
1544 newcard.write(linewithcomment)
1547 if akey
in blockParams
and (stringkey
is not None and stringkey
in blockParams):
1548 raise RuntimeError(
'Conflicting use of numeric and string keys '+akey+
' and '+stringkey)
1550 theParam = blockParams.get(akey,blockParams[stringkey]
if stringkey
in blockParams
else None)
1551 if blockName
not in doneParams:
1552 doneParams[blockName] = {}
1553 if akey
in blockParams:
1554 doneParams[blockName][akey]=
True
1555 elif stringkey
is not None and stringkey
in blockParams:
1556 doneParams[blockName][stringkey]=
True
1559 if blockName==
"DECAY":
1560 if theParam.splitlines()[0].
split()[0].
upper()==
"DECAY":
1562 for newline
in theParam.splitlines():
1563 newcard.write(newline+
'\n')
1567 newcard.write(
'DECAY '+akey+
' '+str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].
strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1568 mglog.info(
'DECAY '+akey+
' '+str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].
strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1570 elif blockName==
'QNUMBERS':
1572 for newline
in theParam.splitlines():
1573 newcard.write(newline+
'\n')
1577 newcard.write(
' '+akey+
' '+str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].
strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1578 mglog.info(
' '+akey+
' '+str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].
strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1582 for blockName
in paramsUpper:
1583 if blockName
not in doneParams
and len(paramsUpper[blockName].keys())>0:
1584 raise RuntimeError(
'Did not find any of the parameters for block '+blockName+
' in param_card')
1585 for paramName
in paramsUpper[blockName]:
1586 if paramName
not in doneParams[blockName]:
1587 raise RuntimeError(
'Was not able to replace parameter '+paramName+
' in param_card')
1659def modify_run_card(run_card_input=None,run_card_backup=None,process_dir=MADGRAPH_GRIDPACK_LOCATION,runArgs=None,settings={},skipBaseFragment=False):
1660 """Build a new run_card.dat from an existing one.
1661 This function can get a fresh runcard from DATAPATH or start from the process directory.
1662 Settings is a dictionary of keys (no spaces needed) and values to replace.
1667 for s
in list(settings.keys()):
1668 settings_lower[s.lower()] = settings[s]
1671 if run_card_input
is None:
1673 elif run_card_input
is not None and not os.access(run_card_input,os.R_OK):
1674 runcard = subprocess.Popen([
'get_files',
'-data',run_card_input])
1676 if not os.access(run_card_input,os.R_OK):
1677 raise RuntimeError(
'Could not get run card '+run_card_input)
1680 isNLO=is_NLO_run(process_dir=process_dir)
1682 if not skipBaseFragment:
1683 MadGraphControl.MadGraphSystematicsUtils.setup_pdf_and_systematic_weights(MADGRAPH_PDFSETTING,settings_lower,isNLO)
1686 if runArgs
is not None:
1687 beamEnergy,rand_seed = get_runArgs_info(runArgs)
1688 if 'iseed' not in settings_lower:
1689 settings_lower[
'iseed']=rand_seed
1690 if not isNLO
and 'python_seed' not in settings_lower:
1691 settings_lower[
'python_seed']=rand_seed
1692 if 'beamenergy' in settings_lower:
1693 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']))
1694 beamEnergy=settings_lower[
'beamenergy']
1695 settings_lower.pop(
'beamenergy')
1696 if 'ebeam1' not in settings_lower:
1697 settings_lower[
'ebeam1']=beamEnergy
1698 if 'ebeam2' not in settings_lower:
1699 settings_lower[
'ebeam2']=beamEnergy
1701 if 'nevents' in settings_lower:
1702 settings_lower[
'nevents'] = int(settings_lower[
'nevents'])
1705 if 'custom_fcts' in settings_lower
and settings_lower[
'custom_fcts']:
1706 raw_name = str(settings_lower[
'custom_fcts']).
split()[0]
1708 if runArgs
is not None and hasattr(runArgs,
'jobConfig'):
1709 cfgdir = runArgs.jobConfig[0]
if isinstance(runArgs.jobConfig, (list, tuple))
else runArgs.jobConfig
1711 full_path = os.path.join(cfgdir, raw_name)
1712 settings_lower[
'custom_fcts'] = os.path.abspath(full_path)
1713 print(f
"Using custom function(s), specified in custom_fcts with path: {settings_lower['custom_fcts']}")
1716 settings_lower[
'custom_fcts'] = os.path.abspath(raw_name)
1718 mglog.info(
'Modifying run card located at '+run_card_input)
1719 if run_card_backup
is not None:
1720 mglog.info(
'Keeping backup of original run card at '+run_card_backup)
1721 run_card_old = run_card_backup
1723 run_card_old = run_card_input+
'.old_to_be_deleted'
1724 mglog.debug(
'Modifying runcard settings: '+str(settings_lower))
1725 if os.path.isfile(run_card_old):
1726 os.unlink(run_card_old)
1727 os.rename(run_card_input, run_card_old)
1729 oldCard = open(run_card_old,
'r')
1730 newCard = open(process_dir+
'/Cards/run_card.dat',
'w')
1732 for line
in iter(oldCard):
1733 if not line.strip().startswith(
'#'):
1734 command = line.split(
'!', 1)[0]
1735 comment = line.split(
'!', 1)[1]
if '!' in line
else ''
1737 setting = command.split(
'=')[-1]
1738 stripped_setting = setting.strip()
1739 oldValue =
'='.join(command.split(
'=')[:-1])
1740 if stripped_setting.lower()
in settings_lower:
1742 if settings_lower[stripped_setting.lower()]
is None:
1744 mglog.info(
'Removing '+stripped_setting+
'.')
1745 used_settings += [ stripped_setting.lower() ]
1747 if stripped_setting.lower() ==
'custom_fcts':
1749 line =
' '+str(settings_lower[stripped_setting.lower()])+
' = '+setting
1751 line +=
' !'+comment
1753 line = oldValue.replace(oldValue.strip(), str(settings_lower[stripped_setting.lower()]))+
'='+setting
1755 line +=
' !' + comment
1756 mglog.info(
'Setting '+stripped_setting+
' = '+str(settings_lower[stripped_setting.lower()]))
1757 used_settings += [ stripped_setting.lower() ]
1758 newCard.write(line.strip()+
'\n')
1761 if 'mcatnlo_delta' in settings_lower:
1762 if settings_lower[
'mcatnlo_delta'] ==
'True':
1763 modify_config_card(process_dir=process_dir,settings={
'pythia8_path':os.getenv(
"PY8PATH")})
1766 for asetting
in settings_lower:
1767 if asetting
in used_settings:
1769 if settings_lower[asetting]
is None:
1771 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]) )
1772 newCard.write(
' '+str(settings_lower[asetting])+
' = '+str(asetting)+
'\n')
1776 mglog.info(
'Finished modification of run card.')
1777 if run_card_backup
is None:
1778 os.unlink(run_card_old)
1851 cardpath=process_dir+
'/Cards/run_card.dat'
1852 mydict=getDictFromCard(cardpath)
1855 if checkSetting(
'event_norm',
'sum',mydict):
1856 modify_run_card(process_dir=process_dir,settings={
'event_norm':
'average'},skipBaseFragment=
True)
1857 mglog.warning(
"setting event_norm to average, there is basically no use case where event_norm=sum is a good idea")
1861 if 'ktdurham' in mydict
and float(mydict[
'ktdurham']) > 0
and int(mydict[
'ickkw']) != 0:
1862 log=
'Bad combination of settings for CKKW-L merging! ktdurham=%s and ickkw=%s.'%(mydict[
'ktdurham'],mydict[
'ickkw'])
1864 raise RuntimeError(log)
1867 if 'systematics_program' not in mydict
or mydict[
'systematics_program']==
'systematics':
1868 syscalc_settings=[
'sys_pdf',
'sys_scalefact',
'sys_alpsfact',
'sys_matchscale']
1869 found_syscalc_setting=
False
1870 for s
in syscalc_settings:
1872 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)')
1873 found_syscalc_setting=
True
1874 if found_syscalc_setting:
1875 syst_arguments=MadGraphControl.MadGraphSystematicsUtils.convertSysCalcArguments(mydict)
1876 mglog.info(
'Converted syscalc arguments to systematics arguments: '+syst_arguments)
1877 syst_settings_update={
'systematics_arguments':syst_arguments}
1878 for s
in syscalc_settings:
1879 syst_settings_update[s]=
None
1880 modify_run_card(process_dir=process_dir,settings=syst_settings_update,skipBaseFragment=
True)
1885 mglog.info(
'Checking PDF and systematics settings')
1886 if not MadGraphControl.MadGraphSystematicsUtils.base_fragment_setup_check(MADGRAPH_PDFSETTING,mydict,isNLO):
1888 syst_settings=MadGraphControl.MadGraphSystematicsUtils.get_pdf_and_systematic_settings(MADGRAPH_PDFSETTING,isNLO)
1889 modify_run_card(process_dir=process_dir,settings=syst_settings,skipBaseFragment=
True)
1891 mydict_new=getDictFromCard(cardpath)
1892 if 'systematics_arguments' in mydict_new:
1893 systematics_arguments=MadGraphControl.MadGraphSystematicsUtils.parse_systematics_arguments(mydict_new[
'systematics_arguments'])
1894 if 'weight_info' not in systematics_arguments:
1895 mglog.info(
'Enforcing systematic weight name convention')
1897 if '--dyn' in systematics_arguments
or ' dyn' in systematics_arguments:
1898 if '--dyn' in systematics_arguments:
1899 dyn = systematics_arguments.split(
'--dyn')[1]
1900 if ' dyn' in systematics_arguments:
1901 dyn = systematics_arguments.split(
' dyn')[1]
1902 dyn = dyn.replace(
'\'',
' ').
replace(
'=',
' ').
split()[0]
1903 if dyn
is not None and len(dyn.split(
','))>1:
1904 systematics_arguments[
'weight_info']=MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO_ALTDYNSCALES
1906 systematics_arguments[
'weight_info']=MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO
1907 modify_run_card(process_dir=process_dir,settings={
'systematics_arguments':MadGraphControl.MadGraphSystematicsUtils.write_systematics_arguments(systematics_arguments)},skipBaseFragment=
True)
1910 if 'python_seed' not in mydict:
1911 mglog.warning(
'No python seed set in run_card -- adding one with same value as iseed')
1912 modify_run_card(process_dir=process_dir,settings={
'python_seed':mydict[
'iseed']},skipBaseFragment=
True)
1916 proton_5flav =
False
1918 with open(process_dir+
'/Cards/proc_card_mg5.dat',
'r')
as file:
1919 content = file.readlines()
1920 for rawline
in content:
1921 line = rawline.split(
'#')[0]
1922 if line.startswith(
"define p"):
1923 if (
'b' in line.split()
and 'b~' in line.split())
or (
'5' in line.split()
and '-5' in line.split()):
1925 if 'j' in line.split()
and jet_5flav:
1927 if line.startswith(
"define j"):
1928 if (
'b' in line.split()
and 'b~' in line.split())
or (
'5' in line.split()
and '-5' in line.split()):
1930 if 'p' in line.split()
and proton_5flav:
1932 if proton_5flav
or jet_5flav:
1933 FS_updates[
'asrwgtflavor'] = 5
1934 if not proton_5flav:
1935 mglog.warning(
'Found 5-flavour jets but 4-flavour proton. This is inconsistent - please pick one.')
1936 mglog.warning(
'Will proceed assuming 5-flavour scheme.')
1938 mglog.warning(
'Found 5-flavour protons but 4-flavour jets. This is inconsistent - please pick one.')
1939 mglog.warning(
'Will proceed assuming 5-flavour scheme.')
1941 FS_updates[
'asrwgtflavor'] = 4
1943 if len(FS_updates)==0:
1944 mglog.warning(f
'Could not identify 4- or 5-flavor scheme from process card {process_dir}/Cards/proc_card_mg5.dat')
1946 if 'asrwgtflavor' in mydict
or 'maxjetflavor' in mydict
or 'pdgs_for_merging_cut' in mydict:
1947 if FS_updates[
'asrwgtflavor'] == 5:
1949 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']):
1951 mglog.warning(
'b and b~ included in p and j for 5-flavor scheme but run card settings are inconsistent; adjusting run card')
1952 run_card_updates = {
'asrwgtflavor': 5,
'maxjetflavor': 5,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 5, 21'}
1953 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1954 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'0.000000e+00'}})
1956 mglog.debug(
'Consistent 5-flavor scheme setup detected.')
1957 if FS_updates[
'asrwgtflavor'] == 4:
1959 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']):
1961 mglog.warning(
'b and b~ not included in p and j (4-flavor scheme) but run card settings are inconsistent; adjusting run card')
1962 run_card_updates = {
'asrwgtflavor': 4,
'maxjetflavor': 4,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 21'}
1963 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1964 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'4.700000e+00'}})
1966 mglog.debug(
'Consistent 4-flavor scheme setup detected.')
1969 if FS_updates[
'asrwgtflavor'] == 4:
1971 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.')
1972 run_card_updates = {
'asrwgtflavor': 4,
'maxjetflavor': 4,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 21'}
1973 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1974 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'4.700000e+00'}})
1975 elif FS_updates[
'asrwgtflavor'] == 5:
1976 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.')
1977 run_card_updates = {
'asrwgtflavor': 5,
'maxjetflavor': 5,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 5, 21'}
1978 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1979 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'0.000000e+00'}})
1981 mglog.info(
'Finished checking run card - All OK!')