ATLAS Offline Software
Loading...
Searching...
No Matches
python.GEN_Skeleton Namespace Reference

Functions

 setupSample (flags)
 checkBlackList (cache, generatorName, checkType)
 fromRunArgs (runArgs)

Variables

 jobPropertiesDisallowed
 evgenLog = logging.getLogger("Gen_tf")

Detailed Description

Functionality core of the Gen_tf transform

Function Documentation

◆ checkBlackList()

python.GEN_Skeleton.checkBlackList ( cache,
generatorName,
checkType )

Definition at line 130 of file GEN_Skeleton.py.

130def checkBlackList(cache, generatorName, checkType) :
131 isError = None
132 fileName = "BlackList_caches.txt" if checkType == "black" else "PurpleList_generators.txt"
133 with open(f"/cvmfs/atlas.cern.ch/repo/sw/Generators/MC16JobOptions/common/{fileName}") as bfile:
134 for line in bfile.readlines():
135 if not line.strip():
136 continue
137 # Bad caches
138 badCache=line.split(',')[1].strip()
139 # Bad generators
140 badGens=line.split(',')[2].strip()
141
142 used_gens = ','.join(generatorName)
143 # Match Generator and release cache
144 if cache==badCache and re.search(badGens,used_gens) is not None:
145 if badGens=="": badGens="all generators"
146 isError=f"{cache} is {checkType}-listed for {badGens}"
147 return isError
148 return isError
149
150
151# Main function

◆ fromRunArgs()

python.GEN_Skeleton.fromRunArgs ( runArgs)

Definition at line 152 of file GEN_Skeleton.py.

