3"""Functionality core of the Gen_tf transform"""
13import AthenaCommon.AlgSequence
as acas
14import AthenaCommon.AppMgr
as acam
15from AthenaCommon.AthenaCommonFlags
import jobproperties
17from xAODEventInfoCnv.xAODEventInfoCnvConf
import xAODMaker__EventInfoCnvAlg
18acam.athMasterSeq += xAODMaker__EventInfoCnvAlg(xAODKey=
"TMPEvtInfo")
21acam.athMasterSeq += acas.AlgSequence(
"EvgenGenSeq")
22genSeq = acam.athMasterSeq.EvgenGenSeq
23acam.athMasterSeq += acas.AlgSequence(
"EvgenPreFilterSeq")
24prefiltSeq = acam.athMasterSeq.EvgenPreFilterSeq
25acam.athMasterSeq += acas.AlgSequence(
"EvgenTestSeq")
26testSeq = acam.athMasterSeq.EvgenTestSeq
28from EvgenProdTools.LogicalExpressionFilter
import LogicalExpressionFilter
30filtSeq = acam.athMasterSeq.EvgenFilterSeq
31topSeq = acas.AlgSequence()
33topSeq += acas.AlgSequence(
"EvgenPostSeq")
34postSeq = topSeq.EvgenPostSeq
43import AthenaCommon.AtlasUnixStandardJob
44include(
"PartPropSvc/PartPropSvc.py")
47from PerfMonComps.PerfMonFlags
import jobproperties
as perfmonjp
48perfmonjp.PerfMonFlags.doFastMonMT =
True
51from RngComps.RngCompsConf
import AthRNGSvc
55jobproperties.AthenaCommonFlags.AllowIgnoreConfigError =
False
62from AthenaCommon.Logging
import logging
63evgenLog = logging.getLogger(
'Generate_ab')
71evgenLog.debug(
"****************** CHECKING EVENT GENERATION ARGS *****************")
72evgenLog.debug(
str(runArgs))
76if not hasattr(runArgs,
"outputEVNTFile")
and not hasattr(runArgs,
"outputEVNT_PreFile"):
77 raise RuntimeError(
"No output evgen EVNT or EVNT_Pre file provided.")
80if not hasattr(runArgs,
"ecmEnergy"):
81 raise RuntimeError(
"No center of mass energy provided.")
83 evgenLog.info(
'ecmEnergy = ' +
str(runArgs.ecmEnergy) )
84if not hasattr(runArgs,
"randomSeed"):
85 raise RuntimeError(
"No random seed provided.")
86if not hasattr(runArgs,
"firstEvent"):
87 raise RuntimeError(
"No first number provided.")
88if (runArgs.firstEvent <= 0):
89 evgenLog.warning(
"Run argument firstEvent should be > 0")
91if hasattr(runArgs,
"inputEVNT_PreFile"):
92 evgenLog.info(
"inputEVNT_PreFile = " +
','.join(runArgs.inputEVNT_PreFile))
99evgenLog.debug(
"****************** CONFIGURING EVENT GENERATION *****************")
103from EvgenJobTransforms.EvgenConfig
import evgenConfig
104from GeneratorConfig.GenConfigHelpers
import gens_known, gens_lhef, gen_sortkey, gens_testhepmc, gens_notune
107from EvgenProdTools.EvgenProdToolsConf
import TestHepMC
108testSeq +=
TestHepMC(CmEnergy=runArgs.ecmEnergy*Units.GeV)
109if not hasattr(svcMgr,
'THistSvc'):
110 from GaudiSvc.GaudiSvcConf
import THistSvc
112svcMgr.THistSvc.Output = [
"TestHepMCname DATAFILE='TestHepMC.root' OPT='RECREATE'"]
116from EvgenProdTools.EvgenProdToolsConf
import CountHepMC
118import AthenaPoolCnvSvc.ReadAthenaPool
119svcMgr.EventSelector.FirstEvent = runArgs.firstEvent
121if not hasattr(postSeq,
"CountHepMC"):
123 OutputEventInfo=
"EventInfo",
124 mcEventWeightsKey=
"")
127postSeq.CountHepMC.FirstEvent = runArgs.firstEvent
128postSeq.CountHepMC.CorrectHepMC =
True
129postSeq.CountHepMC.CorrectEventID =
True
130postSeq.CountHepMC.CorrectRunNumber =
False
132if hasattr(runArgs,
"inputEVNT_PreFile"):
133 from AthenaCommon.AppMgr
import ServiceMgr
135 if not hasattr(ServiceMgr.ToolSvc,
'IOVDbMetaDataTool'):
136 ServiceMgr.ToolSvc += CfgMgr.IOVDbMetaDataTool()
137 runNum = int((runArgs.jobConfig[0])[-6:])
138 ServiceMgr.ToolSvc.IOVDbMetaDataTool.MinMaxRunNumbers = [runNum, runNum+1]
142if hasattr(runArgs,
"printEvts")
and runArgs.printEvts > 0:
143 from TruthIO.TruthIOConf
import PrintMC
145 postSeq.PrintMC.McEventKey =
"GEN_EVENT"
146 postSeq.PrintMC.VerboseOutput =
True
147 postSeq.PrintMC.PrintStyle =
"Barcode"
148 postSeq.PrintMC.FirstEvent = 1
149 postSeq.PrintMC.LastEvent = runArgs.printEvts
153if hasattr(runArgs,
"rivetAnas"):
154 from Rivet_i.Rivet_iConf
import Rivet_i
156 anaSeq.Rivet_i.Analyses = runArgs.rivetAnas
157 anaSeq.Rivet_i.AnalysisPath = os.environ[
'PWD']
158 if hasattr(runArgs,
"outputYODAFile"):
159 anaSeq.Rivet_i.HistoFile = runArgs.outputYODAFile
166evgenLog.debug(
"****************** LOADING PRE-INCLUDES AND JOB CONFIG *****************")
169if hasattr(runArgs,
"preInclude"):
170 for fragment
in runArgs.preInclude:
174if hasattr(runArgs,
"preExec"):
175 evgenLog.info(
"Transform pre-exec")
176 for cmd
in runArgs.preExec:
183 if hasattr(runArgs,
"outputTXTFile"): outputTXTFile=runArgs.outputTXTFile
188if len(runArgs.jobConfig) != 1:
189 evgenLog.error(
"You must supply one and only one jobConfig file argument")
191evgenLog.info(
"Using JOBOPTSEARCHPATH!! = '%s'" % os.environ[
"JOBOPTSEARCHPATH"])
192FIRST_DIR = (os.environ[
'JOBOPTSEARCHPATH']).
split(
":")[0]
194jofiles = [f
for f
in os.listdir(FIRST_DIR)
if (f.startswith(
'mc')
and f.endswith(
'.py'))]
197 evgenLog.error(
"You must supply one and only one jobOption file in DSID directory")
201joparts = (os.path.basename(jofile)).
split(
".")
203if joparts[0].startswith(
"mc"):
205 if len(joparts) != 3:
206 evgenLog.error(jofile +
" name format is wrong: must be of the form mc.<physicsShort>.py: please rename.")
209 jo_physshortpart = joparts[1]
210 max_jo_physshort_length = 50
211 if len(jo_physshortpart) > max_jo_physshort_length:
212 evgenLog.error(f
"{jofile} contains a physicsShort field of more than {max_jo_physshort_length} characters: please rename.")
215 jo_physshortparts = jo_physshortpart.split(
"_")
216 if len(jo_physshortparts) < 2:
217 evgenLog.error(jofile +
" has too few physicsShort fields separated by '_': should contain <generators>(_<tune+PDF_if_available>)_<process>. Please rename.")
220 check_jofiles=
"/cvmfs/atlas.cern.ch/repo/sw/Generators/MC16JobOptions/scripts/check_jo_consistency.py"
221 if os.path.exists(check_jofiles):
222 include(check_jofiles)
223 check_naming(os.path.basename(jofile))
225 evgenLog.error(
"check_jo_consistency.py not found")
236evgenLog.debug(
"****************** CHECKING EVGEN CONFIGURATION *****************")
239for opt
in str(evgenConfig).
split(os.linesep):
242evgenLog.info(
".transform = Gen_tf")
246if evgenConfig.obsolete:
247 evgenLog.error(
"JOs or icludes are obsolete, please check them")
250if not evgenConfig.generators:
251 evgenLog.error(
"No entries in evgenConfig.generators: invalid configuration, please check your JO")
254if len(evgenConfig.generators) > len(
set(evgenConfig.generators)):
255 evgenLog.error(
"Duplicate entries in evgenConfig.generators: invalid configuration, please check your JO")
258gennames = sorted(evgenConfig.generators, key=gen_sortkey)
260if joparts[0].startswith(
"MC"):
261 genpart = jo_physshortparts[0]
262 expectedgenpart =
''.join(gennames)
264 expectedgenpart = expectedgenpart.replace(
"HerwigJimmy",
"Herwig")
274 if genpart !=
_norm(expectedgenpart)
and _norm2(genpart) !=
_norm(expectedgenpart):
275 evgenLog.error(
"Expected first part of JO name to be '%s' or '%s', but found '%s'" % (
_norm(expectedgenpart),
_norm(
_short2(expectedgenpart)), genpart))
276 evgenLog.error(
"gennames '%s' " %(expectedgenpart))
282 if not gens_notune(gennames)
and len(jo_physshortparts) < 3:
283 evgenLog.error(jofile +
" with generators " + expectedgenpart +
284 " has too few physicsShort fields separated by '_'." +
285 " It should contain <generators>_<tune+PDF_<process>. Please rename.")
291if hasattr(runArgs,
'inputGeneratorFile')
and ',' in runArgs.inputGeneratorFile:
292 multiInput = runArgs.inputGeneratorFile.count(
',')+1
296if not evgenConfig.nEventsPerJob:
297 evgenLog.info(
'#############################################################')
298 evgenLog.info(
' !!!! no nEventsPerJob set !!! The default 10000 used. !!! ')
299 evgenLog.info(
'#############################################################')
301 evgenLog.info(
' nEventsPerJob = ' +
str(evgenConfig.nEventsPerJob) )
304if evgenConfig.minevents > 0 :
305 raise RuntimeError(
"evgenConfig.minevents is obsolete and should be removed from the JOs")
307if evgenConfig.nEventsPerJob < 1:
308 raise RuntimeError(
"evgenConfig.nEventsPerJob must be at least 1")
309elif evgenConfig.nEventsPerJob > 100000:
310 raise RuntimeError(
"evgenConfig.nEventsPerJob can be max. 100000")
312 allowed_nEventsPerJob_lt1000 = [1, 2, 5, 10, 20, 25, 50, 100, 200, 500, 1000]
313 msg =
"evgenConfig.nEventsPerJob = %d: " % evgenConfig.nEventsPerJob
315 if evgenConfig.nEventsPerJob >= 1000
and evgenConfig.nEventsPerJob <=10000
and (evgenConfig.nEventsPerJob % 1000 != 0
or 10000 % evgenConfig.nEventsPerJob != 0) :
316 msg +=
"nEventsPerJob in range [1K, 10K] must be a multiple of 1K and a divisor of 10K"
317 raise RuntimeError(msg)
318 elif evgenConfig.nEventsPerJob > 10000
and evgenConfig.nEventsPerJob % 10000 != 0:
319 msg +=
"nEventsPerJob >10K must be a multiple of 10K"
320 raise RuntimeError(msg)
321 elif evgenConfig.nEventsPerJob < 1000
and evgenConfig.nEventsPerJob
not in allowed_nEventsPerJob_lt1000:
322 msg +=
"nEventsPerJob in range <= 1000 must be one of %s" % allowed_nEventsPerJob_lt1000
323 raise RuntimeError(msg)
324 postSeq.CountHepMC.RequestedOutput = evgenConfig.nEventsPerJob
if runArgs.maxEvents == -1
else runArgs.maxEvents
325 evgenLog.info(
'Requested output events = '+
str(postSeq.CountHepMC.RequestedOutput))
330 if hasattr(testSeq,
"TestHepMC")
and postSeq.CountHepMC.RequestedOutput<100:
331 testSeq.TestHepMC.EffFailThreshold = postSeq.CountHepMC.RequestedOutput/(postSeq.CountHepMC.RequestedOutput+1) - 0.01
334if evgenConfig.keywords:
335 from GeneratorConfig.GenConfigHelpers
import checkKeywords
336 checkKeywords(evgenConfig, evgenLog)
340if evgenConfig.findJets:
341 include(
"EvgenJobTransforms/Generate_TruthJets.py")
344from AthenaPoolCnvSvc.WriteAthenaPool
import AthenaPoolOutputStream
345from AthenaPoolCnvSvc.AthenaPoolCnvSvcConf
import AthenaPoolCnvSvc
348if hasattr(runArgs,
"outputEVNTFile"):
349 poolFile = runArgs.outputEVNTFile
350elif hasattr(runArgs,
"outputEVNT_PreFile"):
351 poolFile = runArgs.outputEVNT_PreFile
353 raise RuntimeError(
"Output pool file, either EVNT or EVNT_Pre, is not known.")
356StreamEVGEN = AthenaPoolOutputStream(
"StreamEVGEN", poolFile, asAlg=
True, noTag=
True , eventInfoKey=
"EventInfo")
357if hasattr(runArgs,
"inputEVNT_PreFile") :
358 svcMgr.EventSelector.InputCollections = runArgs.inputEVNT_PreFile
359 StreamEVGEN.TakeItemsFromInput =
True
360 postSeq.CountHepMC.CorrectRunNumber =
True
362StreamEVGEN.ForceRead =
True
363StreamEVGEN.ItemList += [
"EventInfo#*",
"xAOD::EventInfo#EventInfo*",
"xAOD::EventAuxInfo#EventInfoAux.*",
"McEventCollection#*"]
364StreamEVGEN.RequireAlgs += [
"EvgenFilterSeq"]
366if evgenConfig.saveJets:
367 StreamEVGEN.ItemList += [
"xAOD::JetContainer#*"]
368 StreamEVGEN.ItemList += [
"xAOD::JetAuxContainer#*Aux.TruthLabelID.PartonTruthLabelID"]
369if evgenConfig.savePileupTruthParticles:
370 StreamEVGEN.ItemList += [
"xAOD::TruthParticleContainer#TruthPileupParticles*"]
371 StreamEVGEN.ItemList += [
"xAOD::TruthParticleAuxContainer#TruthPileupParticlesAux.*"]
375dsid = os.path.basename(runArgs.jobConfig[0])
376if not dsid.isdigit():
378svcMgr.EventSelector.RunNumber = int(dsid)
380if postSeq.CountHepMC.CorrectRunNumber ==
True:
381 postSeq.CountHepMC.NewRunNumber = int(dsid)
382 evgenLog.info(
"Set new run number in skel NewRunNumber = " +
str(postSeq.CountHepMC.NewRunNumber))
384 evgenLog.info(
"No new run number set in skel RunNumber = " + dsid)
387import EventInfoMgt.EventInfoMgtInit
388svcMgr.TagInfoMgr.ExtraTagValuePairs.update({
"beam_energy":
str(int(runArgs.ecmEnergy*Units.GeV/2.0))})
389svcMgr.TagInfoMgr.ExtraTagValuePairs.update({
"beam_type":
'collisions'})
390if len(evgenConfig.keywords)>0:
392 svcMgr.TagInfoMgr.ExtraTagValuePairs.update({
"keywords":
", ".join(evgenConfig.keywords).lower()})
395from PyUtils
import AMITagHelper
396AMITagHelper.SetAMITag(runArgs=runArgs)
399from OutputStreamAthenaPool.OutputStreamAthenaPoolConf
import CopyEventStreamInfo
401ToolSvc += streamInfoTool
402svcMgr.MetaDataSvc.MetaDataTools += [ streamInfoTool ]
406include(
"EvgenJobTransforms/Generate_ecmenergies.py")
409include(
"EvgenJobTransforms/Generate_dsid_ranseed.py")
412if (hasattr( runArgs,
"VERBOSE")
and runArgs.VERBOSE )
or (hasattr( runArgs,
"loglevel")
and runArgs.loglevel ==
"DEBUG")
or (hasattr( runArgs,
"loglevel")
and runArgs.loglevel ==
"VERBOSE"):
413 include(
"EvgenJobTransforms/Generate_debug_level.py")
416svcMgr.TagInfoMgr.ExtraTagValuePairs.update({
"specialConfiguration": evgenConfig.specialConfig})
420if hasattr(testSeq,
"TestHepMC")
and not gens_testhepmc(evgenConfig.generators):
421 evgenLog.info(
"Removing TestHepMC sanity checker")
422 del testSeq.TestHepMC
429if hasattr(runArgs,
"postInclude"):
430 for fragment
in runArgs.postInclude:
433if hasattr(runArgs,
"postExec"):
434 evgenLog.info(
"Transform post-exec")
435 for cmd
in runArgs.postExec:
443acas.dumpMasterSequence()
451evgenLog.debug(
"****************** HANDLING EVGEN INPUT FILES *****************")
455if "McAtNlo" in evgenConfig.generators
and "Herwig" in evgenConfig.generators:
456 datFile =
"inparmMcAtNlo.dat"
457elif "Alpgen" in evgenConfig.generators:
458 datFile =
"inparmAlpGen.dat"
459elif "Protos" in evgenConfig.generators:
460 datFile =
"protos.dat"
461elif "ProtosLHEF" in evgenConfig.generators:
462 datFile =
"protoslhef.dat"
463elif "AcerMC" in evgenConfig.generators:
464 datFile =
"inparmAcerMC.dat"
465elif "CompHep" in evgenConfig.generators:
466 datFile =
"inparmCompHep.dat"
473 "Return a matching file, provided it is unique"
475 files = glob.glob(pattern)
478 raise RuntimeError(
"No '%s' file found" % pattern)
480 raise RuntimeError(
"More than one '%s' file found" % pattern)
484 "Make a symlink safely"
486 if os.path.exists(dstfile)
and not os.path.samefile(dstfile, srcfile):
488 if not os.path.exists(dstfile):
489 evgenLog.info(
"Symlinking %s to %s" % (srcfile, dstfile))
490 os.symlink(srcfile, dstfile)
492 evgenLog.debug(
"Symlinking: %s is already the same as %s" % (dstfile, srcfile))
496if evgenConfig.auxfiles:
498 get_files(evgenConfig.auxfiles, keepDir=
False, errorIfNotFound=
True)
506 if not hasattr(evgenConfig, attr)
or not getattr(evgenConfig, attr):
507 msg =
"evgenConfig attribute '%s' not found." % attr
509 raise RuntimeError(
"Required " + msg)
514 msg = evgenConfig.description
516 msg +=
" " + evgenConfig.notes
517 print (
"MetaData: %s = %s" % (
"physicsComment", msg))
519 print (
"MetaData: %s = %s" % (
"generatorName",
"+".join(gennames)))
521 print (
"MetaData: %s = %s" % (
"physicsProcess", evgenConfig.process))
523 print (
"MetaData: %s = %s" % (
"generatorTune", evgenConfig.tune))
525 print (
"MetaData: %s = %s" % (
"hardPDF", evgenConfig.hardPDF))
527 print (
"MetaData: %s = %s" % (
"softPDF", evgenConfig.softPDF))
529 print (
"MetaData: %s = %s" % (
"nEventsPerJob", evgenConfig.nEventsPerJob))
531 print (
"MetaData: %s = %s" % (
"keywords",
", ".join(evgenConfig.keywords).lower()))
533 print (
"MetaData: %s = %s" % (
"specialConfig", evgenConfig.specialConfig))
536 print (
"MetaData: %s = %s" % (
"contactPhysicist",
", ".join(evgenConfig.contact)))
539filterNames = [alg.getType()
for alg
in acas.iter_algseq(filtSeq)]
540excludedNames = [
'AthSequencer',
'PyAthena::Alg',
'TestHepMC']
541filterNames = list(
set(filterNames) -
set(excludedNames))
542print (
"MetaData: %s = %s" % (
"genFilterNames",
", ".join(filterNames)))
549from PyJobTransformsCore.runargs
import RunArguments
550runPars = RunArguments()
551runPars.nEventsPerJob = evgenConfig.nEventsPerJob
552runPars.maxeventsstrategy = evgenConfig.maxeventsstrategy
553with open(
"config.pickle",
"wb")
as f:
555 pickle.dump(runPars, f)
561evgenLog.info(
"****************** STARTING EVENT GENERATION *****************")
A service to manage multiple RNG streams in thread-safe way.
This class provides an algorithm to make the EventStreamInfo object and update it.
Count the number of events to pass all algorithms/filters.
Print MC event details for a range of event numbers.
Interface to the Rivet analysis package.
Filtering algorithm to sanity check HepMC event features.
std::string replace(std::string s, const std::string &s2, const std::string &s3)
std::vector< std::string > split(const std::string &s, const std::string &t=":")
_checkattr(attr, required=False)
==============================================================
mk_symlink(srcfile, dstfile)
OutputTXTFile()
==============================================================