ATLAS Offline Software
GENtoEVGEN_Skeleton.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2 #
3 """Functionality core of the Gen_tf transform"""
4 
5 # force no legacy job properties
6 from AthenaCommon import JobProperties
7 JobProperties.jobPropertiesDisallowed = True
8 
9 # Get logger
10 from AthenaCommon.Logging import logging
11 evgenLog = logging.getLogger("Gen_tf")
12 
13 # Common
14 from AthenaCommon.SystemOfUnits import GeV
15 from GeneratorConfig.Sequences import EvgenSequence
16 from PyUtils.Helpers import release_metadata
17 
18 # Functions for pre/post-include/exec
19 from PyJobTransforms.TransformUtils import processPreExec, processPreInclude, processPostExec, processPostInclude
20 
21 # Other imports that are needed
22 import sys, os, re
23 
24 # Function that reads the jO and returns an instance of Sample(EvgenCAConfig)
25 def setupSample(runArgs, flags):
26  # Only permit one jobConfig argument for evgen
27  if len(runArgs.jobConfig) != 1:
28  raise RuntimeError("You must supply one and only one jobConfig file argument")
29 
30  evgenLog.info("Using JOBOPTSEARCHPATH (as seen in skeleton) = {}".format(os.environ["JOBOPTSEARCHPATH"]))
31 
32  FIRST_DIR = (os.environ["JOBOPTSEARCHPATH"]).split(":")[0]
33 
34  # Find jO file
35  jofiles = [f for f in os.listdir(FIRST_DIR) if (f.startswith("mc") and f.endswith(".py"))]
36  if len(jofiles) !=1:
37  raise RuntimeError("You must supply one and only one jobOption file in DSID directory")
38  jofile = jofiles[0]
39 
40  # Perform consistency checks on the jO
41  from GeneratorConfig.GenConfigHelpers import checkJOConsistency, checkNEventsPerJob, checkKeywords, checkCategories
42  officialJO = checkJOConsistency(jofile)
43 
44  # Import the jO as a module
45  # We cannot do import BLAH directly since
46  # 1. the filenames are not python compatible (mc.GEN_blah.py)
47  # 2. the filenames are different for every jO
48  import importlib.util
49  spec = importlib.util.spec_from_file_location(
50  name="sample",
51  location=os.path.join(FIRST_DIR,jofile),
52  )
53  jo = importlib.util.module_from_spec(spec)
54  spec.loader.exec_module(jo)
55  evgenLog.info("including file %s", jofile)
56 
57  # Create instance of Sample(EvgenCAConfig)
58  sample = jo.Sample(flags)
59 
60  # Set up the sample properties
61  sample.setupFlags(flags)
62 
63  # Set the random number seed
64  # Need to use logic in EvgenJobTransforms.Generate_dsid_ranseed
65 
66  # Get DSID
67  dsid = os.path.basename(runArgs.jobConfig[0])
68  if dsid.startswith("Test"):
69  dsid = dsid.split("Test")[-1]
70 
71  # Update the global flags
72  if dsid.isdigit():
73  flags.Generator.DSID = int(dsid)
74 
75  # Set nEventsPerJob
76  if not sample.nEventsPerJob:
77  evgenLog.info("#############################################################")
78  evgenLog.info(" !!!! no sample.nEventsPerJob set !!! The default 10000 used. !!! ")
79  evgenLog.info("#############################################################")
80  else:
81  checkNEventsPerJob(sample)
82  evgenLog.info(" nEventsPerJob = " + str(sample.nEventsPerJob))
83  flags.Generator.nEventsPerJob = sample.nEventsPerJob
84 
85  # Check if sample attributes have been properly set
86  for var, value in vars(sample).items():
87  if not value:
88  raise RuntimeError("self.{} should be set in Sample(EvgenConfig)".format(var))
89  else:
90  if var == "generators":
91  from GeneratorConfig.Versioning import generatorsGetInitialVersionedDictionary, generatorsVersionedStringList
92  from GeneratorConfig.GenConfigHelpers import gen_sortkey
93  gennames = sorted(sample.generators, key=gen_sortkey)
94  gendict = generatorsGetInitialVersionedDictionary(gennames)
95  gennamesvers = generatorsVersionedStringList(gendict)
96  evgenLog.info("MetaData: generatorName = {}".format(gennamesvers))
97  else:
98  evgenLog.info("MetaData: {} = {}".format(var, value))
99 
100  # Check for other inconsistencies in jO
101  if len(sample.generators) > len(set(sample.generators)):
102  raise RuntimeError("Duplicate entries in generators: invalid configuration, please check your JO")
103  from GeneratorConfig.GenConfigHelpers import gen_require_steering
104  if gen_require_steering(sample.generators):
105  if hasattr(runArgs, "outputEVNTFile") and not hasattr(runArgs, "outputEVNT_PreFile"):
106  raise RuntimeError("'EvtGen' found in job options name, please set '--steering=afterburn'")
107 
108  # Keywords check
109  if hasattr(sample, "keywords"):
110  checkKeywords(sample, evgenLog, officialJO)
111 
112  # L1, L2 categories check
113  if hasattr(sample, "categories"):
114  checkCategories(sample, evgenLog, officialJO)
115 
116  return sample
117 
118 
119 # Function to check black-listed releases
120 def checkBlackList(cache, generatorName, checkType) :
121  isError = None
122  fileName = "BlackList_caches.txt" if checkType == "black" else "PurpleList_generators.txt"
123  with open(f"/cvmfs/atlas.cern.ch/repo/sw/Generators/MC16JobOptions/common/{fileName}") as bfile:
124  for line in bfile.readlines():
125  if not line.strip():
126  continue
127  # Bad caches
128  badCache=line.split(',')[1].strip()
129  # Bad generators
130  badGens=line.split(',')[2].strip()
131 
132  used_gens = ','.join(generatorName)
133  # Match Generator and release cache
134  if cache==badCache and re.search(badGens,used_gens) is not None:
135  if badGens=="": badGens="all generators"
136  isError=f"{cache} is {checkType}-listed for {badGens}"
137  return isError
138  return isError
139 
140 
141 # Main function
142 def fromRunArgs(runArgs):
143  # print release information
144  d = release_metadata()
145  evgenLog.info("using release [%(project name)s-%(release)s] [%(platform)s] [%(nightly name)s/%(nightly release)s] -- built on [%(date)s]", d)
146  athenaRel = d["release"]
147 
148  evgenLog.info("****************** STARTING EVENT GENERATION *****************")
149 
150  evgenLog.info("**** Transformation run arguments")
151  evgenLog.info(runArgs)
152 
153  evgenLog.info("**** Setting-up configuration flags")
154 
155  from AthenaConfiguration.AllConfigFlags import initConfigFlags
156  flags = initConfigFlags()
157 
158  from AthenaConfiguration.Enums import ProductionStep
159  flags.Common.ProductionStep = ProductionStep.Generation
160 
161  # Convert run arguments to global athena flags
162  from PyJobTransforms.CommonRunArgsToFlags import commonRunArgsToFlags
163  commonRunArgsToFlags(runArgs, flags)
164 
165  # Convert generator-specific run arguments to global athena flags
166  from GeneratorConfig.GeneratorConfigFlags import generatorRunArgsToFlags
167  generatorRunArgsToFlags(runArgs, flags)
168 
169  # convert arguments to flags
170  flags.fillFromArgs()
171 
172  # Create an instance of the Sample(EvgenCAConfig) and update global flags accordingly
173  sample = setupSample(runArgs, flags)
174 
175  # Sort the list of generator names into standard form
176  from GeneratorConfig.GenConfigHelpers import gen_sortkey, gen_lhef
177  generatorNames = sorted(sample.generators, key=gen_sortkey)
178 
179  # Check black-list and purple-list
180  blError = checkBlackList(athenaRel,generatorNames, "black")
181  plError = checkBlackList(athenaRel,generatorNames, "purple")
182  if blError is not None:
183  raise RuntimeError(blError)
184  if plError is not None:
185  evgenLog.warning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
186  evgenLog.warning(f"!!! WARNING {plError} !!!")
187  evgenLog.warning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
188 
189  # Setup the main flags
190  flags.Exec.FirstEvent = runArgs.firstEvent
191  flags.Exec.MaxEvents = runArgs.maxEvents if runArgs.maxEvents != -1 else flags.Generator.nEventsPerJob
192 
193  flags.Input.Files = []
194  flags.Input.RunNumbers = [flags.Generator.DSID]
195  flags.Input.TimeStamps = [0]
196 
197  flags.Output.EVNTFileName = runArgs.outputEVNTFile
198 
199  flags.Beam.Energy = runArgs.ecmEnergy / 2 * GeV
200 
201  flags.PerfMon.doFastMonMT = True
202  flags.PerfMon.doFullMonMT = True
203 
204  # Process pre-include
205  processPreInclude(runArgs, flags)
206 
207  # Process pre-exec
208  processPreExec(runArgs, flags)
209 
210  # Lock flags
211  flags.lock()
212 
213  evgenLog.info("**** Configuration flags")
214  if runArgs.VERBOSE:
215  flags.dump()
216  else:
217  flags.dump("Generator.*")
218 
219  # Print various stuff
220  evgenLog.info(".transform = Gen_tf")
221  evgenLog.info(".platform = " + str(os.environ["BINARY_TAG"]))
222 
223  # Announce start of job configuration
224  evgenLog.info("**** Configuring event generation")
225 
226  # Main object
227  from AthenaConfiguration.MainServicesConfig import MainEvgenServicesCfg
228  cfg = MainEvgenServicesCfg(flags, withSequences=True)
229 
230  # EventInfoCnvAlg
231  from xAODEventInfoCnv.xAODEventInfoCnvConfig import EventInfoCnvAlgCfg
232  cfg.merge(EventInfoCnvAlgCfg(flags, disableBeamSpot=True, xAODKey="TMPEvtInfo"),
233  sequenceName=EvgenSequence.Generator.value)
234 
235  # Set up the process
236  cfg.merge(sample.setupProcess(flags))
237 
238  # Filter
239 
240  # Fix non-standard event features
241  from EvgenProdTools.EvgenProdToolsConfig import FixHepMCCfg
242  cfg.merge(FixHepMCCfg(flags))
243 
244 
245  from GeneratorConfig.GenConfigHelpers import gens_testhepmc
246  if gens_testhepmc(sample.generators):
247  from EvgenProdTools.EvgenProdToolsConfig import TestHepMCCfg
248  cfg.merge(TestHepMCCfg(flags))
249 
250  # Copy the event weight from HepMC to the Athena EventInfo class
251  from EvgenProdTools.EvgenProdToolsConfig import CopyEventWeightCfg
252  cfg.merge(CopyEventWeightCfg(flags))
253 
254  from EvgenProdTools.EvgenProdToolsConfig import FillFilterValuesCfg
255  cfg.merge(FillFilterValuesCfg(flags))
256 
257  # Configure the event counting (AFTER all filters)
258  from EvgenProdTools.EvgenProdToolsConfig import CountHepMCCfg
259  cfg.merge(CountHepMCCfg(flags,
260  RequestedOutput = sample.nEventsPerJob if runArgs.maxEvents == -1
261  else runArgs.maxEvents))
262  evgenLog.info("Requested output events = %s", str(cfg.getEventAlgo("CountHepMC").RequestedOutput))
263 
264  # Print out the contents of the first 5 events (after filtering)
265  if hasattr(runArgs, "printEvts") and runArgs.printEvts > 0:
266  from TruthIO.TruthIOConfig import PrintMCCfg
267  cfg.merge(PrintMCCfg(flags,
268  LastEvent=runArgs.printEvts))
269 
270  # PerfMon
271  from PerfMonComps.PerfMonCompsConfig import PerfMonMTSvcCfg
272  cfg.merge(PerfMonMTSvcCfg(flags), sequenceName=EvgenSequence.Post.value)
273 
274  # Estimate time needed for Simulation
275  from EvgenProdTools.EvgenProdToolsConfig import SimTimeEstimateCfg
276  cfg.merge(SimTimeEstimateCfg(flags))
277 
278  # TODO: Rivet
279 
280  # Include information about generators in metadata
281  from GeneratorConfig.Versioning import generatorsGetInitialVersionedDictionary, generatorsVersionedStringList
282  generatorDictionary = generatorsGetInitialVersionedDictionary(generatorNames)
283  generatorList = generatorsVersionedStringList(generatorDictionary)
284 
285  # Extra metadata
286  # TODO: to be optimised
287  from EventInfoMgt.TagInfoMgrConfig import TagInfoMgrCfg
288  metadata = {
289  "project_name": "IS_SIMULATION",
290  f"AtlasRelease_{runArgs.trfSubstepName}": flags.Input.Release or "n/a",
291  "beam_energy": str(int(flags.Beam.Energy)),
292  "beam_type": flags.Beam.Type.value,
293  "generators": '+'.join(generatorList),
294  "hepmc_version": f"HepMC{os.environ['HEPMCVER']}",
295  "keywords": ", ".join(sample.keywords).lower(),
296  "lhefGenerator": '+'.join(filter(gen_lhef, generatorNames)),
297  "mc_channel_number": str(flags.Generator.DSID),
298  }
299  if hasattr(sample, "process"): metadata.update({"evgenProcess": sample.process})
300  if hasattr(sample, "tune"): metadata.update({"evgenTune": sample.tune})
301  if hasattr(sample, "specialConfig"): metadata.update({"specialConfiguration": sample.specialConfig})
302  if hasattr(sample, "hardPDF"): metadata.update({"hardPDF": sample.hardPDF})
303  if hasattr(sample, "softPDF"): metadata.update({"softPDF": sample.softPDF})
304  if hasattr(sample, "randomSeed"): metadata.update({"randomSeed": str(runArgs.randomSeed)})
305  cfg.merge(TagInfoMgrCfg(flags, tagValuePairs=metadata))
306 
307  # Print version of HepMC to the log
308  evgenLog.info("HepMC version %s", os.environ["HEPMCVER"])
309 
310  # Configure output stream
311  from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
312  cfg.merge(OutputStreamCfg(flags, "EVNT", ["McEventCollection#*"]))
313 
314  # Add in-file MetaData
315  from xAODMetaDataCnv.InfileMetaDataConfig import SetupMetaDataForStreamCfg
316  cfg.merge(SetupMetaDataForStreamCfg(flags, "EVNT"))
317 
318  # Post-include
319  processPostInclude(runArgs, flags, cfg)
320 
321  # Post-exec
322  processPostExec(runArgs, flags, cfg)
323 
324  # Write AMI tag into in-file MetaData
325  from PyUtils.AMITagHelperConfig import AMITagCfg
326  cfg.merge(AMITagCfg(flags, runArgs))
327 
328  # Print ComponentAccumulator components
329  cfg.printConfig(prefix="Gen_tf", printSequenceTreeOnly=not runArgs.VERBOSE)
330 
331  # Run final ComponentAccumulator
332  sys.exit(not cfg.run().isSuccess())
python.GENtoEVGEN_Skeleton.checkBlackList
def checkBlackList(cache, generatorName, checkType)
Definition: GENtoEVGEN_Skeleton.py:120
python.GENtoEVGEN_Skeleton.fromRunArgs
def fromRunArgs(runArgs)
Definition: GENtoEVGEN_Skeleton.py:142
python.GenConfigHelpers.gens_testhepmc
def gens_testhepmc(gennames)
Definition: GenConfigHelpers.py:76
SystemOfUnits
python.TransformUtils.processPreExec
def processPreExec(runArgs, flags)
Definition: Tools/PyJobTransforms/python/TransformUtils.py:41
vtune_athena.format
format
Definition: vtune_athena.py:14
python.TransformUtils.processPostExec
def processPostExec(runArgs, flags, cfg)
Definition: Tools/PyJobTransforms/python/TransformUtils.py:50
python.OutputStreamConfig.OutputStreamCfg
def OutputStreamCfg(flags, streamName, ItemList=[], MetadataItemList=[], disableEventTag=False, trigNavThinningSvc=None, takeItemsFromInput=False, extendProvenanceRecord=True, AcceptAlgs=[], HelperTools=[])
Definition: OutputStreamConfig.py:12
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
TruthIOConfig.PrintMCCfg
def PrintMCCfg(flags, name="PrintMC", **kwargs)
Definition: TruthIOConfig.py:8
python.Helpers.release_metadata
def release_metadata()
Definition: Tools/PyUtils/python/Helpers.py:143
python.GENtoEVGEN_Skeleton.setupSample
def setupSample(runArgs, flags)
Definition: GENtoEVGEN_Skeleton.py:25
python.GeneratorConfigFlags.generatorRunArgsToFlags
def generatorRunArgsToFlags(runArgs, flags)
Definition: GeneratorConfigFlags.py:43
python.TransformUtils.processPostInclude
def processPostInclude(runArgs, flags, cfg)
Definition: Tools/PyJobTransforms/python/TransformUtils.py:69
python.GenConfigHelpers.checkJOConsistency
def checkJOConsistency(jofile)
Definition: GenConfigHelpers.py:102
python.TransformUtils.processPreInclude
def processPreInclude(runArgs, flags)
Definition: Tools/PyJobTransforms/python/TransformUtils.py:62
python.PerfMonCompsConfig.PerfMonMTSvcCfg
def PerfMonMTSvcCfg(flags, **kwargs)
A minimal new-style configuration for PerfMonMTSvc.
Definition: PerfMonCompsConfig.py:10
python.TagInfoMgrConfig.TagInfoMgrCfg
def TagInfoMgrCfg(flags, tagValuePairs={})
Definition: TagInfoMgrConfig.py:6
EvgenProdToolsConfig.SimTimeEstimateCfg
def SimTimeEstimateCfg(flags, name="SimTimeEstimate", **kwargs)
Definition: EvgenProdToolsConfig.py:54
covarianceTool.filter
filter
Definition: covarianceTool.py:514
EvgenProdToolsConfig.CopyEventWeightCfg
def CopyEventWeightCfg(flags, name="CopyEventWeight", **kwargs)
Definition: EvgenProdToolsConfig.py:38
python.MainServicesConfig.MainEvgenServicesCfg
def MainEvgenServicesCfg(flags, LoopMgr="AthenaEventLoopMgr", withSequences=True)
Definition: MainServicesConfig.py:349
EvgenProdToolsConfig.TestHepMCCfg
def TestHepMCCfg(flags, name="TestHepMC", streamName="TestHepMCname", fileName="TestHepMC.root", **kwargs)
Definition: EvgenProdToolsConfig.py:8
python.GenConfigHelpers.checkNEventsPerJob
def checkNEventsPerJob(sample)
Definition: GenConfigHelpers.py:135
python.GenConfigHelpers.gen_require_steering
def gen_require_steering(gennames)
Definition: GenConfigHelpers.py:49
python.CommonRunArgsToFlags.commonRunArgsToFlags
def commonRunArgsToFlags(runArgs, configFlags)
Definition: CommonRunArgsToFlags.py:12
python.Versioning.generatorsGetInitialVersionedDictionary
def generatorsGetInitialVersionedDictionary(generators)
Definition: Versioning.py:25
python.GenConfigHelpers.checkKeywords
def checkKeywords(sample, evgenLog, officialJO)
Definition: GenConfigHelpers.py:150
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename T::value_type > sorted(T begin, T end)
Helper function to create a sorted vector from an unsorted one.
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:224
EvgenProdToolsConfig.FixHepMCCfg
def FixHepMCCfg(flags, name="FixHepMC", **kwargs)
Definition: EvgenProdToolsConfig.py:19
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
python.Versioning.generatorsVersionedStringList
def generatorsVersionedStringList(generatorsDictionary)
Definition: Versioning.py:44
TrigJetMonitorAlgorithm.items
items
Definition: TrigJetMonitorAlgorithm.py:79
EvgenProdToolsConfig.CountHepMCCfg
def CountHepMCCfg(flags, name="CountHepMC", **kwargs)
Definition: EvgenProdToolsConfig.py:25
Trk::open
@ open
Definition: BinningType.h:40
python.AMITagHelperConfig.AMITagCfg
def AMITagCfg(flags, runArgs=None, fixBroken=False)
Definition: AMITagHelperConfig.py:77
python.AllConfigFlags.initConfigFlags
def initConfigFlags()
Definition: AllConfigFlags.py:19
python.GenConfigHelpers.checkCategories
def checkCategories(sample, evgenLog, officialJO)
Definition: GenConfigHelpers.py:177
str
Definition: BTagTrackIpAccessor.cxx:11
EvgenProdToolsConfig.FillFilterValuesCfg
def FillFilterValuesCfg(flags, name="FillFilterValues", **kwargs)
Definition: EvgenProdToolsConfig.py:46
python.xAODEventInfoCnvConfig.EventInfoCnvAlgCfg
def EventInfoCnvAlgCfg(flags, name="EventInfoCnvAlg", inputKey="McEventInfo", outputKey="EventInfo", disableBeamSpot=False, **kwargs)
Definition: xAODEventInfoCnvConfig.py:11
InfileMetaDataConfig.SetupMetaDataForStreamCfg
def SetupMetaDataForStreamCfg(flags, streamName="", AcceptAlgs=None, createMetadata=None, propagateMetadataFromInput=True, *args, **kwargs)
Definition: InfileMetaDataConfig.py:216
Trk::split
@ split
Definition: LayerMaterialProperties.h:38