152def fromRunArgs(runArgs):
153 # print release information
154 d = release_metadata()
155 evgenLog.info("using release [%(project name)s-%(release)s] [%(platform)s] [%(nightly name)s/%(nightly release)s] -- built on [%(date)s]", d)
156 athenaRel = d["release"]
157
158 evgenLog.info("****************** STARTING EVENT GENERATION *****************")
159
160 evgenLog.info("**** Transformation run arguments")
161 evgenLog.info(runArgs)
162
163 evgenLog.info("**** Setting-up configuration flags")
164
165 from AthenaConfiguration.AllConfigFlags import initConfigFlags
166 flags = initConfigFlags()
167
168 from AthenaConfiguration.Enums import ProductionStep
169 flags.Common.ProductionStep = ProductionStep.Generation
170
171 # Convert run arguments to global athena flags
172 from PyJobTransforms.CommonRunArgsToFlags import commonRunArgsToFlags
173 commonRunArgsToFlags(runArgs, flags)
174
175 # Convert generator-specific run arguments to global athena flags
176 from GeneratorConfig.GeneratorConfigFlags import generatorRunArgsToFlags
177 generatorRunArgsToFlags(runArgs, flags)
178
179 # convert arguments to flags
180 flags.fillFromArgs()
181
182 # Determine maximum number of events to generate
183 requested_max_events = flags.Exec.MaxEvents
184 # Event generation is not using standard event counting
185 flags.Exec.MaxEvents = -1
186
187 # Create an instance of the Sample(EvgenCAConfig) and update global flags accordingly
188 sample = setupSample(flags)
189
190 # Determine output file name and type.
191 output_pool_file = (
192 flags.Output.EVNTFileName
193 or getattr(runArgs, "outputEVNTFile", None)
194 or getattr(runArgs, "outputEVNT_PreFile", None)
195 )
196 flags.Output.EVNTFileName = output_pool_file or ""
197 output_txt_file = (
198 flags.Output.TXTFileName
199 or getattr(runArgs, "outputTXTFile", None)
200 )
201 flags.Output.TXTFileName = output_txt_file or ""
202
203 # If no EVNT output is specified, we check if it's a TXT-only run (i.e. standalone LHE output production).
204 # In that case, we don't require an EVNT output file.
205 txt_only_mode = _is_txt_only_run(flags)
206 if not output_pool_file and not (flags.Generator.outputYODAFile or txt_only_mode):
207 raise RuntimeError("No output evgen EVNT or EVNT_Pre file provided.")
208
209 # Setup the main flags
210 flags.Exec.FirstEvent = flags.Generator.firstEvent
211
212 # We are always doing MC
213 flags.Input.isMC = True
214
215 # If no inputEVNT_PreFile was provided clear transform placeholder input files
216 # and set RunNumber/TimeStamp based on DSID.
217 if hasattr(runArgs, "inputEVNT_PreFile") and runArgs.inputEVNT_PreFile:
218 flags.Input.Files = runArgs.inputEVNT_PreFile
219 else:
220 flags.Input.Files = []
221
222 if not flags.Input.Files:
223 flags.Input.Files = []
224 flags.Input.RunNumbers = [flags.Generator.DSID]
225 flags.Input.TimeStamps = [0]
226
227 flags.PerfMon.doFastMonMT = True
228 flags.PerfMon.doFullMonMT = True
229
230 # Process pre-include
231 processPreInclude(runArgs, flags)
232
233 # Process pre-exec
234 processPreExec(runArgs, flags)
235
236 # Lock flags
237 flags.lock()
238
239 evgenLog.info("**** Configuration flags")
240 if runArgs.VERBOSE:
241 flags.dump()
242 else:
243 flags.dump("Generator.*")
244
245 # Print various stuff
246 evgenLog.info(".transform = Gen_tf")
247 evgenLog.info(".platform = " + str(os.environ["BINARY_TAG"]))
248
249 # Announce start of job configuration
250 evgenLog.info("**** Configuring event generation")
251
252 # Main object
253 from AthenaConfiguration.MainServicesConfig import MainEvgenServicesCfg
254 cfg = MainEvgenServicesCfg(flags, withSequences=True)
255
256 # Input file handling (if needed)
257 if flags.Input.Files and not txt_only_mode:
258 from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
259 cfg.merge(PoolReadCfg(flags))
260
261 # EventInfoCnvAlg
262 from xAODEventInfoCnv.xAODEventInfoCnvConfig import EventInfoCnvAlgCfg
263 cfg.merge(EventInfoCnvAlgCfg(flags, disableBeamSpot=True, xAODKey="TMPEvtInfo"),
264 sequenceName=EvgenSequence.Generator.value)
265
266 # Set up the process
267 cfg.merge(sample.setupProcess(flags))
268
269 # Sort the list of generator names into standard form
270 from GeneratorConfig.GenConfigHelpers import gen_sortkey
271 from GeneratorConfig.Versioning import generatorsGetInitialVersionedDictionary, generatorsVersionedStringList
272 if not flags.Input.Files:
273 generators = sorted(cfg.getService("GeneratorInfoSvc").Generators, key=gen_sortkey)
274 gendict = generatorsGetInitialVersionedDictionary(generators)
275 generatorsWithVersion = generatorsVersionedStringList(gendict)
276 else:
277 # TODO: read from metadata
278 generators = []
279 generatorsWithVersion = []
280
281 # Check if the setup requires steering
282 from GeneratorConfig.GenConfigHelpers import gen_require_steering
283 if gen_require_steering(generators):
284 if hasattr(runArgs, "outputEVNTFile") and not hasattr(runArgs, "outputEVNT_PreFile"):
285 raise RuntimeError("'EvtGen' found in job options name, please set '--steering=afterburn'")
286
287 # LHE input handling
288 nEventsLHE = None
289 if flags.Generator.inputFilesPerJob > 0:
290 if not flags.Generator.inputGeneratorFile:
291 raise RuntimeError(f"Sample sets inputFilesPerJob = {flags.Generator.inputFilesPerJob} but Gen_tf run without inputGeneratorFile")
292 else:
293 nEventsLHE = _handle_input_files(generators, flags)
294
295 # Check black-list and purple-list
296 blError = checkBlackList(athenaRel, generators, "black")
297 plError = checkBlackList(athenaRel, generators, "purple")
298 if blError is not None:
299 raise RuntimeError(blError)
300 if plError is not None:
301 evgenLog.warning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
302 evgenLog.warning(f"!!! WARNING {plError} !!!")
303 evgenLog.warning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
304
305 # Fix non-standard event features
306 if not txt_only_mode and not flags.Input.Files:
307 from EvgenProdTools.EvgenProdToolsConfig import FixHepMCCfg
308 from GeneratorConfig.GenConfigHelpers import gens_purgenoendvtx
309 generatorsList = generators.copy()
310 if "Pythia8" in generatorsList:
311 pythia8Alg = cfg.getEventAlgo("Pythia8_i")
312 if pythia8Alg.Beam1 != "PROTON" or pythia8Alg.Beam2 != "PROTON":
313 # generator name is still "Pythia8", even when colliding nuclei
314 generatorsList.append("Pythia8-Angantyr")
315 cfg.merge(FixHepMCCfg(flags,
316 PurgeUnstableWithoutEndVtx=gens_purgenoendvtx(generatorsList)))
317
318 # Merge GenWeightDeclarationCfg to declare the number
319 # of generator weights to the CutFlowSvc
320 if output_pool_file and not flags.Input.Files:
321 from EvgenProdTools.EvgenProdToolsConfig import GenWeightDeclarationCfg
322 cfg.merge(GenWeightDeclarationCfg(flags))
323
324 # Sanity check the event record (not appropriate for all generators)
325 from GeneratorConfig.GenConfigHelpers import gens_testhepmc
326 if not txt_only_mode and gens_testhepmc(generators):
327 from EvgenProdTools.EvgenProdToolsConfig import TestHepMCCfg
328 cfg.merge(TestHepMCCfg(flags))
329
330 # Copying event-level HepMC decorations is EVNT-oriented and not needed for
331 # standalone LHE output production.
332 if not txt_only_mode:
333 from EvgenProdTools.EvgenProdToolsConfig import CopyEventWeightCfg
334 cfg.merge(CopyEventWeightCfg(flags))
335
336 from EvgenProdTools.EvgenProdToolsConfig import FillFilterValuesCfg
337 cfg.merge(FillFilterValuesCfg(flags))
338
339 # Configure the event counting (AFTER all filters)
340 from EvgenProdTools.EvgenProdToolsConfig import CountHepMCCfg
341 requested_output = (
342 1 if txt_only_mode else
343 (sample.nEventsPerJob if requested_max_events == -1 else requested_max_events)
344 )
345 count_kwargs = {"RequestedOutput": requested_output}
346 if txt_only_mode:
347 # In TXT-only mode there is no GEN_EVENT in StoreGate. Disabling
348 # HepMC/EventInfo corrections avoids dereferencing missing event data.
349 count_kwargs["CorrectHepMC"] = False
350 count_kwargs["CorrectEventID"] = False
351 count_kwargs["CorrectRunNumber"] = False
352 count_kwargs["CopyRunNumber"] = False
353 count_kwargs["InputEventInfo"] = ""
354 count_kwargs["OutputEventInfo"] = ""
355 count_kwargs["mcEventWeightsKey"] = ""
356 cfg.merge(CountHepMCCfg(flags, **count_kwargs))
357 evgenLog.info(f"Requested output events = {cfg.getEventAlgo('CountHepMC').RequestedOutput}")
358
359 # Print out the contents of the first 5 events (after filtering)
360 if not txt_only_mode and flags.Generator.printEvts > 0:
361 from TruthIO.TruthIOConfig import PrintMCCfg
362 cfg.merge(PrintMCCfg(flags,
363 LastEvent=flags.Generator.printEvts))
364
365 # PerfMon
366 from PerfMonComps.PerfMonCompsConfig import PerfMonMTSvcCfg
367 cfg.merge(PerfMonMTSvcCfg(flags), sequenceName=EvgenSequence.Post.value)
368
369 # Estimate time needed for Simulation
370 if not txt_only_mode:
371 from EvgenProdTools.EvgenProdToolsConfig import SimTimeEstimateCfg
372 cfg.merge(SimTimeEstimateCfg(flags))
373
374 # TODO: Rivet
375
376 # Extra metadata
377 from EventInfoMgt.TagInfoMgrConfig import TagInfoMgrCfg
378 from GeneratorConfig.GenConfigHelpers import gen_lhef
379 metadata = {
380 "project_name": "IS_SIMULATION",
381 f"AtlasRelease_{runArgs.trfSubstepName}": flags.Input.Release or "n/a",
382 "beam_energy": str(int(flags.Beam.Energy)),
383 "beam_type": flags.Beam.Type.value,
384 "hepmc_version": f"HepMC{os.environ['HEPMCVER']}",
385 "keywords": ", ".join(sample.keywords).lower(),
386 "lhefGenerator": '+'.join(filter(gen_lhef, generators)),
387 "mc_channel_number": str(flags.Generator.DSID),
388 }
389 if not flags.Input.Files:
390 metadata.update({
391 "generators": '+'.join(generatorsWithVersion),
392 "tune": cfg.getService("GeneratorInfoSvc").Tune
393 })
394 if hasattr(sample, "process"): metadata.update({"evgenProcess": sample.process})
395 if hasattr(sample, "specialConfig"): metadata.update({"specialConfiguration": sample.specialConfig})
396 if hasattr(sample, "hardPDF"): metadata.update({"hardPDF": sample.hardPDF})
397 if hasattr(sample, "softPDF"): metadata.update({"softPDF": sample.softPDF})
398 if hasattr(sample, "randomSeed"): metadata.update({"randomSeed": str(flags.Random.SeedOffset)})
399 cfg.merge(TagInfoMgrCfg(flags, tagValuePairs=metadata))
400
401 # Print metadata in the log
402 evgenLog.info(f"HepMC version {os.environ['HEPMCVER']}")
403 if not flags.Input.Files:
404 evgenLog.info(f"MetaData: generatorTune = {cfg.getService('GeneratorInfoSvc').Tune}")
405 evgenLog.info("MetaData: generatorName = {}".format(generatorsWithVersion))
406 if nEventsLHE is not None:
407 print(f"MetaData: Number of input LHE events = {nEventsLHE}")
408 elif txt_only_mode:
409 produced_lhe = None
410 for candidate in (flags.Output.TXTFileName, "events.lhe"):
411 if candidate and os.path.exists(candidate):
412 produced_lhe = candidate
413 break
414 if produced_lhe:
415 nEventsTXT = _count_lhe_events(produced_lhe)
416 print(f"MetaData: Number of produced LHE events = {nEventsTXT}")
417
418 if output_pool_file:
419 # Count all events that are written
420 from EventBookkeeperTools.EventBookkeeperToolsConfig import AllWrittenEventsCounterAlgCfg
421 cfg.merge(AllWrittenEventsCounterAlgCfg(flags))
422
423 # Configure output stream
424 from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
425 cfg.merge(OutputStreamCfg(flags, "EVNT", ["McEventCollection#*"],
426 MetadataItemList=["IOVMetaDataContainer#*"]))
427
428 # Add in-file MetaData
429 from AthenaConfiguration.Enums import MetadataCategory
430 from xAODMetaDataCnv.InfileMetaDataConfig import SetupMetaDataForStreamCfg
431 cfg.merge(SetupMetaDataForStreamCfg(flags, "EVNT",
432 createMetadata=[MetadataCategory.CutFlowMetaData,
433 MetadataCategory.TruthMetaData]))
434
435 # Post-include
436 processPostInclude(runArgs, flags, cfg)
437
438 # Post-exec
439 processPostExec(runArgs, flags, cfg)
440
441 # Write AMI tag into in-file MetaData
442 from PyUtils.AMITagHelperConfig import AMITagCfg
443 cfg.merge(AMITagCfg(flags, runArgs))
444
445 # Hack the main sequence to not ignore filters
446 # TODO: figure out if we can do it in a more elegant way without another nested sequence
447 cfg.getSequence("AthAlgSeq").IgnoreFilterPassed = False
448
449 # Print ComponentAccumulator components
450 cfg.printConfig(prefix="Gen_tf", printSequenceTreeOnly=not runArgs.VERBOSE)
451
452 # Run final ComponentAccumulator
453 sys.exit(not cfg.run().isSuccess())
void print(char *figname, TCanvas *c1)

