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 -' ]
267 energy =
'%1.1f'%(beamEnergy*2./1000.)
268 energy = energy.replace(
'.0',
'').
replace(
'.',
'p')
269 gridpack_name=
'mc_'+energy+
'TeV.'+get_physics_short()+
'.MG'+get_mg5_version().
replace(
'.',
'')+
'.GRID.tar.gz'
270 mglog.info(
'Tidying up gridpack '+gridpack_name)
273 modify_run_card(process_dir=process_dir,settings={
'systematics_program':original_systematics_program})
278 MADGRAPH_COMMAND_STACK += [f
'mv {process_dir}/Cards/madspin_card.tmp.dat {process_dir}/Cards/madspin_card.dat']
279 os.rename(f
'{process_dir}/Cards/madspin_card.tmp.dat',f
'{process_dir}/Cards/madspin_card.dat')
282 MADGRAPH_COMMAND_STACK += [
'cp '+glob.glob(process_dir+
'/'+MADGRAPH_RUN_NAME+
'_*gridpack.tar.gz')[0]+
' '+gridpack_name]
283 shutil.copy(glob.glob(process_dir+
'/'+MADGRAPH_RUN_NAME+
'_*gridpack.tar.gz')[0],gridpack_name)
286 MADGRAPH_COMMAND_STACK += [
'mkdir tmp%i/'%os.getpid(),
'cd tmp%i/'%os.getpid()]
287 os.mkdir(
'tmp%i/'%os.getpid())
288 os.chdir(
'tmp%i/'%os.getpid())
289 mglog.info(
'untar gridpack')
292 mglog.info(
'compile and clean up')
293 MADGRAPH_COMMAND_STACK += [
'cd madevent']
294 os.chdir(
'madevent/')
295 compilep =
stack_subprocess([
'./bin/compile'],stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
296 (out,err) = compilep.communicate()
297 error_check(err,compilep.returncode)
298 clean =
stack_subprocess([
'./bin/clean4grid'],stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
299 (out,err) = clean.communicate()
300 error_check(err,clean.returncode)
302 MADGRAPH_COMMAND_STACK += [
'cd ..',
'rm ../'+gridpack_name]
304 mglog.info(
'remove old tarball')
305 os.unlink(
'../'+gridpack_name)
306 mglog.info(
'Package up new tarball')
307 tar =
stack_subprocess([
'tar',
'--exclude=SubProcesses/P*/G*/*_results.dat',
'--exclude=SubProcesses/P*/G*/*.log',
'--exclude=SubProcesses/P*/G*/*.txt',
'-cvsf',
'../'+gridpack_name,
'.'])
309 MADGRAPH_COMMAND_STACK += [
'cd ..',
'rm -r tmp%i/'%os.getpid()]
311 mglog.info(
'Remove temporary directory')
312 shutil.rmtree(
'tmp%i/'%os.getpid())
313 mglog.info(
'Tidying up complete!')
318 mglog.info(
'Package up process_dir')
319 MADGRAPH_COMMAND_STACK += [
'mv '+process_dir+
' '+MADGRAPH_GRIDPACK_LOCATION]
320 os.rename(process_dir,MADGRAPH_GRIDPACK_LOCATION)
321 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])
323 MADGRAPH_COMMAND_STACK += [
'mv '+MADGRAPH_GRIDPACK_LOCATION+
' '+process_dir]
324 os.rename(MADGRAPH_GRIDPACK_LOCATION,process_dir)
326 mglog.info(
'Gridpack sucessfully created, exiting the transform')
327 if hasattr(runArgs,
'outputTXTFile'):
328 mglog.info(
'Touching output TXT (LHE) file for the transform')
329 open(runArgs.outputTXTFile,
'w').close()
330 from AthenaCommon.AppMgr
import theApp
334 mglog.info(
'Finished at '+str(time.asctime()))
340 beamEnergy,random_seed = get_runArgs_info(runArgs)
343 setup_path_protection()
345 isNLO=is_NLO_run(process_dir=MADGRAPH_GRIDPACK_LOCATION)
350 gridpack_run_name =
'GridRun_'+str(random_seed)
353 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/madspin_card.dat',os.R_OK):
354 os.rename(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/madspin_card.dat',MADGRAPH_GRIDPACK_LOCATION+
'/Cards/backup_madspin_card.dat')
363 code = check_PMG_updates(process_dir=MADGRAPH_GRIDPACK_LOCATION)
364 if requirePMGSettings
and code!=0:
365 raise RuntimeError(
'Settings are not compliant with PMG defaults! Please use do_PMG_updates function to get PMG default params.')
368 settings={
'iseed':str(random_seed)}
370 settings[
'python_seed']=str(random_seed)
371 modify_run_card(process_dir=MADGRAPH_GRIDPACK_LOCATION,settings=settings,skipBaseFragment=
True)
373 mglog.info(
'Generating events from gridpack')
376 if not os.path.exists(MADGRAPH_GRIDPACK_LOCATION):
377 raise RuntimeError(
'Gridpack directory not found at '+MADGRAPH_GRIDPACK_LOCATION)
379 nevents = getDictFromCard(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/run_card.dat')[
'nevents']
380 mglog.info(
'>>>> FOUND GRIDPACK <<<< <- This will be used for generation')
381 mglog.info(
'Generation of '+str(int(nevents))+
' events will be performed using the supplied gridpack with random seed '+str(random_seed))
382 mglog.info(
'Started generating events at '+str(time.asctime()))
385 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/bin/internal/addmasses.py',os.R_OK):
386 os.remove(MADGRAPH_GRIDPACK_LOCATION+
'/bin/internal/addmasses.py')
391 setNCores(process_dir=MADGRAPH_GRIDPACK_LOCATION)
395 ls_dir(MADGRAPH_GRIDPACK_LOCATION)
405 run_card_dict=getDictFromCard(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/run_card.dat')
406 systematics_settings=
None
407 if checkSetting(
'systematics_program',
'systematics',run_card_dict):
408 if not checkSettingIsTrue(
'store_rwgt_info',run_card_dict):
409 raise RuntimeError(
'Trying to run NLO systematics but reweight info not stored')
410 if checkSettingExists(
'systematics_arguments',run_card_dict):
411 systematics_settings=MadGraphControl.MadGraphSystematicsUtils.parse_systematics_arguments(run_card_dict[
'systematics_arguments'])
413 systematics_settings={}
414 mglog.info(
'Turning off systematics for now, running standalone later')
415 modify_run_card(process_dir=MADGRAPH_GRIDPACK_LOCATION,settings={
'systematics_program':
'none'},skipBaseFragment=
True)
417 global MADGRAPH_COMMAND_STACK
420 if not os.access(MADGRAPH_GRIDPACK_LOCATION+
'/bin/gridrun',os.R_OK):
421 mglog.error(
'/bin/gridrun not found at '+MADGRAPH_GRIDPACK_LOCATION)
422 raise RuntimeError(
'Could not find gridrun executable')
424 mglog.info(
'Found '+MADGRAPH_GRIDPACK_LOCATION+
'/bin/gridrun, starting generation.')
427 mglog.info(
"Now generating {} events with random seed {} and granularity {}".format(int(nevents),int(random_seed),granularity))
429 new_ld_path=
":".join([os.environ[
'LD_LIBRARY_PATH'],os.getcwd()+
'/'+MADGRAPH_GRIDPACK_LOCATION+
'/madevent/lib',os.getcwd()+
'/'+MADGRAPH_GRIDPACK_LOCATION+
'/HELAS/lib'])
430 os.environ[
'LD_LIBRARY_PATH']=new_ld_path
431 MADGRAPH_COMMAND_STACK+=[
"export LD_LIBRARY_PATH="+
":".join([
'${LD_LIBRARY_PATH}',new_ld_path])]
432 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)
433 (out,err) = generate.communicate()
434 error_check(err,generate.returncode)
435 gp_events=MADGRAPH_GRIDPACK_LOCATION+
"/Events/GridRun_{}/unweighted_events.lhe.gz".format(int(random_seed))
436 if not os.path.exists(gp_events):
437 mglog.error(
'Error in gp generation, did not find events at '+gp_events)
441 if reweight_card
is not None:
442 pythonpath_backup=os.environ[
'PYTHONPATH']
444 os.environ[
'PYTHONPATH']=
':'.join([p
for p
in pythonpath_backup.split(
':')
if 'madgraph5amc' not in p])
446 os.environ[
'PYTHONPATH']=pythonpath_backup
448 shutil.move(gp_events,
'events.lhe.gz')
452 if not os.access(MADGRAPH_GRIDPACK_LOCATION+
'/bin/generate_events',os.R_OK):
453 raise RuntimeError(
'Could not find generate_events executable at '+MADGRAPH_GRIDPACK_LOCATION)
455 mglog.info(
'Found '+MADGRAPH_GRIDPACK_LOCATION+
'/bin/generate_events, starting generation.')
457 ls_dir(MADGRAPH_GRIDPACK_LOCATION+
'/Events/')
458 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name, os.F_OK):
459 mglog.info(
'Removing '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
' directory from gridpack generation')
460 MADGRAPH_COMMAND_STACK += [
'rm -rf '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name]
461 shutil.rmtree(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name)
464 if os.access(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1', os.F_OK):
465 mglog.info(
'Removing '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1 directory from gridpack generation')
466 MADGRAPH_COMMAND_STACK += [
'rm -rf '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1']
467 shutil.rmtree(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'_decayed_1')
469 ls_dir(MADGRAPH_GRIDPACK_LOCATION+
'/Events/')
471 if not gridpack_compile:
472 mglog.info(
'Copying make_opts from Template')
473 shutil.copy(os.environ[
'MADPATH']+
'/Template/LO/Source/make_opts',MADGRAPH_GRIDPACK_LOCATION+
'/Source/')
476 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)
477 (out,err) = generate.communicate()
478 error_check(err,generate.returncode)
480 mglog.info(
'Allowing recompilation of gridpack')
481 if os.path.islink(MADGRAPH_GRIDPACK_LOCATION+
'/lib/libLHAPDF.a'):
482 mglog.info(
'Unlinking '+MADGRAPH_GRIDPACK_LOCATION+
'/lib/libLHAPDF.a')
483 os.unlink(MADGRAPH_GRIDPACK_LOCATION+
'/lib/libLHAPDF.a')
486 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)
487 (out,err) = generate.communicate()
488 error_check(err,generate.returncode)
489 if isNLO
and systematics_settings
is not None:
491 mglog.info(
'Running systematics standalone')
492 systematics_path=MADGRAPH_GRIDPACK_LOCATION+
'/bin/internal/systematics.py'
493 events_location=MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/events.lhe.gz'
494 syst_cmd=[python,systematics_path]+[events_location]*2+[
"--"+k+
"="+systematics_settings[k]
for k
in systematics_settings]
495 mglog.info(
'running: '+
' '.join(syst_cmd))
501 if not os.access(
'events.lhe.gz',os.R_OK):
502 mglog.info(
'Copying generated events to '+currdir)
503 if not os.path.exists(MADGRAPH_GRIDPACK_LOCATION+
'Events/'+gridpack_run_name):
504 shutil.copy(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/events.lhe.gz',
'events.lhe.gz')
506 mglog.info(
'Events were already in place')
510 mglog.info(
'Moving generated events to be in correct format for arrange_output().')
511 mglog.info(
'Unzipping generated events.')
515 mglog.info(
'Moving file over to '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe')
516 mkdir =
stack_subprocess([
'mkdir',
'-p',(MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name)])
518 shutil.move(
'events.lhe',MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe')
520 mglog.info(
'Re-zipping into dataset name '+MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe.gz')
521 rezip =
stack_subprocess([
'gzip',MADGRAPH_GRIDPACK_LOCATION+
'/Events/'+gridpack_run_name+
'/unweighted_events.lhe'])
529 os.rename(MADGRAPH_GRIDPACK_LOCATION+
'/Cards/backup_madspin_card.dat',MADGRAPH_GRIDPACK_LOCATION+
'/Cards/madspin_card.dat')
530 mglog.info(
'Decaying with MadSpin.')
531 add_madspin(process_dir=MADGRAPH_GRIDPACK_LOCATION)
533 mglog.info(
'Finished at '+str(time.asctime()))
570def setupLHAPDF(process_dir=None, extlhapath=None, allow_links=True):
571 isNLO=is_NLO_run(process_dir=process_dir)
573 origLHAPATH=os.environ[
'LHAPATH']
574 origLHAPDF_DATA_PATH=os.environ[
'LHAPDF_DATA_PATH']
576 LHAPATH,LHADATAPATH=get_LHAPDF_PATHS()
582 run_card=process_dir+
'/Cards/run_card.dat'
583 mydict=getDictFromCard(run_card)
585 if mydict[
"pdlabel"].
replace(
"'",
"") ==
'lhapdf':
587 mglog.info(
'creating local LHAPDF dir: MGC_LHAPDF/')
588 if os.path.islink(
'MGC_LHAPDF/'):
589 os.unlink(
'MGC_LHAPDF/')
590 elif os.path.isdir(
'MGC_LHAPDF/'):
591 shutil.rmtree(
'MGC_LHAPDF/')
593 newMGCLHA=
'MGC_LHAPDF/'
595 mkdir = subprocess.Popen([
'mkdir',
'-p',newMGCLHA])
598 pdfs_used=[ int(x)
for x
in mydict[
'lhaid'].
replace(
' ',
',').
split(
',') ]
600 if 'sys_pdf' in mydict:
606 pdfs_used.append(idx)
609 if 'systematics_arguments' in mydict:
610 systematics_arguments=MadGraphControl.MadGraphSystematicsUtils.parse_systematics_arguments(mydict[
'systematics_arguments'])
611 if 'pdf' in systematics_arguments:
617 pdfs_used.append(idx)
620 for pdf
in pdfs_used:
621 if isinstance(pdf,str)
and (pdf.lower()==
'errorset' or pdf.lower()==
'central'):
624 pdfid,pdfname=get_lhapdf_id_and_name(pdf)
625 mglog.info(
"Found LHAPDF ID="+str(pdfid)+
", name="+pdfname)
627 if not os.path.exists(newMGCLHA+pdfname)
and not os.path.lexists(newMGCLHA+pdfname):
628 if not os.path.exists(LHADATAPATH+
'/'+pdfname):
629 mglog.warning(
'PDF not installed at '+LHADATAPATH+
'/'+pdfname)
631 mglog.info(
'linking '+LHADATAPATH+
'/'+pdfname+
' --> '+newMGCLHA+pdfname)
632 os.symlink(LHADATAPATH+
'/'+pdfname,newMGCLHA+pdfname)
634 mglog.info(
'copying '+LHADATAPATH+
'/'+pdfname+
' --> '+newMGCLHA+pdfname)
635 shutil.copytree(LHADATAPATH+
'/'+pdfname,newMGCLHA+pdfname)
638 mglog.info(
'linking '+LHADATAPATH+
'/pdfsets.index --> '+newMGCLHA+
'pdfsets.index')
639 os.symlink(LHADATAPATH+
'/pdfsets.index',newMGCLHA+
'pdfsets.index')
641 atlasLHADATAPATH=LHADATAPATH.replace(
'sft.cern.ch/lcg/external/lhapdfsets/current',
'atlas.cern.ch/repo/sw/Generators/lhapdfsets/current')
642 mglog.info(
'linking '+atlasLHADATAPATH+
'/lhapdf.conf --> '+newMGCLHA+
'lhapdf.conf')
643 os.symlink(atlasLHADATAPATH+
'/lhapdf.conf',newMGCLHA+
'lhapdf.conf')
645 mglog.info(
'copying '+LHADATAPATH+
'/pdfsets.index --> '+newMGCLHA+
'pdfsets.index')
646 shutil.copy2(LHADATAPATH+
'/pdfsets.index',newMGCLHA+
'pdfsets.index')
648 atlasLHADATAPATH=LHADATAPATH.replace(
'sft.cern.ch/lcg/external/lhapdfsets/current',
'atlas.cern.ch/repo/sw/Generators/lhapdfsets/current')
649 mglog.info(
'copying '+atlasLHADATAPATH+
'/lhapdf.conf -->'+newMGCLHA+
'lhapdf.conf')
650 shutil.copy2(atlasLHADATAPATH+
'/lhapdf.conf',newMGCLHA+
'lhapdf.conf')
653 LHADATAPATH=os.getcwd()+
'/MGC_LHAPDF'
656 mglog.info(
'Not using LHAPDF')
657 return (LHAPATH,origLHAPATH,origLHAPDF_DATA_PATH)
661 os.environ[
'LHAPDF_DATA_PATH']=LHADATAPATH
663 mglog.info(
'Path to LHAPDF install dir: '+LHAPATH)
664 mglog.info(
'Path to LHAPDF data dir: '+LHADATAPATH)
665 if not os.path.isdir(LHADATAPATH):
666 raise RuntimeError(
'LHAPDF data dir not accesible: '+LHADATAPATH)
667 if not os.path.isdir(LHAPATH):
668 raise RuntimeError(
'LHAPDF path dir not accesible: '+LHAPATH)
672 lhapdfconfig=extlhapath
673 if not os.access(lhapdfconfig,os.X_OK):
674 raise RuntimeError(
'Failed to find valid external lhapdf-config at '+lhapdfconfig)
675 LHADATAPATH=subprocess.Popen([lhapdfconfig,
'--datadir'],stdout = subprocess.PIPE).stdout.read().
strip()
676 mglog.info(
'Changing LHAPDF_DATA_PATH to '+LHADATAPATH)
677 os.environ[
'LHAPDF_DATA_PATH']=LHADATAPATH
679 getlhaconfig = subprocess.Popen([
'get_files',
'-data',
'lhapdf-config'])
682 if not os.access(os.getcwd()+
'/lhapdf-config',os.X_OK):
683 mglog.error(
'Failed to get lhapdf-config from MadGraphControl')
685 lhapdfconfig = os.getcwd()+
'/lhapdf-config'
687 mglog.info(
'lhapdf-config --version: '+str(subprocess.Popen([lhapdfconfig,
'--version'],stdout = subprocess.PIPE).stdout.read().
strip()))
688 mglog.info(
'lhapdf-config --prefix: '+str(subprocess.Popen([lhapdfconfig,
'--prefix'],stdout = subprocess.PIPE).stdout.read().
strip()))
689 mglog.info(
'lhapdf-config --libdir: '+str(subprocess.Popen([lhapdfconfig,
'--libdir'],stdout = subprocess.PIPE).stdout.read().
strip()))
690 mglog.info(
'lhapdf-config --datadir: '+str(subprocess.Popen([lhapdfconfig,
'--datadir'],stdout = subprocess.PIPE).stdout.read().
strip()))
691 mglog.info(
'lhapdf-config --pdfsets-path: '+str(subprocess.Popen([lhapdfconfig,
'--pdfsets-path'],stdout = subprocess.PIPE).stdout.read().
strip()))
693 modify_config_card(process_dir=process_dir,settings={
'lhapdf':lhapdfconfig,
'lhapdf_py3':lhapdfconfig})
695 mglog.info(
'Creating links for LHAPDF')
696 if os.path.islink(process_dir+
'/lib/PDFsets'):
697 os.unlink(process_dir+
'/lib/PDFsets')
698 elif os.path.isdir(process_dir+
'/lib/PDFsets'):
699 shutil.rmtree(process_dir+
'/lib/PDFsets')
701 os.symlink(LHADATAPATH,process_dir+
'/lib/PDFsets')
703 shutil.copytree(LHADATAPATH,process_dir+
'/lib/PDFsets')
704 mglog.info(
'Available PDFs are:')
705 mglog.info( sorted( [ x
for x
in os.listdir(process_dir+
'/lib/PDFsets')
if ".tar.gz" not in x ] ) )
707 global MADGRAPH_COMMAND_STACK
708 MADGRAPH_COMMAND_STACK += [
'# Copy the LHAPDF files locally' ]
709 MADGRAPH_COMMAND_STACK += [
'cp -r '+os.getcwd()+
'/MGC_LHAPDF .' ]
710 MADGRAPH_COMMAND_STACK += [
'cp -r '+process_dir+
'/lib/PDFsets ${MGaMC_PROCESS_DIR}/lib/' ]
712 return (LHAPATH,origLHAPATH,origLHAPDF_DATA_PATH)
837 """ Run MadSpin on an input LHE file. Takes the process
838 from the LHE file, so you don't need to have a process directory
839 set up in advance. Runs MadSpin and packs the LHE file up appropriately
840 Needs runArgs for the file handling"""
841 if not os.access(input_LHE,os.R_OK):
842 raise RuntimeError(
'Could not find LHE file '+input_LHE)
843 if not os.access(madspin_card,os.R_OK):
844 raise RuntimeError(
'Could not find input MadSpin card '+madspin_card)
846 shutil.copy(input_LHE,input_LHE+
'.original')
847 mglog.info(
'Put backup copy of LHE file at '+input_LHE+
'.original')
849 madspin_exec_card = open(
'madspin_exec_card',
'w')
850 madspin_exec_card.write(
'import '+input_LHE+
'\n')
852 input_madspin_card = open(madspin_card,
'r')
854 for l
in input_madspin_card.readlines():
855 commands = l.split(
'#')[0].
split()
857 if len(commands)>1
and 'import'==commands[0]
and not 'model'==commands[1]:
860 if len(commands)>0
and 'launch' == commands[0]:
862 madspin_exec_card.write(l.strip()+
'\n')
864 madspin_exec_card.write(
'launch\n')
865 madspin_exec_card.close()
866 input_madspin_card.close()
868 madpath=os.environ[
'MADPATH']
869 if not os.access(madpath+
'/MadSpin/madspin',os.R_OK):
870 raise RuntimeError(
'madspin executable not found in '+madpath)
871 mglog.info(
'Starting madspin at '+str(time.asctime()))
872 generate =
stack_subprocess([python,madpath+
'/MadSpin/madspin',
'madspin_exec_card'],stdin=subprocess.PIPE,stderr=subprocess.PIPE
if MADGRAPH_CATCH_ERRORS
else None)
873 (out,err) = generate.communicate()
874 error_check(err,generate.returncode)
875 mglog.info(
'Done with madspin at '+str(time.asctime()))
879 if os.path.exists(os.getcwd()+
'/events.lhe'):
880 os.remove(os.getcwd()+
'/events.lhe')
882 mglog.info(
'Unzipping generated events.')
886 mglog.info(
'Putting a copy in place for the transform.')
887 mod_output = open(os.getcwd()+
'/events.lhe',
'w')
891 with open(input_LHE,
'r')
as fileobject:
892 for line
in fileobject:
894 mod_output.write(line)
899 mglog.info(
'Removed '+str(nEmpty)+
' empty lines from LHEF')
903 raise RuntimeError(
'Must provide runArgs to madspin_on_lhe')
905 outputDS = runArgs.outputTXTFile
if hasattr(runArgs,
'outputTXTFile')
else 'tmp_LHE_events.tar.gz'
907 mglog.info(
'Moving file over to '+outputDS.split(
'.tar.gz')[0]+
'.events')
908 shutil.move(os.getcwd()+
'/events.lhe',outputDS.split(
'.tar.gz')[0]+
'.events')
910 mglog.info(
'Re-zipping into dataset name '+outputDS)
911 rezip =
stack_subprocess([
'tar',
'cvzf',outputDS,outputDS.split(
'.tar.gz')[0]+
'.events'])
915 if hasattr(runArgs,
'outputTXTFile')
and runArgs.outputTXTFile
is not None:
916 outputDS = outputDS.split(
'.TXT')[0]
918 if runArgs
is not None:
919 mglog.debug(
'Setting inputGenerator file to '+outputDS)
920 runArgs.inputGeneratorFile=outputDS
923def arrange_output(process_dir=MADGRAPH_GRIDPACK_LOCATION,lhe_version=None,saveProcDir=False,runArgs=None,fixEventWeightsForBridgeMode=False):
928 if len(glob.glob(os.path.join(process_dir,
'Events',
'*')))<1:
929 mglog.error(
'Process dir '+process_dir+
' does not contain events?')
930 proc_dir_list = glob.glob(os.path.join(process_dir,
'Events',
'*'))
933 for adir
in proc_dir_list:
934 if 'decayed' in adir:
937 if 'GridRun_' in adir:
940 elif os.path.join(process_dir,
'Events',MADGRAPH_RUN_NAME)
in adir:
942 if not os.access(this_run_name,os.R_OK):
943 raise RuntimeError(
'Unable to locate run directory')
945 hasUnweighted = os.access(this_run_name+
'/unweighted_events.lhe.gz',os.R_OK)
948 madspinDirs=sorted(glob.glob(this_run_name+
'_decayed_*/'))
951 if hasRunMadSpin
and not hasUnweighted:
953 hasUnweighted = os.access(madspinDirs[-1]+
'/unweighted_events.lhe.gz',os.R_OK)
955 global MADGRAPH_COMMAND_STACK
964 if os.path.exists(madspinDirs[-1]+
'/unweighted_events.lhe.gz'):
965 MADGRAPH_COMMAND_STACK += [
'mv '+madspinDirs[-1]+
'/unweighted_events.lhe.gz'+
' '+this_run_name+
'/unweighted_events.lhe.gz']
966 shutil.move(madspinDirs[-1]+
'/unweighted_events.lhe.gz',this_run_name+
'/unweighted_events.lhe.gz')
967 mglog.info(
'Moving MadSpin events from '+madspinDirs[-1]+
'/unweighted_events.lhe.gz to '+this_run_name+
'/unweighted_events.lhe.gz')
968 elif os.path.exists(madspinDirs[-1]+
'/events.lhe.gz'):
969 MADGRAPH_COMMAND_STACK += [
'mv '+madspinDirs[-1]+
'/events.lhe.gz'+
' '+this_run_name+
'/unweighted_events.lhe.gz']
970 shutil.move(madspinDirs[-1]+
'/events.lhe.gz',this_run_name+
'/unweighted_events.lhe.gz')
971 mglog.info(
'Moving MadSpin events from '+madspinDirs[-1]+
'/events.lhe.gz to '+this_run_name+
'/unweighted_events.lhe.gz')
973 raise RuntimeError(
'MadSpin was run but can\'t find files :(')
976 MADGRAPH_COMMAND_STACK += [
'mv '+madspinDirs[-1]+
'/events.lhe.gz '+this_run_name+
'/events.lhe.gz']
977 shutil.move(madspinDirs[-1]+
'/events.lhe.gz',this_run_name+
'/events.lhe.gz')
978 mglog.info(
'Moving MadSpin events from '+madspinDirs[-1]+
'/events.lhe.gz to '+this_run_name+
'/events.lhe.gz')
981 mglog.error(
'MadSpin was run but can\'t find output folder '+(this_run_name+
'_decayed_1/'))
982 raise RuntimeError(
'MadSpin was run but can\'t find output folder '+(this_run_name+
'_decayed_1/'))
984 if fixEventWeightsForBridgeMode:
985 mglog.info(
"Fixing event weights after MadSpin... initial checks.")
993 eventsfilename=
"unweighted_events"
995 eventsfilename=
"events"
996 unzip =
stack_subprocess([
'gunzip',
'-f',this_run_name+
'/%s.lhe.gz' % eventsfilename])
999 for line
in open(process_dir+
'/Events/'+MADGRAPH_RUN_NAME+
'/%s.lhe'%eventsfilename):
1000 if "Number of Events" in line:
1002 MGnumevents=int(sline[-1])
1003 elif "Integrated weight (pb)" in line:
1005 MGintweight=float(sline[-1])
1006 elif "set spinmode none" in line:
1008 elif "</header>" in line:
1011 if spinmodenone
and MGnumevents>0
and MGintweight>0:
1012 mglog.info(
"Fixing event weights after MadSpin... modifying LHE file.")
1013 newlhe=open(this_run_name+
'/%s_fixXS.lhe'%eventsfilename,
'w')
1021 event_norm_setting=
"average"
1023 for line
in open(this_run_name+
'/%s.lhe'%eventsfilename):
1026 if "<init>" in line:
1029 elif "</init>" in line:
1031 elif inInit
and initlinecount==0:
1035 if abs(int(sline[-2])) == 3:
1036 event_norm_setting=
"sum"
1037 elif abs(int(sline[-2])) == 4:
1038 event_norm_setting=
"average"
1039 elif inInit
and initlinecount==1:
1042 relunc=float(sline[1])/float(sline[0])
1043 sline[0]=str(MGintweight)
1044 sline[1]=str(float(sline[0])*relunc)
1045 if event_norm_setting==
"sum":
1046 sline[2]=str(MGintweight/MGnumevents)
1047 elif event_norm_setting==
"average":
1048 sline[2]=str(MGintweight)
1049 newline=
' '.join(sline)
1052 elif inInit
and initlinecount>1:
1054 elif "<event>" in line:
1057 elif "</event>" in line:
1059 elif inEvent
and eventlinecount==0:
1062 if event_norm_setting==
"sum":
1063 sline[2]=str(MGintweight/MGnumevents)
1064 elif event_norm_setting==
"average":
1065 sline[2]=str(MGintweight)
1066 newline=
' '.join(sline)
1069 newlhe.write(newline)
1072 mglog.info(
"Fixing event weights after MadSpin... cleaning up.")
1073 shutil.copyfile(this_run_name+
'/%s.lhe' % eventsfilename,
1074 this_run_name+
'/%s_badXS.lhe' % eventsfilename)
1076 shutil.move(this_run_name+
'/%s_fixXS.lhe' % eventsfilename,
1077 this_run_name+
'/%s.lhe' % eventsfilename)
1079 rezip =
stack_subprocess([
'gzip',this_run_name+
'/%s.lhe' % eventsfilename])
1082 rezip =
stack_subprocess([
'gzip',this_run_name+
'/%s_badXS.lhe' % eventsfilename])
1086 if os.path.exists(os.getcwd()+
'/events.lhe'):
1087 os.remove(os.getcwd()+
'/events.lhe')
1089 mglog.info(
'Unzipping generated events.')
1091 unzip =
stack_subprocess([
'gunzip',
'-f',this_run_name+
'/unweighted_events.lhe.gz'])
1097 mglog.info(
'Putting a copy in place for the transform.')
1099 orig_input = this_run_name+
'/unweighted_events.lhe'
1100 mod_output = open(os.getcwd()+
'/events.lhe',
'w')
1102 orig_input = this_run_name+
'/events.lhe'
1103 mod_output = open(os.getcwd()+
'/events.lhe',
'w')
1110 with open(orig_input,
'r')
as fileobject:
1111 for line
in fileobject:
1115 if '#' not in newline:
1117 elif '>' not in newline[ newline.find(
'#'): ]:
1120 mglog.info(
'Found bad LHE line with an XML mark in a comment: "'+newline.strip()+
'"')
1121 newline=newline[:newline.find(
'#')]+
'#'+ (newline[newline.find(
'#'):].
replace(
'>',
'-'))
1123 if initrwgt
is False:
1125 elif "</initrwgt>" in newline:
1127 elif "<initrwgt>" in newline:
1129 elif initrwgt
is not None:
1130 newline=newline.replace(
'_DYNSCALE-1',
'')
1131 if '</weight>' in newline:
1132 iend=newline.find(
'</weight>')
1133 istart=newline[:iend].rfind(
'>')
1134 lhe_weights+=[newline[istart+1:iend].
strip()]
1135 mod_output.write(newline)
1139 mglog.info(
'Removed '+str(nEmpty)+
' empty lines from LHEF')
1141 mglog.info(
"The following "+str(len(lhe_weights))+
" weights have been written to the LHE file: "+
",".join(lhe_weights))
1144 mglog.info(
"Checking whether the following expected weights are in LHE file: "+
",".join(expected_weights))
1145 for w
in expected_weights:
1146 if w
not in lhe_weights:
1147 raise RuntimeError(
"Did not find expected weight "+w+
" in lhe file. Did the reweight or systematics module crash?")
1148 mglog.info(
"Found all required weights!")
1151 mod_output2 = open(os.getcwd()+
'/events.lhe',
'r')
1152 test=mod_output2.readline()
1153 if 'version="' in test:
1154 mglog.info(
'Applying LHE version hack')
1155 final_file = open(os.getcwd()+
'/events.lhe.copy',
'w')
1156 final_file.write(
'<LesHouchesEvents version="%i.0">\n'%lhe_version)
1157 shutil.copyfileobj(mod_output2, final_file)
1159 shutil.copy(os.getcwd()+
'/events.lhe.copy',os.getcwd()+
'/events.lhe')
1161 os.remove(os.getcwd()+
'/events.lhe.copy')
1166 raise RuntimeError(
'Must provide runArgs to arrange_output')
1168 if hasattr(runArgs,
'outputTXTFile'):
1169 outputDS = runArgs.outputTXTFile
1171 outputDS =
'tmp_LHE_events.tar.gz'
1173 mglog.info(
'Moving file over to '+outputDS.split(
'.tar.gz')[0]+
'.events')
1175 shutil.move(os.getcwd()+
'/events.lhe',outputDS.split(
'.tar.gz')[0]+
'.events')
1177 mglog.info(
'Re-zipping into dataset name '+outputDS)
1178 rezip =
stack_subprocess([
'tar',
'cvzf',outputDS,outputDS.split(
'.tar.gz')[0]+
'.events'])
1182 mglog.info(
'Removing the process directory')
1183 shutil.rmtree(process_dir,ignore_errors=
True)
1185 if os.path.isdir(
'MGC_LHAPDF/'):
1186 shutil.rmtree(
'MGC_LHAPDF/',ignore_errors=
True)
1189 if hasattr(runArgs,
'outputTXTFile')
and runArgs.outputTXTFile
is not None:
1190 outputDS = outputDS.split(
'.TXT')[0]
1192 if runArgs
is not None:
1193 mglog.debug(
'Setting inputGenerator file to '+outputDS)
1194 runArgs.inputGeneratorFile=outputDS
1196 mglog.info(
'All done with output arranging!')
1234 run_card = process_dir+
'/Cards/run_card.dat'
1235 if isinstance(bias_module,tuple):
1236 mglog.info(
'Using bias module '+bias_module[0])
1237 the_run_card = open(run_card,
'r')
1238 for line
in the_run_card:
1239 if 'bias_module' in line
and not bias_module[0]
in line:
1240 raise RuntimeError(
'You need to add the bias module '+bias_module[0]+
' to the run card to actually run it')
1241 the_run_card.close()
1242 if len(bias_module)!=3:
1243 raise RuntimeError(
'Please give a 3-tuple of strings containing bias module name, bias module, and makefile. Alternatively, give path to bias module tarball.')
1244 bias_module_newpath=process_dir+
'/Source/BIAS/'+bias_module[0]
1245 os.makedirs(bias_module_newpath)
1246 bias_module_file=open(bias_module_newpath+
'/'+bias_module[0]+
'.f',
'w')
1247 bias_module_file.write(bias_module[1])
1248 bias_module_file.close()
1249 bias_module_make_file=open(bias_module_newpath+
'/Makefile',
'w')
1250 bias_module_make_file.write(bias_module[2])
1251 bias_module_make_file.close()
1253 mglog.info(
'Using bias module '+bias_module)
1254 bias_module_name=bias_module.split(
'/')[-1].
replace(
'.gz',
'')
1255 bias_module_name=bias_module_name.replace(
'.tar',
'')
1256 the_run_card = open(run_card,
'r')
1257 for line
in the_run_card:
1258 if 'bias_module' in line
and bias_module_name
not in line:
1259 raise RuntimeError(
'You need to add the bias module '+bias_module_name+
' to the run card to actually run it')
1260 the_run_card.close()
1262 if os.path.exists(bias_module+
'.tar.gz'):
1263 bias_module_path=bias_module+
'.tar.gz'
1264 elif os.path.exists(bias_module+
'.gz'):
1265 bias_module_path=bias_module+
'.gz'
1266 elif os.path.exists(bias_module):
1267 bias_module_path=bias_module
1269 mglog.error(
'Did not find bias module '+bias_module+
' , this path should point to folder or tarball. Alternatively give a tuple of strings containing module name, module, and makefile')
1271 bias_module_newpath=process_dir+
'/Source/BIAS/'+bias_module_path.split(
'/')[-1]
1272 mglog.info(
'Copying bias module into place: '+bias_module_newpath)
1273 shutil.copy(bias_module_path,bias_module_newpath)
1274 mglog.info(
'Unpacking bias module')
1275 if bias_module_newpath.endswith(
'.tar.gz'):
1276 untar =
stack_subprocess([
'tar',
'xvzf',bias_module_newpath,
'--directory='+process_dir+
'/Source/BIAS/'])
1278 elif bias_module_path.endswith(
'.gz'):
1325def update_lhe_file(lhe_file_old,param_card_old=None,lhe_file_new=None,masses={},delete_old_lhe=True):
1326 """Build a new LHE file from an old one and an updated param card.
1327 The masses of some particles can be changed via the masses dictionary. No particles that appear in the events
1328 may have their masses changed.
1329 If the param card is provided, the decay block in the LHE file will be replaced with the one in the param card.
1330 By default, the old LHE file is removed.
1331 If None is provided as a new LHE file name, the new file will replace the old one."""
1333 lhe_file_new_tmp = lhe_file_new
if lhe_file_new
is not None else lhe_file_old+
'.tmp'
1335 if not os.access(lhe_file_old,os.R_OK):
1336 raise RuntimeError(
'Could not access old LHE file at '+str(lhe_file_old)+
'. Please check the file location.')
1338 if param_card_old
is not None:
1339 paramcard = subprocess.Popen([
'get_files',
'-data',param_card_old])
1341 if not os.access(param_card_old,os.R_OK):
1342 raise RuntimeError(
'Could not get param card '+param_card_old)
1344 if os.access(lhe_file_new_tmp,os.R_OK):
1345 raise RuntimeError(
'Old file at'+str(lhe_file_new_tmp)+
' in the current directory. Dont want to clobber it. Please move it first.')
1347 newlhe = open(lhe_file_new_tmp,
'w')
1351 particles_in_events = []
1354 with open(lhe_file_old,
'r')
as fileobject:
1355 for line
in fileobject:
1356 if decayEdit
and '</slha>' not in line:
1358 if decayEdit
and '</slha>' in line:
1360 if line.strip().
upper().startswith(
'BLOCK')
or line.strip().
upper().startswith(
'DECAY')\
1361 and len(line.strip().
split()) > 1:
1362 pos = 0
if line.strip().startswith(
'DECAY')
else 1
1363 blockName = line.strip().
upper().
split()[pos]
1366 if blockName !=
'DECAY' and len(line.strip().
split()) > 0:
1367 akey = line.strip().
split()[0]
1368 elif blockName ==
'DECAY' and len(line.strip().
split()) > 1:
1369 akey = line.strip().
split()[1]
1372 if akey
is not None and blockName ==
'MASS' and akey
in masses:
1373 newlhe.write(
' '+akey+
' '+str(masses[akey])+
' # \n')
1374 mglog.info(
' '+akey+
' '+str(masses[akey])+
' #')
1379 if blockName ==
'DECAY' and param_card_old
is not None:
1381 oldparam = open(param_card_old,
'r')
1383 for old_line
in oldparam.readlines():
1385 if old_line.strip().
upper().startswith(
'DECAY')
and len(old_line.strip().
split()) > 1:
1386 newBlockName = line.strip().
upper().
split()[pos]
1388 newlhe.write(old_line)
1389 elif newBlockName ==
'DECAY':
1391 newlhe.write(old_line)
1399 if not eventRead
and '<event>' in line:
1402 if len(line.split())==11:
1403 aparticle = line.split()[0]
1404 if aparticle
not in particles_in_events:
1405 particles_in_events += [aparticle]
1412 if akey
in particles_in_events:
1413 mglog.error(
'Attempted to change mass of a particle that was in an LHE event! This is not allowed!')
1420 if lhe_file_new
is None:
1421 os.remove(lhe_file_old)
1422 shutil.move(lhe_file_new_tmp,lhe_file_old)
1423 lhe_file_new_tmp = lhe_file_old
1425 elif delete_old_lhe:
1426 os.remove(lhe_file_old)
1428 return lhe_file_new_tmp
1447def modify_param_card(param_card_input=None,param_card_backup=None,process_dir=MADGRAPH_GRIDPACK_LOCATION,params={},output_location=None):
1448 """Build a new param_card.dat from an existing one.
1449 Params should be a dictionary of dictionaries. The first key is the block name, and the second in the param name.
1450 Keys can include MASS (for masses) and DECAY X (for decays of particle X)"""
1454 if param_card_input
is None:
1455 param_card_input=process_dir+
'/Cards/param_card.dat'
1456 elif param_card_input
is not None and not os.access(param_card_input,os.R_OK):
1457 paramcard = subprocess.Popen([
'get_files',
'-data',param_card_input])
1459 if not os.access(param_card_input,os.R_OK):
1460 raise RuntimeError(
'Could not get param card '+param_card_input)
1461 mglog.info(
'Using input param card at '+param_card_input)
1465 for blockName
in list(params.keys()):
1466 paramsUpper[blockName.upper()] = {}
1467 for paramName
in list(params[blockName].keys()):
1468 paramsUpper[blockName.upper()][paramName.upper()] = params[blockName][paramName]
1470 if param_card_backup
is not None:
1471 mglog.info(
'Keeping backup of original param card at '+param_card_backup)
1472 param_card_old = param_card_backup
1474 param_card_old = param_card_input+
'.old_to_be_deleted'
1475 if os.path.isfile(param_card_old):
1476 os.unlink(param_card_old)
1477 os.rename(param_card_input, param_card_old)
1479 oldcard = open(param_card_old,
'r')
1480 param_card_location= process_dir+
'/Cards/param_card.dat' if output_location
is None else output_location
1481 newcard = open(param_card_location,
'w')
1485 for linewithcomment
in oldcard:
1486 line=linewithcomment.split(
'#')[0]
1487 if line.strip().
upper().startswith(
'BLOCK')
or line.strip().
upper().startswith(
'DECAY')\
1488 and len(line.strip().
split()) > 1:
1489 if decayEdit
and blockName ==
'DECAY':
1491 pos = 0
if line.strip().startswith(
'DECAY')
else 1
1492 if blockName==
'MASS' and 'MASS' in paramsUpper:
1494 if "MASS" in doneParams:
1495 leftOvers = [ x
for x
in paramsUpper[
'MASS']
if x
not in doneParams[
'MASS'] ]
1497 leftOvers = [ x
for x
in paramsUpper[
'MASS'] ]
1499 for pdg_id
in leftOvers:
1500 mglog.warning(
'Adding mass line for '+str(pdg_id)+
' = '+str(paramsUpper[
'MASS'][pdg_id])+
' which was not in original param card')
1501 newcard.write(
' '+str(pdg_id)+
' '+str(paramsUpper[
'MASS'][pdg_id])+
'\n')
1502 doneParams[
'MASS'][pdg_id]=
True
1503 if blockName==
'DECAY' and 'DECAY' not in line.strip().
upper()
and 'DECAY' in paramsUpper:
1505 leftOvers = [ x
for x
in paramsUpper[
'DECAY']
if x
not in doneParams[
'DECAY'] ]
1506 for pdg_id
in leftOvers:
1507 mglog.warning(
'Adding decay for pdg id '+str(pdg_id)+
' which was not in the original param card')
1508 newcard.write( paramsUpper[
'DECAY'][pdg_id].
strip()+
'\n' )
1509 doneParams[
'DECAY'][pdg_id]=
True
1510 blockName = line.strip().
upper().
split()[pos]
1515 if blockName !=
'DECAY' and len(line.strip().
split()) > 0:
1518 if len(line.split())==2:
1522 akey = line.upper().
strip()[:line.strip().rfind(
' ')].
strip()
1523 elif blockName ==
'DECAY' and len(line.strip().
split()) > 1:
1524 akey = line.strip().
split()[1]
1526 newcard.write(linewithcomment)
1530 if blockName
not in paramsUpper:
1531 newcard.write(linewithcomment)
1533 blockParams = paramsUpper[blockName]
1539 if '#' in linewithcomment:
1540 stringkey = linewithcomment[linewithcomment.find(
'#')+1:].
strip()
1541 if len(stringkey.split()) > 0:
1542 stringkey = stringkey.split()[0].
upper()
1544 if akey
not in blockParams
and not (stringkey
is not None and stringkey
in blockParams):
1545 newcard.write(linewithcomment)
1548 if akey
in blockParams
and (stringkey
is not None and stringkey
in blockParams):
1549 raise RuntimeError(
'Conflicting use of numeric and string keys '+akey+
' and '+stringkey)
1551 theParam = blockParams.get(akey,blockParams[stringkey]
if stringkey
in blockParams
else None)
1552 if blockName
not in doneParams:
1553 doneParams[blockName] = {}
1554 if akey
in blockParams:
1555 doneParams[blockName][akey]=
True
1556 elif stringkey
is not None and stringkey
in blockParams:
1557 doneParams[blockName][stringkey]=
True
1560 if blockName==
"DECAY":
1561 if theParam.splitlines()[0].
split()[0].
upper()==
"DECAY":
1563 for newline
in theParam.splitlines():
1564 newcard.write(newline+
'\n')
1568 newcard.write(
'DECAY '+akey+
' '+str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].
strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1569 mglog.info(
'DECAY '+akey+
' '+str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].
strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1571 elif blockName==
'QNUMBERS':
1573 for newline
in theParam.splitlines():
1574 newcard.write(newline+
'\n')
1578 newcard.write(
' '+akey+
' '+str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].
strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1579 mglog.info(
' '+akey+
' '+str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].
strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
1583 for blockName
in paramsUpper:
1584 if blockName
not in doneParams
and len(paramsUpper[blockName].keys())>0:
1585 raise RuntimeError(
'Did not find any of the parameters for block '+blockName+
' in param_card')
1586 for paramName
in paramsUpper[blockName]:
1587 if paramName
not in doneParams[blockName]:
1588 raise RuntimeError(
'Was not able to replace parameter '+paramName+
' in param_card')
1660def modify_run_card(run_card_input=None,run_card_backup=None,process_dir=MADGRAPH_GRIDPACK_LOCATION,runArgs=None,settings={},skipBaseFragment=False):
1661 """Build a new run_card.dat from an existing one.
1662 This function can get a fresh runcard from DATAPATH or start from the process directory.
1663 Settings is a dictionary of keys (no spaces needed) and values to replace.
1668 for s
in list(settings.keys()):
1669 settings_lower[s.lower()] = settings[s]
1672 if run_card_input
is None:
1674 elif run_card_input
is not None and not os.access(run_card_input,os.R_OK):
1675 runcard = subprocess.Popen([
'get_files',
'-data',run_card_input])
1677 if not os.access(run_card_input,os.R_OK):
1678 raise RuntimeError(
'Could not get run card '+run_card_input)
1681 isNLO=is_NLO_run(process_dir=process_dir)
1683 if not skipBaseFragment:
1684 MadGraphControl.MadGraphSystematicsUtils.setup_pdf_and_systematic_weights(MADGRAPH_PDFSETTING,settings_lower,isNLO)
1687 if runArgs
is not None:
1688 beamEnergy,rand_seed = get_runArgs_info(runArgs)
1689 if 'iseed' not in settings_lower:
1690 settings_lower[
'iseed']=rand_seed
1691 if not isNLO
and 'python_seed' not in settings_lower:
1692 settings_lower[
'python_seed']=rand_seed
1693 if 'beamenergy' in settings_lower:
1694 mglog.warning(
'Do not set beam energy in MG settings. The variables are ebeam1 and ebeam2. Will use your setting of '+str(settings_lower[
'beamenergy']))
1695 beamEnergy=settings_lower[
'beamenergy']
1696 settings_lower.pop(
'beamenergy')
1697 if 'ebeam1' not in settings_lower:
1698 settings_lower[
'ebeam1']=beamEnergy
1699 if 'ebeam2' not in settings_lower:
1700 settings_lower[
'ebeam2']=beamEnergy
1702 if 'nevents' in settings_lower:
1703 settings_lower[
'nevents'] = int(settings_lower[
'nevents'])
1706 if 'custom_fcts' in settings_lower
and settings_lower[
'custom_fcts']:
1707 raw_name = str(settings_lower[
'custom_fcts']).
split()[0]
1709 if runArgs
is not None and hasattr(runArgs,
'jobConfig'):
1710 cfgdir = runArgs.jobConfig[0]
if isinstance(runArgs.jobConfig, (list, tuple))
else runArgs.jobConfig
1712 full_path = os.path.join(cfgdir, raw_name)
1713 settings_lower[
'custom_fcts'] = os.path.abspath(full_path)
1714 print(f
"Using custom function(s), specified in custom_fcts with path: {settings_lower['custom_fcts']}")
1717 settings_lower[
'custom_fcts'] = os.path.abspath(raw_name)
1719 mglog.info(
'Modifying run card located at '+run_card_input)
1720 if run_card_backup
is not None:
1721 mglog.info(
'Keeping backup of original run card at '+run_card_backup)
1722 run_card_old = run_card_backup
1724 run_card_old = run_card_input+
'.old_to_be_deleted'
1725 mglog.debug(
'Modifying runcard settings: '+str(settings_lower))
1726 if os.path.isfile(run_card_old):
1727 os.unlink(run_card_old)
1728 os.rename(run_card_input, run_card_old)
1730 oldCard = open(run_card_old,
'r')
1731 newCard = open(process_dir+
'/Cards/run_card.dat',
'w')
1733 for line
in iter(oldCard):
1734 if not line.strip().startswith(
'#'):
1735 command = line.split(
'!', 1)[0]
1736 comment = line.split(
'!', 1)[1]
if '!' in line
else ''
1738 setting = command.split(
'=')[-1]
1739 stripped_setting = setting.strip()
1740 oldValue =
'='.join(command.split(
'=')[:-1])
1741 if stripped_setting.lower()
in settings_lower:
1743 if settings_lower[stripped_setting.lower()]
is None:
1745 mglog.info(
'Removing '+stripped_setting+
'.')
1746 used_settings += [ stripped_setting.lower() ]
1748 if stripped_setting.lower() ==
'custom_fcts':
1750 line =
' '+str(settings_lower[stripped_setting.lower()])+
' = '+setting
1752 line +=
' !'+comment
1754 line = oldValue.replace(oldValue.strip(), str(settings_lower[stripped_setting.lower()]))+
'='+setting
1756 line +=
' !' + comment
1757 mglog.info(
'Setting '+stripped_setting+
' = '+str(settings_lower[stripped_setting.lower()]))
1758 used_settings += [ stripped_setting.lower() ]
1759 newCard.write(line.strip()+
'\n')
1762 if 'mcatnlo_delta' in settings_lower:
1763 if settings_lower[
'mcatnlo_delta'] ==
'True':
1764 modify_config_card(process_dir=process_dir,settings={
'pythia8_path':os.getenv(
"PY8PATH")})
1767 for asetting
in settings_lower:
1768 if asetting
in used_settings:
1770 if settings_lower[asetting]
is None:
1772 mglog.info(
'Option '+asetting+
' was not in the default run_card (normal for hidden options). Adding by hand a setting to '+str(settings_lower[asetting]) )
1773 newCard.write(
' '+str(settings_lower[asetting])+
' = '+str(asetting)+
'\n')
1777 mglog.info(
'Finished modification of run card.')
1778 if run_card_backup
is None:
1779 os.unlink(run_card_old)
1852 cardpath=process_dir+
'/Cards/run_card.dat'
1853 mydict=getDictFromCard(cardpath)
1856 if checkSetting(
'event_norm',
'sum',mydict):
1857 modify_run_card(process_dir=process_dir,settings={
'event_norm':
'average'},skipBaseFragment=
True)
1858 mglog.warning(
"setting event_norm to average, there is basically no use case where event_norm=sum is a good idea")
1862 if 'ktdurham' in mydict
and float(mydict[
'ktdurham']) > 0
and int(mydict[
'ickkw']) != 0:
1863 log=
'Bad combination of settings for CKKW-L merging! ktdurham=%s and ickkw=%s.'%(mydict[
'ktdurham'],mydict[
'ickkw'])
1865 raise RuntimeError(log)
1868 if 'systematics_program' not in mydict
or mydict[
'systematics_program']==
'systematics':
1869 syscalc_settings=[
'sys_pdf',
'sys_scalefact',
'sys_alpsfact',
'sys_matchscale']
1870 found_syscalc_setting=
False
1871 for s
in syscalc_settings:
1873 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)')
1874 found_syscalc_setting=
True
1875 if found_syscalc_setting:
1876 syst_arguments=MadGraphControl.MadGraphSystematicsUtils.convertSysCalcArguments(mydict)
1877 mglog.info(
'Converted syscalc arguments to systematics arguments: '+syst_arguments)
1878 syst_settings_update={
'systematics_arguments':syst_arguments}
1879 for s
in syscalc_settings:
1880 syst_settings_update[s]=
None
1881 modify_run_card(process_dir=process_dir,settings=syst_settings_update,skipBaseFragment=
True)
1886 mglog.info(
'Checking PDF and systematics settings')
1887 if not MadGraphControl.MadGraphSystematicsUtils.base_fragment_setup_check(MADGRAPH_PDFSETTING,mydict,isNLO):
1889 syst_settings=MadGraphControl.MadGraphSystematicsUtils.get_pdf_and_systematic_settings(MADGRAPH_PDFSETTING,isNLO)
1890 modify_run_card(process_dir=process_dir,settings=syst_settings,skipBaseFragment=
True)
1892 mydict_new=getDictFromCard(cardpath)
1893 if 'systematics_arguments' in mydict_new:
1894 systematics_arguments=MadGraphControl.MadGraphSystematicsUtils.parse_systematics_arguments(mydict_new[
'systematics_arguments'])
1895 if 'weight_info' not in systematics_arguments:
1896 mglog.info(
'Enforcing systematic weight name convention')
1898 if '--dyn' in systematics_arguments
or ' dyn' in systematics_arguments:
1899 if '--dyn' in systematics_arguments:
1900 dyn = systematics_arguments.split(
'--dyn')[1]
1901 if ' dyn' in systematics_arguments:
1902 dyn = systematics_arguments.split(
' dyn')[1]
1903 dyn = dyn.replace(
'\'',
' ').
replace(
'=',
' ').
split()[0]
1904 if dyn
is not None and len(dyn.split(
','))>1:
1905 systematics_arguments[
'weight_info']=MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO_ALTDYNSCALES
1907 systematics_arguments[
'weight_info']=MadGraphControl.MadGraphSystematicsUtils.SYSTEMATICS_WEIGHT_INFO
1908 modify_run_card(process_dir=process_dir,settings={
'systematics_arguments':MadGraphControl.MadGraphSystematicsUtils.write_systematics_arguments(systematics_arguments)},skipBaseFragment=
True)
1911 if 'python_seed' not in mydict:
1912 mglog.warning(
'No python seed set in run_card -- adding one with same value as iseed')
1913 modify_run_card(process_dir=process_dir,settings={
'python_seed':mydict[
'iseed']},skipBaseFragment=
True)
1917 proton_5flav =
False
1919 with open(process_dir+
'/Cards/proc_card_mg5.dat',
'r')
as file:
1920 content = file.readlines()
1921 for rawline
in content:
1922 line = rawline.split(
'#')[0]
1923 if line.startswith(
"define p"):
1924 if (
'b' in line.split()
and 'b~' in line.split())
or (
'5' in line.split()
and '-5' in line.split()):
1926 if 'j' in line.split()
and jet_5flav:
1928 if line.startswith(
"define j"):
1929 if (
'b' in line.split()
and 'b~' in line.split())
or (
'5' in line.split()
and '-5' in line.split()):
1931 if 'p' in line.split()
and proton_5flav:
1933 if proton_5flav
or jet_5flav:
1934 FS_updates[
'asrwgtflavor'] = 5
1935 if not proton_5flav:
1936 mglog.warning(
'Found 5-flavour jets but 4-flavour proton. This is inconsistent - please pick one.')
1937 mglog.warning(
'Will proceed assuming 5-flavour scheme.')
1939 mglog.warning(
'Found 5-flavour protons but 4-flavour jets. This is inconsistent - please pick one.')
1940 mglog.warning(
'Will proceed assuming 5-flavour scheme.')
1942 FS_updates[
'asrwgtflavor'] = 4
1944 if len(FS_updates)==0:
1945 mglog.warning(f
'Could not identify 4- or 5-flavor scheme from process card {process_dir}/Cards/proc_card_mg5.dat')
1947 if 'asrwgtflavor' in mydict
or 'maxjetflavor' in mydict
or 'pdgs_for_merging_cut' in mydict:
1948 if FS_updates[
'asrwgtflavor'] == 5:
1950 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']):
1952 mglog.warning(
'b and b~ included in p and j for 5-flavor scheme but run card settings are inconsistent; adjusting run card')
1953 run_card_updates = {
'asrwgtflavor': 5,
'maxjetflavor': 5,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 5, 21'}
1954 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1955 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'0.000000e+00'}})
1957 mglog.debug(
'Consistent 5-flavor scheme setup detected.')
1958 if FS_updates[
'asrwgtflavor'] == 4:
1960 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']):
1962 mglog.warning(
'b and b~ not included in p and j (4-flavor scheme) but run card settings are inconsistent; adjusting run card')
1963 run_card_updates = {
'asrwgtflavor': 4,
'maxjetflavor': 4,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 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':
'4.700000e+00'}})
1967 mglog.debug(
'Consistent 4-flavor scheme setup detected.')
1970 if FS_updates[
'asrwgtflavor'] == 4:
1972 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.')
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'}})
1976 elif FS_updates[
'asrwgtflavor'] == 5:
1977 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.')
1978 run_card_updates = {
'asrwgtflavor': 5,
'maxjetflavor': 5,
'pdgs_for_merging_cut':
'1, 2, 3, 4, 5, 21'}
1979 modify_run_card(process_dir=process_dir,settings=run_card_updates,skipBaseFragment=
True)
1980 modify_param_card(process_dir=process_dir, params={
'MASS': {
'5':
'0.000000e+00'}})
1982 mglog.info(
'Finished checking run card - All OK!')