ATLAS Offline Software
Loading...
Searching...
No Matches
skel.GENtoTXT.py
Go to the documentation of this file.
1# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2#
3"""Functionality core of the Generate_tf transform"""
4
5
8
9
11
12import ast
13import os, re, string, subprocess
14import AthenaCommon.AlgSequence as acas
15import AthenaCommon.AppMgr as acam
16from AthenaCommon.AthenaCommonFlags import jobproperties
17from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
18from AthenaCommon.AthenaCommonFlags import jobproperties
19
20from xAODEventInfoCnv.xAODEventInfoCnvConf import xAODMaker__EventInfoCnvAlg
21acam.athMasterSeq += xAODMaker__EventInfoCnvAlg(xAODKey="TMPEvtInfo")
22
23theApp = acam.theApp
24acam.athMasterSeq += acas.AlgSequence("EvgenGenSeq")
25genSeq = acam.athMasterSeq.EvgenGenSeq
26acam.athMasterSeq += acas.AlgSequence("EvgenFixSeq")
27fixSeq = acam.athMasterSeq.EvgenFixSeq
28acam.athMasterSeq += acas.AlgSequence("EvgenPreFilterSeq")
29prefiltSeq = acam.athMasterSeq.EvgenPreFilterSeq
30acam.athMasterSeq += acas.AlgSequence("EvgenTestSeq")
31testSeq = acam.athMasterSeq.EvgenTestSeq
32
33from EvgenProdTools.LogicalExpressionFilter import LogicalExpressionFilter
34acam.athMasterSeq += LogicalExpressionFilter("EvgenFilterSeq")
35filtSeq = acam.athMasterSeq.EvgenFilterSeq
36topSeq = acas.AlgSequence()
37anaSeq = topSeq
38topSeq += acas.AlgSequence("EvgenPostSeq")
39postSeq = topSeq.EvgenPostSeq
40
43
44
45import AthenaCommon.AtlasUnixGeneratorJob
46include("PartPropSvc/PartPropSvc.py")
47
48
49from PerfMonComps.PerfMonFlags import jobproperties as perfmonjp
50perfmonjp.PerfMonFlags.doFastMonMT = True
51
52from RngComps.RngCompsConf import AthRNGSvc
53svcMgr += AthRNGSvc()
54
55
56jobproperties.AthenaCommonFlags.AllowIgnoreConfigError = False
57
58
59from AthenaCommon.Logging import logging
60evgenLog = logging.getLogger('Gen_tf')
61
62
65
66
67evgenLog.debug("****************** CHECKING EVENT GENERATION ARGS *****************")
68evgenLog.debug(str(runArgs))
69evgenLog.info ("****************** CHECKING EVENT GENERATION ARGS *****************")
70
71# TODO: Allow generation without writing an output file (if outputEVNTFile is None)?
72if not hasattr(runArgs, "ecmEnergy"):
73 raise RuntimeError("No center of mass energy provided.")
74else:
75 evgenLog.info('ecmEnergy = ' + str(runArgs.ecmEnergy) )
76
79
80
81evgenLog.debug("****************** CONFIGURING MATRIX ELEMENT GENERATION *****************")
82evgenLog.info("****************** CONFIGURING MATRIX ELEMENT GENERATION *****************")
83
84
86from EvgenJobTransforms.EvgenConfig import evgenConfig
87from GeneratorConfig.GenConfigHelpers import gens_known, gen_lhef, gens_lhef, gen_sortkey, gens_testhepmc, gens_notune, gen_require_steering
88
89
91from EvgenProdTools.EvgenProdToolsConf import CountHepMC
92if (runArgs.firstEvent <= 0):
93 evgenLog.warning("Run argument firstEvent should be > 0")
94
95svcMgr.EventSelector.FirstEvent = runArgs.firstEvent
96theApp.EvtMax = -1
97
98#evgenConfig.nEventsPerJob = 1
99if not hasattr(postSeq, "CountHepMC"):
100 postSeq += CountHepMC(InputEventInfo="TMPEvtInfo",
101 OutputEventInfo="EventInfo",
102 mcEventWeightsKey="")
103
104postSeq.CountHepMC.FirstEvent = runArgs.firstEvent
105postSeq.CountHepMC.CorrectHepMC = True
106postSeq.CountHepMC.CorrectEventID = True
107
108
109
112
113
114evgenLog.debug("****************** LOADING PRE-INCLUDES AND JOB CONFIG *****************")
115evgenLog.info("****************** LOADING PRE-INCLUDES AND JOB CONFIG *****************")
116
117
118if hasattr(runArgs, "preInclude"):
119 for fragment in runArgs.preInclude:
120 include(fragment)
121
122
123if hasattr(runArgs, "preExec"):
124 evgenLog.info("Transform pre-exec")
125 for cmd in runArgs.preExec:
126 evgenLog.info(cmd)
127 exec(cmd)
128
129def get_immediate_subdirectories(a_dir):
130 return [name for name in os.listdir(a_dir)
131 if os.path.isdir(os.path.join(a_dir, name))]
132
133
134# TODO: Explain!!!
135def OutputTXTFile():
136 outputTXTFile = None
137 if hasattr(runArgs,"outputTXTFile"): outputTXTFile=runArgs.outputTXTFile
138 return outputTXTFile
139
140
142
143if len(runArgs.jobConfig) != 1:
144 evgenLog.info("runArgs.jobConfig = " + runArgs.jobConfig)
145 evgenLog.error("You must supply one and only one jobConfig file argument. It has to start from mc. and end with .py")
146 sys.exit(1)
147
148print ("Using JOBOPTSEARCHPATH (as seen in skeleton) = '%s'" % (os.environ["JOBOPTSEARCHPATH"]))
149FIRST_DIR = (os.environ['JOBOPTSEARCHPATH']).split(":")[0]
150
151dsid_param = runArgs.jobConfig[0]
152evgenLog.info("dsid_param = " + dsid_param)
153dsid = os.path.basename(dsid_param)
154evgenLog.info("dsid = " + dsid)
155jofiles = [f for f in os.listdir(FIRST_DIR) if (f.startswith('mc') and f.endswith('.py'))]
156
157if len(jofiles) !=1:
158 evgenLog.info("runArgs.jobConfig wrong " + runArgs.jobConfig)
159 evgenLog.error("You must supply one and only one jobOption file in DSID directory. It has to start with mc. and end with .py")
160 sys.exit(1)
161jofile = jofiles[0]
162joparts = (os.path.basename(jofile)).split(".")
163
164officialJO = False
165if joparts[0].startswith("mc") and all(c in string.digits for c in joparts[0][2:]):
166 officialJO = True
167
168 if len(joparts) != 3:
169 evgenLog.error(jofile + " name format is wrong: must be of the form MC<xx>.<physicsShort>.py: please rename.")
170 sys.exit(1)
171
172
173 jo_physshortpart = joparts[1]
174 max_jo_physshort_length = 50
175 if len(jo_physshortpart) > max_jo_physshort_length:
176 evgenLog.error(f"{jofile} contains a physicsShort field of more than {max_jo_physshort_length} characters: please rename.")
177 sys.exit(1)
178
179 jo_physshortparts = jo_physshortpart.split("_")
180 if len(jo_physshortparts) < 2:
181 evgenLog.error(jofile + " has too few physicsShort fields separated by '_': should contain <generators>(_<tune+PDF_if_available>)_<process>. Please rename.")
182 sys.exit(1)
183
184 check_jofiles="/cvmfs/atlas.cern.ch/repo/sw/Generators/MC16JobOptions/scripts/check_jo_consistency.py"
185 if os.path.exists(check_jofiles):
186 evgenLog.info("Checking offical JO file name consistency")
187 include(check_jofiles)
188 check_naming(os.path.basename(jofile))
189 else:
190 evgenLog.warning("check_jo_consistency.py not found, will proceed without JOs consistency check")
191# sys.exit(1)
192
193include(jofile)
194include("EvgenJobTransforms/LHEonly.py")
195
196
199
200
201evgenLog.debug("****************** CHECKING EVGEN CONFIGURATION *****************")
202evgenLog.info("****************** CHECKING EVGEN CONFIGURATION *****************")
203
204
205for opt in str(evgenConfig).split(os.linesep):
206 evgenLog.info(opt)
207evgenLog.info(".transform = Gen_tf")
208
209
210evgenLog.info(".platform = "+str(os.environ['BINARY_TAG']))
211
212
215if evgenConfig.obsolete:
216 evgenLog.error("JOs or icludes are obsolete, please check them")
217 sys.exit(1)
218
219if not evgenConfig.generators:
220 evgenLog.error("No entries in evgenConfig.generators: invalid configuration, please check your JO")
221 sys.exit(1)
222
223if len(evgenConfig.generators) > len(set(evgenConfig.generators)):
224 evgenLog.error("Duplicate entries in evgenConfig.generators: invalid configuration, please check your JO")
225 sys.exit(1)
226
227gennames = sorted(evgenConfig.generators, key=gen_sortkey)
228
229if joparts[0].startswith("MC"): #< if this is an "official" JO
230 genpart = jo_physshortparts[0]
231 expectedgenpart = ''.join(gennames)
232
233 expectedgenpart = expectedgenpart.replace("HerwigJimmy", "Herwig")
234 def _norm(s):
235 # TODO: add EvtGen to this normalization for MC14?
236 return s.replace("Photospp", "").replace("Photos", "").replace("TauolaPP", "").replace("Tauolapp", "").replace("Tauola", "")
237 def _norm2(s):
238 return s.replace("Py", "Pythia").replace("MG","MadGraph").replace("Ph","Powheg").replace("Hpp","Herwigpp").replace("H7","Herwig7").replace("Sh","Sherpa").replace("Ag","Alpgen").replace("EG","EvtGen").replace("PG","ParticleGun").replace("Gva","Geneva")
239
240 def _short2(s):
241 return s.replace("Pythia","Py").replace("MadGraph","MG").replace("Powheg","Ph").replace("Herwigpp","Hpp").replace("Herwig7","H7").replace("Sherpa","Sh").replace("Alpgen","Ag").replace("EvtGen","EG").replace("PG","ParticleGun").replace("Geneva","Gva")
242
243
244 if genpart != _norm(expectedgenpart) and _norm2(genpart) != _norm(expectedgenpart):
245 evgenLog.error("Expected first part of JO name to be '%s' or '%s', but found '%s'" % (_norm(expectedgenpart), _norm(_short2(expectedgenpart)), genpart))
246 evgenLog.error("gennames '%s' " %(expectedgenpart))
247 sys.exit(1)
248
249 del _norm
250
251 if not gens_notune(gennames) and len(jo_physshortparts) < 3:
252 evgenLog.error(jofile + " with generators " + expectedgenpart +
253 " has too few physicsShort fields separated by '_'." +
254 " It should contain <generators>_<tune+PDF_<process>. Please rename.")
255 sys.exit(1)
256
257
259if gen_require_steering(gennames):
260 if hasattr(runArgs, "outputEVNTFile") and not hasattr(runArgs, "outputEVNT_PreFile"):
261 raise RuntimeError("'EvtGen' found in job options name, please set '--steering=afterburn'")
262
263
264
266rounding = 0
267if hasattr(runArgs,'inputGeneratorFile') and ',' in runArgs.inputGeneratorFile: multiInput = runArgs.inputGeneratorFile.count(',')+1
268else:
269 multiInput = 0
270
271# check if default nEventsPerJob used
272if not evgenConfig.nEventsPerJob:
273 evgenLog.info('#############################################################')
274 evgenLog.info(' !!!! no nEventsPerJob set !!! The default 10000 used. !!! ')
275 evgenLog.info('#############################################################')
276else:
277 evgenLog.info(' nEventsPerJob set to ' + str(evgenConfig.nEventsPerJob) )
278
279if evgenConfig.minevents > 0 :
280 raise RuntimeError("evgenConfig.minevents is obsolete and should be removed from the JOs")
281
282if evgenConfig.nEventsPerJob < 1:
283 raise RunTimeError("evgenConfig.nEventsPerJob must be at least 1")
284else:
285 evgenLog.info("evgenConfig.nEventsPerJob = {}, but only {} (dummy) event(s) will be generated by Pythia8 for lhe-only production".format(evgenConfig.nEventsPerJob, postSeq.CountHepMC.RequestedOutput))
286
287
288
289if not evgenConfig.keywords:
290 evgenLog.warning("No entries in evgenConfig.keywords: invalid configuration, please check your JO !!")
291
292
293if evgenConfig.keywords:
294 from GeneratorConfig.GenConfigHelpers import checkKeywords
295 checkKeywords(evgenConfig, evgenLog, officialJO)
296
297
298if not evgenConfig.categories:
299 evgenLog.warning("No entries in evgenConfig.categories: invalid configuration, please check your JO !!")
300
301
302if evgenConfig.categories:
303
305 lkwfile = "CategoryList.txt"
306 lkwpath = None
307 for p in os.environ["DATAPATH"].split(":"):
308 lkwpath = os.path.join(p, lkwfile)
309 if os.path.exists(lkwpath):
310 break
311 lkwpath = None
312
313 allowed_cat = []
314 if lkwpath:
315 with open(lkwpath, 'r') as catlist:
316 for line in catlist:
317 allowed_list = ast.literal_eval(line)
318 allowed_cat.append(allowed_list)
319
320
321 bad_cat =[]
322 it = iter(evgenConfig.categories)
323 for x in it:
324 l1 = x
325 l2 = next(it)
326 if "L1:" in l2 and "L2:" in l1:
327 l1, l2 = l2, l1
328 print("first",l1,"second",l2)
329 bad_cat.extend([l1, l2])
330 for a1,a2 in allowed_cat:
331 if l1.strip().lower()==a1.strip().lower() and l2.strip().lower()==a2.strip().lower():
332 bad_cat=[]
333 if bad_cat:
334 msg = "evgenConfig.categories contains non-standard category: %s. " % ", ".join(bad_cat)
335 msg += "Please check the allowed categories list and fix."
336 evgenLog.error(msg)
337 if officialJO:
338 sys.exit(1)
339 else:
340 evgenLog.warning("Could not find CategoryList.txt file %s in DATAPATH" % lkwfile)
341
342
343dsid = os.path.basename(runArgs.jobConfig[0])
344if not dsid.isdigit():
345 dsid = "999999"
346svcMgr.EventSelector.RunNumber = int(dsid)
347
348
349from GeneratorConfig.Versioning import generatorsGetInitialVersionedDictionary, generatorsVersionedStringList
350gendict = generatorsGetInitialVersionedDictionary(gennames)
351gennamesvers = generatorsVersionedStringList(gendict)
352
353import EventInfoMgt.EventInfoMgtInit
354svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"hepmc_version":"HepMC" + str(os.environ['HEPMCVER'])})
355svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"mc_channel_number":str(dsid)})
356svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"lhefGenerator": '+'.join( filter( gen_lhef, gennames ) ) })
357svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"generators": '+'.join(gennamesvers)})
358svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"evgenProcess": evgenConfig.process})
359svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"evgenTune": evgenConfig.tune})
360if hasattr( evgenConfig, "hardPDF" ) : svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"hardPDF": evgenConfig.hardPDF})
361if hasattr( evgenConfig, "softPDF" ) : svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"softPDF": evgenConfig.softPDF})
362if hasattr( runArgs, "randomSeed") : svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"randomSeed": str(runArgs.randomSeed)})
363svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"keywords": ", ".join(evgenConfig.keywords).lower()})
364
365# print version of HepMC to the log
366evgenLog.info("HepMC version " + str(os.environ['HEPMCVER']))
367
368# Set AMITag in in-file metadata
369from PyUtils import AMITagHelper
370AMITagHelper.SetAMITag(runArgs=runArgs)
371
372
373svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"beam_energy": str(int(runArgs.ecmEnergy*Units.GeV/2.0))})
374svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"beam_type": 'collisions'})
375
376
378include("EvgenJobTransforms/Generate_ecmenergies.py")
379
380# Propagate DSID and seed to the generators
381include("EvgenJobTransforms/Generate_dsid_ranseed.py")
382
383
384if (hasattr( runArgs, "VERBOSE") and runArgs.VERBOSE ) or (hasattr( runArgs, "loglevel") and runArgs.loglevel == "DEBUG") or (hasattr( runArgs, "loglevel") and runArgs.loglevel == "VERBOSE"):
385 include("EvgenJobTransforms/Generate_debug_level.py")
386
387
391def checkBlockList(relFlavour,cache,generatorName) :
392 isError = None
393 with open('/cvmfs/atlas.cern.ch/repo/sw/Generators/MC16JobOptions/common/BlackList_caches.txt') as bfile:
394 for line in bfile.readlines():
395 if not line.strip():
396 continue
397 # Blocklisted release flavours
398 badRelFlav=line.split(',')[0].strip()
399 # Blocklisted caches
400 badCache=line.split(',')[1].strip()
401 # Blocklisted generators
402 badGens=line.split(',')[2].strip()
403
404 used_gens = ','.join(generatorName)
405 #Match Generator and release type e.g. AtlasProduction, MCProd
406 if relFlavour==badRelFlav and cache==badCache and re.search(badGens,used_gens) is not None:
407 if badGens=="": badGens="all generators"
408 isError=relFlavour+","+cache+" is blocklisted for " + badGens
409 return isError
410 return isError
411
412def checkPurpleList(relFlavour,cache,generatorName) :
413 isError = None
414 with open('/cvmfs/atlas.cern.ch/repo/sw/Generators/MC16JobOptions/common/PurpleList_generators.txt') as bfile:
415 for line in bfile.readlines():
416 if not line.strip():
417 continue
418 # Purple-listed release flavours
419 purpleRelFlav=line.split(',')[0].strip()
420 # Purple-listed caches
421 purpleCache=line.split(',')[1].strip()
422 # Purple-listed generators
423 purpleGens=line.split(',')[2].strip()
424 # Purple-listed process
425 purpleProcess=line.split(',')[3].strip()
426
427 used_gens = ','.join(generatorName)
428 #Match Generator and release type e.g. AtlasProduction, MCProd
429 if relFlavour==purpleRelFlav and cache==purpleCache and re.search(purpleGens,used_gens) is not None:
430 isError=relFlavour+","+cache+" is blocklisted for " + purpleGens + " if it uses " + purpleProcess
431 return isError
432 return isError
433
434
435evgenLog.debug("****************** CHECKING RELEASE IS NOT BLACKLISTED *****************")
436rel = os.popen("echo $AtlasVersion").read()
437rel = rel.strip()
438if os.path.exists('/cvmfs/atlas.cern.ch/repo/sw/Generators/MC16JobOptions/common'):
439 errorBL = checkBlockList("AthGeneration",rel,gennames)
440 if (errorBL):
441 if (hasattr( runArgs, "ignoreBlackList") and runArgs.ignoreBlackList):
442 evgenLog.warning("This run is blocklisted for this generator, please use a different one for production !! "+ errorBL )
443 else:
444 raise RuntimeError("This run is blocklisted for this generator, please use a different one !! "+ errorBL)
445
446 errorPL = checkPurpleList("AthGeneration",rel,gennames)
447 if (errorPL):
448 evgenLog.warning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
449 evgenLog.warning("!!! WARNING !!! "+ errorPL )
450 evgenLog.warning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
451else:
452 msg.waring("No access to cvmfs, so blocklisted runs will not be checked")
453
454
455
456svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"specialConfiguration": evgenConfig.specialConfig})
457
458
459
461
462
463
466
467if hasattr(runArgs, "postInclude"):
468 for fragment in runArgs.postInclude:
469 include(fragment)
470
471if hasattr(runArgs, "postExec"):
472 evgenLog.info("Transform post-exec")
473 for cmd in runArgs.postExec:
474 evgenLog.info(cmd)
475 exec(cmd)
476
477
480acas.dumpMasterSequence()
481
482
483
486
487
488evgenLog.debug("****************** HANDLING EVGEN INPUT FILES *****************")
489print("****************** HANDLING EVGEN INPUT FILES *****************")
490
491datFile = None
492if "McAtNlo" in evgenConfig.generators and "Herwig" in evgenConfig.generators:
493 datFile = "inparmMcAtNlo.dat"
494elif "Alpgen" in evgenConfig.generators:
495 datFile = "inparmAlpGen.dat"
496elif "Protos" in evgenConfig.generators:
497 datFile = "protos.dat"
498elif "ProtosLHEF" in evgenConfig.generators:
499 datFile = "protoslhef.dat"
500elif "AcerMC" in evgenConfig.generators:
501 datFile = "inparmAcerMC.dat"
502elif "CompHep" in evgenConfig.generators:
503 datFile = "inparmCompHep.dat"
504
505
506if "Alpgen" in evgenConfig.generators:
507 eventsFile = "alpgen.unw_events"
508elif "Protos" in evgenConfig.generators:
509 eventsFile = "protos.events"
510elif "ProtosLHEF" in evgenConfig.generators:
511 eventsFile = "protoslhef.events"
512elif "BeamHaloGenerator" in evgenConfig.generators:
513 eventsFile = "beamhalogen.events"
514elif "HepMCAscii" in evgenConfig.generators:
515 eventsFile = "events.hepmc"
516elif "ReadMcAscii" in evgenConfig.generators:
517 eventsFile = "events.hepmc"
518elif gens_lhef(evgenConfig.generators):
519 #eventsFile = outputTXTFile
520 eventsFile = "events.lhe"
521
522
523
524def find_unique_file(pattern):
525 "Return a matching file, provided it is unique"
526 import glob
527 files = glob.glob(pattern)
528
529 if not files:
530 raise RuntimeError("No '%s' file found" % pattern)
531 elif len(files) > 1:
532 raise RuntimeError("More than one '%s' file found" % pattern)
533 return files[0]
534
535# This function merges a list of input LHE file to make one outputFile. The header is taken from the first
536# file, but the number of events is updated to equal the total number of events in all the input files
537def merge_lhe_files(listOfFiles,outputFile):
538 if(os.path.exists(outputFile)):
539 print ("outputFile ",outputFile," already exists. Will rename to ",outputFile,".OLD")
540 os.rename(outputFile,outputFile+".OLD")
541 output = open(outputFile,'w')
542 holdHeader = ""
543 nevents=0
544 for file in listOfFiles:
545 cmd = "grep /event "+file+" | wc -l"
546 nevents+=int(subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True))
547
548 for file in listOfFiles:
549 inHeader = True
550 header = ""
551 print ("*** Starting file ",file)
552 for line in open(file,"r"):
553
558 if("<event" in line and inHeader):
559 inHeader = False
560 if(len(holdHeader)<1):
561 holdHeader = header
562 output.write(header)
563 output.write(line)
564
566 elif(not inHeader and not ("</LesHouchesEvents>" in line)):
567 output.write(line)
568 if(inHeader):
569
570 if("nevents" in line):
571
572 tmp = line.split("=")
573 line = line.replace(tmp[0],str(nevents))
574 elif("numevts" in line):
575
576 tmp = line.split(" ")
577 nnn = str(nevents)
578 line = line.replace(tmp[1],nnn)
579 header+=line
580 output.write("</LesHouchesEvents>\n")
581 output.close()
582
583def mk_symlink(srcfile, dstfile):
584 "Make a symlink safely"
585 if dstfile:
586 if os.path.exists(dstfile) and not os.path.samefile(dstfile, srcfile):
587 os.remove(dstfile)
588 if not os.path.exists(dstfile):
589 evgenLog.info("Symlinking %s to %s" % (srcfile, dstfile))
590 os.symlink(srcfile, dstfile)
591 else:
592 evgenLog.debug("Symlinking: %s is already the same as %s" % (dstfile, srcfile))
593
594
595if eventsFile or datFile:
596 if not hasattr(runArgs, "inputGeneratorFile") or runArgs.inputGeneratorFile == "NONE":
597 raise RuntimeError("%s needs input file (argument inputGeneratorFile)" % runArgs.jobConfig)
598 if evgenConfig.inputfilecheck and not re.search(evgenConfig.inputfilecheck, runArgs.inputGeneratorFile):
599 raise RuntimeError("inputGeneratorFile=%s is incompatible with inputfilecheck '%s' in %s" %
600 (runArgs.inputGeneratorFile, evgenConfig.inputfilecheck, runArgs.jobConfig))
601 if datFile:
602 if ".tar" in os.path.basename(runArgs.inputGeneratorFile):
603 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".tar.")[0]
604 elif ".tgz" in os.path.basename(runArgs.inputGeneratorFile):
605 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".tgz")[0]
606 elif ".gz" in os.path.basename(runArgs.inputGeneratorFile):
607 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".gz")[0]
608 else:
609 inputroot = os.path.basename(runArgs.inputGeneratorFile).split("._")[0]
610
611 realDatFile = find_unique_file('*%s*.dat' % inputroot)
612 mk_symlink(realDatFile, datFile)
613 if eventsFile:
614 myinputfiles = runArgs.inputGeneratorFile
615 genInputFiles = myinputfiles.split(',')
616 numberOfFiles = len(genInputFiles)
617 # if there is a single file, make a symlink. If multiple files, merge them into one output eventsFile
618 if(numberOfFiles<2):
619 if ".tar" in os.path.basename(runArgs.inputGeneratorFile):
620 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".tar.")[0]
621 elif ".tgz" in os.path.basename(runArgs.inputGeneratorFile):
622 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".tgz")[0]
623 elif ".gz" in os.path.basename(runArgs.inputGeneratorFile):
624 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".gz")[0]
625 else:
626 inputroot = os.path.basename(runArgs.inputGeneratorFile).split("._")[0]
627
628 if "events" in inputroot :
629 inputroot = inputroot.replace(".events","")
630 realEventsFile = find_unique_file('*%s.*ev*ts' % inputroot)
631 mk_symlink(realEventsFile, eventsFile)
632 else:
633 allFiles = []
634 for file in genInputFiles:
635# Since we can have multiple files from the same task, inputroot must include more of the filename
636# to make it unique
637 if ".tar" in os.path.basename(runArgs.inputGeneratorFile):
638 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".tar.")[0]
639 elif ".tgz" in os.path.basename(runArgs.inputGeneratorFile):
640 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".tgz")[0]
641 elif ".gz" in os.path.basename(runArgs.inputGeneratorFile):
642 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".gz")[0]
643 else:
644 input0 = os.path.basename(file).split("._")[0]
645 input1 = (os.path.basename(file).split("._")[1]).split(".")[0]
646 inputroot = input0+"._"+input1
647 realEventsFile = find_unique_file('*%s.*ev*ts' % inputroot)
648# The only input format where merging is permitted is LHE
649 with open(realEventsFile, 'r') as f:
650 first_line = f.readline()
651 if(not ("LesHouche" in first_line)):
652 raise RuntimeError("%s is NOT a LesHouche file" % realEventsFile)
653 allFiles.append(realEventsFile)
654 merge_lhe_files(allFiles,eventsFile)
655
656else:
657 if hasattr(runArgs, "inputGeneratorFile") and runArgs.inputGeneratorFile != "NONE":
658 raise RuntimeError("inputGeneratorFile arg specified for %s, but generators %s do not require an input file" %
659 (runArgs.jobConfig, str(gennames)))
660# if evgenConfig.inputfilecheck:
661# raise RuntimeError("evgenConfig.inputfilecheck specified in %s, but generators %s do not require an input file" %
662# (runArgs.jobConfig, str(gennames)))
663
664
665if evgenConfig.auxfiles:
666 from PyJobTransformsCore.trfutil import get_files
667 get_files(evgenConfig.auxfiles, keepDir=False, errorIfNotFound=True)
668
669
672
673def _checkattr(attr, required=False):
674 if not hasattr(evgenConfig, attr) or not getattr(evgenConfig, attr):
675 msg = "evgenConfig attribute '%s' not found." % attr
676 if required:
677 raise RuntimeError("Required " + msg)
678 return False
679 return True
680# counting the number of events in LHE output
681count_ev = 0
682with open(eventsFile) as f:
683 for line in f:
684 count_ev += line.count('/event')
685
686evgenLog.info('Requested output events = '+str(count_ev))
687print("MetaData: %s = %s" % ("Number of produced LHE events ", count_ev))
688
689if _checkattr("description", required=True):
690 msg = evgenConfig.description
691 if _checkattr("notes"):
692 msg += " " + evgenConfig.notes
693 print("MetaData: %s = %s" % ("physicsComment", msg))
694if _checkattr("generators", required=True):
695 print ("MetaData: %s = %s" % ("generatorName", "+".join(gennamesvers)))
696if _checkattr("process"):
697 print ("MetaData: %s = %s" % ("physicsProcess", evgenConfig.process))
698if _checkattr("tune"):
699 print ("MetaData: %s = %s" % ("generatorTune", evgenConfig.tune))
700if _checkattr("hardPDF"):
701 print ("MetaData: %s = %s" % ("hardPDF", evgenConfig.hardPDF))
702if _checkattr("softPDF"):
703 print ("MetaData: %s = %s" % ("softPDF", evgenConfig.softPDF))
704if _checkattr("nEventsPerJob"):
705 print ("MetaData: %s = %s" % ("nEventsPerJob", evgenConfig.nEventsPerJob))
706if _checkattr("keywords"):
707 print ("MetaData: %s = %s" % ("keywords", ", ".join(evgenConfig.keywords).lower() ))
708if _checkattr("categories"):
709 print ( ", " + ", ".join(evgenConfig.categories))
710else:
711 print (" ")
712
713#if _checkattr("categories"): # will be uncommented when categories included into metadata
714# print "MetaData: %s = %s" % ("categories", ", ".join(evgenConfig.categories))
715if _checkattr("specialConfig"):
716 print ("MetaData: %s = %s" % ("specialConfig", evgenConfig.specialConfig))
717# TODO: Require that a contact / JO author is always set
718if _checkattr("contact"):
719 print ("MetaData: %s = %s" % ("contactPhysicist", ", ".join(evgenConfig.contact)))
720#if _checkattr( "randomSeed") : # comment out for the time being
721print ("MetaData: %s = %s" % ("randomSeed", str(runArgs.randomSeed)))
722
723
724
725
726# Output list of generator filters used
727filterNames = [alg.getType() for alg in acas.iter_algseq(filtSeq)]
728excludedNames = ['AthSequencer', 'PyAthena::Alg', 'TestHepMC']
729filterNames = list(set(filterNames) - set(excludedNames))
730print ("MetaData: %s = %s" % ("genFilterNames", ", ".join(filterNames)))
731
732
733
736
737from PyJobTransformsCore.runargs import RunArguments
738runPars = RunArguments()
739runPars.nEventsPerJob = evgenConfig.nEventsPerJob
740runPars.maxeventsstrategy = evgenConfig.maxeventsstrategy
741with open("config.pickle", "wb") as f:
742 import pickle
743 pickle.dump(runPars, f)
744
745
746
749
750evgenLog.debug("****************** STARTING EVENT GENERATION *****************")
751print ("****************** STARTING EVENT GENERATION *****************")
752print ("**************************************************************")
753print ("****************** PLEASE IGNORE THE LOG FROM PYTHIA ************")
754print ("****************** GENERATION OF ONE PYTHIA EVENT ***************")
755print ("******************** IS NEEDED TO MAKE *************")
756print ("****************** THE TRANSFORM WORK ***************************")
757print ("**************************************************************")
if(febId1==febId2)
void print(char *figname, TCanvas *c1)
A service to manage multiple RNG streams in thread-safe way.
Definition AthRNGSvc.h:34
Count the number of events to pass all algorithms/filters.
Definition CountHepMC.h:26
STL class.
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition hcg.cxx:310
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177
checkBlockList(relFlavour, cache, generatorName)
Add special config option (extended model info for BSM scenarios)
_checkattr(attr, required=False)
==============================================================
mk_symlink(srcfile, dstfile)
checkPurpleList(relFlavour, cache, generatorName)
IovVectorMap_t read(const Folder &theFolder, const SelectionCriterion &choice, const unsigned int limit=10)