◆ setupSample()

python.GEN_Skeleton.setupSample ( flags)

Definition at line 37 of file GEN_Skeleton.py.

37def setupSample(flags):
38 # Only permit one jobConfig argument for evgen
39 job_config = flags.Generator.jobConfig
40 if isinstance(job_config, str):
41 job_config = [job_config]
42 if len(job_config) != 1:
43 raise RuntimeError("You must supply one and only one jobConfig file argument")
44
45 evgenLog.info("Using JOBOPTSEARCHPATH (as seen in skeleton) = {}".format(os.environ["JOBOPTSEARCHPATH"]))
46
47 FIRST_DIR = (os.environ["JOBOPTSEARCHPATH"]).split(":")[0]
48
49 # Find jO file
50 jofiles = [f for f in os.listdir(FIRST_DIR) if (f.startswith("mc") and f.endswith(".py"))]
51 if len(jofiles) !=1:
52 raise RuntimeError("You must supply one and only one jobOption file in DSID directory")
53 jofile = jofiles[0]
54
55 # Perform consistency checks on the jO
56 from GeneratorConfig.GenConfigHelpers import (
57 checkNaming,
58 checkNEventsPerJob,
59 checkKeywords,
60 checkCategories
61 )
62 checkNaming(jofile)
63
64 # Import the jO as a module
65 # We cannot do import BLAH directly since
66 # 1. the filenames are not python compatible (mc.GEN_blah.py)
67 # 2. the filenames are different for every jO
68 import importlib.util
69 spec = importlib.util.spec_from_file_location(
70 name="sample",
71 location=os.path.join(FIRST_DIR,jofile),
72 )
73 jo = importlib.util.module_from_spec(spec)
74
75 spec.loader.exec_module(jo)
76 evgenLog.info(f"including file {jofile}")
77
78 # Create instance of Sample(EvgenCAConfig)
79 sample = jo.Sample(flags)
80
81 # Set up the sample properties
82 sample.setupFlags(flags)
83
84 # Set the random number seed
85 # Need to use logic in EvgenJobTransforms.Generate_dsid_ranseed
86
87 # Get DSID
88 dsid = os.path.basename(job_config[0])
89 if dsid.startswith("Test"):
90 dsid = dsid.split("Test")[-1]
91
92 # Update the global flags
93 if dsid.isdigit():
94 flags.Generator.DSID = int(dsid)
95
96 # Set nEventsPerJob
97 if not sample.nEventsPerJob:
98 evgenLog.info("#############################################################")
99 evgenLog.info(" !!!! no sample.nEventsPerJob set !!!")
100 evgenLog.info("#############################################################")
101 # We don't need to set the global flag because its default is 10000
102 else:
103 checkNEventsPerJob(sample)
104 evgenLog.info(" nEventsPerJob = " + str(sample.nEventsPerJob))
105 flags.Generator.nEventsPerJob = sample.nEventsPerJob
106
107 # Validate all required/conditional sample metadata with explicit rules.
108 _validate_sample_properties(sample)
109
110 # Propagate optional sample values to global flags.
111 flags.Generator.inputFilesPerJob = sample.inputFilesPerJob
112 flags.Generator.MEgenerator = sample.MEgenerator or ""
113
114 # Print sample metadata in the log.
115 for var, value in vars(sample).items():
116 evgenLog.info("MetaData: {} = {}".format(var, value))
117
118 # Keywords check
119 if hasattr(sample, "keywords"):
120 checkKeywords(sample, evgenLog)
121
122 # L1, L2 categories check
123 if hasattr(sample, "categories"):
124 checkCategories(sample, evgenLog)
125
126 return sample
127
128
129# Function to check black-listed releases
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:179

Variable Documentation

◆ evgenLog

python.GEN_Skeleton.evgenLog = logging.getLogger("Gen_tf")

Definition at line 11 of file GEN_Skeleton.py.

◆ jobPropertiesDisallowed

python.GEN_Skeleton.jobPropertiesDisallowed

Definition at line 7 of file GEN_Skeleton.py.