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
164if joparts[0].startswith("mc") and all(c in string.digits for c in joparts[0][2:]):
165
166 if len(joparts) != 3:
167 evgenLog.error(jofile + " name format is wrong: must be of the form MC<xx>.<physicsShort>.py: please rename.")
168 sys.exit(1)
169
170
171 jo_physshortpart = joparts[1]
172 max_jo_physshort_length = 50
173 if len(jo_physshortpart) > max_jo_physshort_length:
174 evgenLog.error(f"{jofile} contains a physicsShort field of more than {max_jo_physshort_length} characters: please rename.")
175 sys.exit(1)
176
177 jo_physshortparts = jo_physshortpart.split("_")
178 if len(jo_physshortparts) < 2:
179 evgenLog.error(jofile + " has too few physicsShort fields separated by '_': should contain <generators>(_<tune+PDF_if_available>)_<process>. Please rename.")
180 sys.exit(1)
181
182 check_jofiles="/cvmfs/atlas.cern.ch/repo/sw/Generators/MCJobOptions/scripts/check_jo_consistency.py"
183 if os.path.exists(check_jofiles):
184 evgenLog.info("Checking offical JO file name consistency")
185 include(check_jofiles)
186 check_naming(os.path.basename(jofile))
187 else:
188 evgenLog.warning("check_jo_consistency.py not found, will proceed without JOs consistency check")
189else:
190 evgenLog.error(jofile + " should be named mc.XXXXXX.*")
191 sys.exit(1)
192
193
194include(jofile)
195include("EvgenJobTransforms/LHEonly.py")
196
197
200
201
202evgenLog.debug("****************** CHECKING EVGEN CONFIGURATION *****************")
203evgenLog.info("****************** CHECKING EVGEN CONFIGURATION *****************")
204
205
206for opt in str(evgenConfig).split(os.linesep):
207 evgenLog.info(opt)
208evgenLog.info(".transform = Gen_tf")
209
210
211evgenLog.info(".platform = "+str(os.environ['BINARY_TAG']))
212
213
216if evgenConfig.obsolete:
217 evgenLog.error("JOs or icludes are obsolete, please check them")
218 sys.exit(1)
219
220if not evgenConfig.generators:
221 evgenLog.error("No entries in evgenConfig.generators: invalid configuration, please check your JO")
222 sys.exit(1)
223
224if len(evgenConfig.generators) > len(set(evgenConfig.generators)):
225 evgenLog.error("Duplicate entries in evgenConfig.generators: invalid configuration, please check your JO")
226 sys.exit(1)
227
228gennames = sorted(evgenConfig.generators, key=gen_sortkey)
229
230if joparts[0].startswith("MC"): #< if this is an "official" JO
231 genpart = jo_physshortparts[0]
232 expectedgenpart = ''.join(gennames)
233
234 expectedgenpart = expectedgenpart.replace("HerwigJimmy", "Herwig")
235 def _norm(s):
236 # TODO: add EvtGen to this normalization for MC14?
237 return s.replace("Photospp", "").replace("Photos", "").replace("TauolaPP", "").replace("Tauolapp", "").replace("Tauola", "")
238 def _norm2(s):
239 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")
240
241 def _short2(s):
242 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")
243
244
245 if genpart != _norm(expectedgenpart) and _norm2(genpart) != _norm(expectedgenpart):
246 evgenLog.error("Expected first part of JO name to be '%s' or '%s', but found '%s'" % (_norm(expectedgenpart), _norm(_short2(expectedgenpart)), genpart))
247 evgenLog.error("gennames '%s' " %(expectedgenpart))
248 sys.exit(1)
249
250 del _norm
251
252 if not gens_notune(gennames) and len(jo_physshortparts) < 3:
253 evgenLog.error(jofile + " with generators " + expectedgenpart +
254 " has too few physicsShort fields separated by '_'." +
255 " It should contain <generators>_<tune+PDF_<process>. Please rename.")
256 sys.exit(1)
257
258
260if gen_require_steering(gennames):
261 if hasattr(runArgs, "outputEVNTFile") and not hasattr(runArgs, "outputEVNT_PreFile"):
262 raise RuntimeError("'EvtGen' found in job options name, please set '--steering=afterburn'")
263
264
265
267rounding = 0
268if hasattr(runArgs,'inputGeneratorFile') and ',' in runArgs.inputGeneratorFile: multiInput = runArgs.inputGeneratorFile.count(',')+1
269else:
270 multiInput = 0
271
272# check if default nEventsPerJob used
273if not evgenConfig.nEventsPerJob:
274 evgenLog.info('#############################################################')
275 evgenLog.info(' !!!! no nEventsPerJob set !!! The default 10000 used. !!! ')
276 evgenLog.info('#############################################################')
277else:
278 evgenLog.info(' nEventsPerJob set to ' + str(evgenConfig.nEventsPerJob) )
279
280if evgenConfig.minevents > 0 :
281 raise RuntimeError("evgenConfig.minevents is obsolete and should be removed from the JOs")
282
283if evgenConfig.nEventsPerJob < 1:
284 raise RunTimeError("evgenConfig.nEventsPerJob must be at least 1")
285else:
286 evgenLog.info("evgenConfig.nEventsPerJob = {}, but only {} (dummy) event(s) will be generated by Pythia8 for lhe-only production".format(evgenConfig.nEventsPerJob, postSeq.CountHepMC.RequestedOutput))
287
288
289
290if not evgenConfig.keywords:
291 evgenLog.warning("No entries in evgenConfig.keywords: invalid configuration, please check your JO !!")
292
293
294if evgenConfig.keywords:
295 from GeneratorConfig.GenConfigHelpers import checkKeywords
296 checkKeywords(evgenConfig, evgenLog)
297
298
299if not evgenConfig.categories:
300 evgenLog.warning("No entries in evgenConfig.categories: invalid configuration, please check your JO !!")
301
302
303if evgenConfig.categories:
304
306 lkwfile = "CategoryList.txt"
307 lkwpath = None
308 for p in os.environ["DATAPATH"].split(":"):
309 lkwpath = os.path.join(p, lkwfile)
310 if os.path.exists(lkwpath):
311 break
312 lkwpath = None
313
314 allowed_cat = []
315 if lkwpath:
316 with open(lkwpath, 'r') as catlist:
317 for line in catlist:
318 allowed_list = ast.literal_eval(line)
319 allowed_cat.append(allowed_list)
320
321
322 bad_cat =[]
323 it = iter(evgenConfig.categories)
324 for x in it:
325 l1 = x
326 l2 = next(it)
327 if "L1:" in l2 and "L2:" in l1:
328 l1, l2 = l2, l1
329 print("first",l1,"second",l2)
330 bad_cat.extend([l1, l2])
331 for a1,a2 in allowed_cat:
332 if l1.strip().lower()==a1.strip().lower() and l2.strip().lower()==a2.strip().lower():
333 bad_cat=[]
334 if bad_cat:
335 msg = "evgenConfig.categories contains non-standard category: %s. " % ", ".join(bad_cat)
336 msg += "Please check the allowed categories list and fix."
337 evgenLog.error(msg)
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})
360svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"hadronizationModel": evgenConfig.hadronizationModel})
361svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"partonShowerModel": evgenConfig.partonShowerModel})
362if hasattr( evgenConfig, "hardPDF" ) : svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"hardPDF": evgenConfig.hardPDF})
363if hasattr( evgenConfig, "softPDF" ) : svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"softPDF": evgenConfig.softPDF})
364if hasattr( runArgs, "randomSeed") : svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"randomSeed": str(runArgs.randomSeed)})
365svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"keywords": ", ".join(evgenConfig.keywords).lower()})
366
367# print version of HepMC to the log
368evgenLog.info("HepMC version " + str(os.environ['HEPMCVER']))
369
370# Set AMITag in in-file metadata
371from PyUtils import AMITagHelper
372AMITagHelper.SetAMITag(runArgs=runArgs)
373
374
375svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"beam_energy": str(int(runArgs.ecmEnergy*Units.GeV/2.0))})
376svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"beam_type": 'collisions'})
377
378
380include("EvgenJobTransforms/Generate_ecmenergies.py")
381
382# Propagate DSID and seed to the generators
383include("EvgenJobTransforms/Generate_dsid_ranseed.py")
384
385
386if (hasattr( runArgs, "VERBOSE") and runArgs.VERBOSE ) or (hasattr( runArgs, "loglevel") and runArgs.loglevel == "DEBUG") or (hasattr( runArgs, "loglevel") and runArgs.loglevel == "VERBOSE"):
387 include("EvgenJobTransforms/Generate_debug_level.py")
388
389
393def checkBlockList(relFlavour,cache,generatorName) :
394 isError = None
395 with open('/cvmfs/atlas.cern.ch/repo/sw/Generators/MCJobOptions/common/BlackList_caches.txt') as bfile:
396 for line in bfile.readlines():
397 if not line.strip():
398 continue
399 # Blocklisted release flavours
400 badRelFlav=line.split(',')[0].strip()
401 # Blocklisted caches
402 badCache=line.split(',')[1].strip()
403 # Blocklisted generators
404 badGens=line.split(',')[2].strip()
405
406 used_gens = ','.join(generatorName)
407 #Match Generator and release type e.g. AtlasProduction, MCProd
408 if relFlavour==badRelFlav and cache==badCache and re.search(badGens,used_gens) is not None:
409 if badGens=="": badGens="all generators"
410 isError=relFlavour+","+cache+" is blocklisted for " + badGens
411 return isError
412 return isError
413
414def checkPurpleList(relFlavour,cache,generatorName) :
415 isError = None
416 with open('/cvmfs/atlas.cern.ch/repo/sw/Generators/MCJobOptions/common/PurpleList_generators.txt') as bfile:
417 for line in bfile.readlines():
418 if not line.strip():
419 continue
420 # Purple-listed release flavours
421 purpleRelFlav=line.split(',')[0].strip()
422 # Purple-listed caches
423 purpleCache=line.split(',')[1].strip()
424 # Purple-listed generators
425 purpleGens=line.split(',')[2].strip()
426 # Purple-listed process
427 purpleProcess=line.split(',')[3].strip()
428
429 used_gens = ','.join(generatorName)
430 #Match Generator and release type e.g. AtlasProduction, MCProd
431 if relFlavour==purpleRelFlav and cache==purpleCache and re.search(purpleGens,used_gens) is not None:
432 isError=relFlavour+","+cache+" is blocklisted for " + purpleGens + " if it uses " + purpleProcess
433 return isError
434 return isError
435
436
437evgenLog.debug("****************** CHECKING RELEASE IS NOT BLACKLISTED *****************")
438rel = os.popen("echo $AtlasVersion").read()
439rel = rel.strip()
440if os.path.exists('/cvmfs/atlas.cern.ch/repo/sw/Generators/MCJobOptions/common'):
441 errorBL = checkBlockList("AthGeneration",rel,gennames)
442 if (errorBL):
443 if (hasattr( runArgs, "ignoreBlackList") and runArgs.ignoreBlackList):
444 evgenLog.warning("This run is blocklisted for this generator, please use a different one for production !! "+ errorBL )
445 else:
446 raise RuntimeError("This run is blocklisted for this generator, please use a different one !! "+ errorBL)
447
448 errorPL = checkPurpleList("AthGeneration",rel,gennames)
449 if (errorPL):
450 evgenLog.warning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
451 evgenLog.warning("!!! WARNING !!! "+ errorPL )
452 evgenLog.warning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
453else:
454 msg.waring("No access to cvmfs, so blocklisted runs will not be checked")
455
456
457
458svcMgr.TagInfoMgr.ExtraTagValuePairs.update({"specialConfiguration": evgenConfig.specialConfig})
459
460
461
463
464
465
468
469if hasattr(runArgs, "postInclude"):
470 for fragment in runArgs.postInclude:
471 include(fragment)
472
473if hasattr(runArgs, "postExec"):
474 evgenLog.info("Transform post-exec")
475 for cmd in runArgs.postExec:
476 evgenLog.info(cmd)
477 exec(cmd)
478
479
482acas.dumpMasterSequence()
483
484
485
488
489
490evgenLog.debug("****************** HANDLING EVGEN INPUT FILES *****************")
491print("****************** HANDLING EVGEN INPUT FILES *****************")
492
493datFile = None
494if "McAtNlo" in evgenConfig.generators and "Herwig" in evgenConfig.generators:
495 datFile = "inparmMcAtNlo.dat"
496elif "Alpgen" in evgenConfig.generators:
497 datFile = "inparmAlpGen.dat"
498elif "Protos" in evgenConfig.generators:
499 datFile = "protos.dat"
500elif "ProtosLHEF" in evgenConfig.generators:
501 datFile = "protoslhef.dat"
502elif "AcerMC" in evgenConfig.generators:
503 datFile = "inparmAcerMC.dat"
504elif "CompHep" in evgenConfig.generators:
505 datFile = "inparmCompHep.dat"
506
507
508if "Alpgen" in evgenConfig.generators:
509 eventsFile = "alpgen.unw_events"
510elif "Protos" in evgenConfig.generators:
511 eventsFile = "protos.events"
512elif "ProtosLHEF" in evgenConfig.generators:
513 eventsFile = "protoslhef.events"
514elif "BeamHaloGenerator" in evgenConfig.generators:
515 eventsFile = "beamhalogen.events"
516elif "HepMCAscii" in evgenConfig.generators:
517 eventsFile = "events.hepmc"
518elif "ReadMcAscii" in evgenConfig.generators:
519 eventsFile = "events.hepmc"
520elif gens_lhef(evgenConfig.generators):
521 #eventsFile = outputTXTFile
522 eventsFile = "events.lhe"
523
524
525
526def find_unique_file(pattern):
527 "Return a matching file, provided it is unique"
528 import glob
529 files = glob.glob(pattern)
530
531 if not files:
532 raise RuntimeError("No '%s' file found" % pattern)
533 elif len(files) > 1:
534 raise RuntimeError("More than one '%s' file found" % pattern)
535 return files[0]
536
537# This function merges a list of input LHE file to make one outputFile. The header is taken from the first
538# file, but the number of events is updated to equal the total number of events in all the input files
539def merge_lhe_files(listOfFiles,outputFile):
540 if(os.path.exists(outputFile)):
541 print ("outputFile ",outputFile," already exists. Will rename to ",outputFile,".OLD")
542 os.rename(outputFile,outputFile+".OLD")
543 output = open(outputFile,'w')
544 holdHeader = ""
545 nevents=0
546 for file in listOfFiles:
547 cmd = "grep /event "+file+" | wc -l"
548 nevents+=int(subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True))
549
550 for file in listOfFiles:
551 inHeader = True
552 header = ""
553 print ("*** Starting file ",file)
554 for line in open(file,"r"):
555
560 if("<event" in line and inHeader):
561 inHeader = False
562 if(len(holdHeader)<1):
563 holdHeader = header
564 output.write(header)
565 output.write(line)
566
568 elif(not inHeader and not ("</LesHouchesEvents>" in line)):
569 output.write(line)
570 if(inHeader):
571
572 if("nevents" in line):
573
574 tmp = line.split("=")
575 line = line.replace(tmp[0],str(nevents))
576 elif("numevts" in line):
577
578 tmp = line.split(" ")
579 nnn = str(nevents)
580 line = line.replace(tmp[1],nnn)
581 header+=line
582 output.write("</LesHouchesEvents>\n")
583 output.close()
584
585def mk_symlink(srcfile, dstfile):
586 "Make a symlink safely"
587 if dstfile:
588 if os.path.exists(dstfile) and not os.path.samefile(dstfile, srcfile):
589 os.remove(dstfile)
590 if not os.path.exists(dstfile):
591 evgenLog.info("Symlinking %s to %s" % (srcfile, dstfile))
592 os.symlink(srcfile, dstfile)
593 else:
594 evgenLog.debug("Symlinking: %s is already the same as %s" % (dstfile, srcfile))
595
596
597if eventsFile or datFile:
598 if not hasattr(runArgs, "inputGeneratorFile") or runArgs.inputGeneratorFile == "NONE":
599 raise RuntimeError("%s needs input file (argument inputGeneratorFile)" % runArgs.jobConfig)
600 if evgenConfig.inputfilecheck and not re.search(evgenConfig.inputfilecheck, runArgs.inputGeneratorFile):
601 raise RuntimeError("inputGeneratorFile=%s is incompatible with inputfilecheck '%s' in %s" %
602 (runArgs.inputGeneratorFile, evgenConfig.inputfilecheck, runArgs.jobConfig))
603 if datFile:
604 if ".tar" in os.path.basename(runArgs.inputGeneratorFile):
605 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".tar.")[0]
606 elif ".tgz" in os.path.basename(runArgs.inputGeneratorFile):
607 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".tgz")[0]
608 elif ".gz" in os.path.basename(runArgs.inputGeneratorFile):
609 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".gz")[0]
610 else:
611 inputroot = os.path.basename(runArgs.inputGeneratorFile).split("._")[0]
612
613 realDatFile = find_unique_file('*%s*.dat' % inputroot)
614 mk_symlink(realDatFile, datFile)
615 if eventsFile:
616 myinputfiles = runArgs.inputGeneratorFile
617 genInputFiles = myinputfiles.split(',')
618 numberOfFiles = len(genInputFiles)
619 # if there is a single file, make a symlink. If multiple files, merge them into one output eventsFile
620 if(numberOfFiles<2):
621 if ".tar" in os.path.basename(runArgs.inputGeneratorFile):
622 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".tar.")[0]
623 elif ".tgz" in os.path.basename(runArgs.inputGeneratorFile):
624 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".tgz")[0]
625 elif ".gz" in os.path.basename(runArgs.inputGeneratorFile):
626 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".gz")[0]
627 else:
628 inputroot = os.path.basename(runArgs.inputGeneratorFile).split("._")[0]
629
630 if "events" in inputroot :
631 inputroot = inputroot.replace(".events","")
632 realEventsFile = find_unique_file('*%s.*ev*ts' % inputroot)
633 mk_symlink(realEventsFile, eventsFile)
634 else:
635 allFiles = []
636 for file in genInputFiles:
637# Since we can have multiple files from the same task, inputroot must include more of the filename
638# to make it unique
639 if ".tar" in os.path.basename(runArgs.inputGeneratorFile):
640 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".tar.")[0]
641 elif ".tgz" in os.path.basename(runArgs.inputGeneratorFile):
642 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".tgz")[0]
643 elif ".gz" in os.path.basename(runArgs.inputGeneratorFile):
644 inputroot = os.path.basename(runArgs.inputGeneratorFile).split(".gz")[0]
645 else:
646 input0 = os.path.basename(file).split("._")[0]
647 input1 = (os.path.basename(file).split("._")[1]).split(".")[0]
648 inputroot = input0+"._"+input1
649 realEventsFile = find_unique_file('*%s.*ev*ts' % inputroot)
650# The only input format where merging is permitted is LHE
651 with open(realEventsFile, 'r') as f:
652 first_line = f.readline()
653 if(not ("LesHouche" in first_line)):
654 raise RuntimeError("%s is NOT a LesHouche file" % realEventsFile)
655 allFiles.append(realEventsFile)
656 merge_lhe_files(allFiles,eventsFile)
657
658else:
659 if hasattr(runArgs, "inputGeneratorFile") and runArgs.inputGeneratorFile != "NONE":
660 raise RuntimeError("inputGeneratorFile arg specified for %s, but generators %s do not require an input file" %
661 (runArgs.jobConfig, str(gennames)))
662# if evgenConfig.inputfilecheck:
663# raise RuntimeError("evgenConfig.inputfilecheck specified in %s, but generators %s do not require an input file" %
664# (runArgs.jobConfig, str(gennames)))
665
666
667if evgenConfig.auxfiles:
668 from PyJobTransformsCore.trfutil import get_files
669 get_files(evgenConfig.auxfiles, keepDir=False, errorIfNotFound=True)
670
671
674
675def _checkattr(attr, required=False):
676 if not hasattr(evgenConfig, attr) or not getattr(evgenConfig, attr):
677 msg = "evgenConfig attribute '%s' not found." % attr
678 if required:
679 raise RuntimeError("Required " + msg)
680 return False
681 return True
682# counting the number of events in LHE output
683count_ev = 0
684with open(eventsFile) as f:
685 for line in f:
686 count_ev += line.count('/event')
687
688evgenLog.info('Requested output events = '+str(count_ev))
689print("MetaData: %s = %s" % ("Number of produced LHE events ", count_ev))
690
691if _checkattr("description", required=True):
692 msg = evgenConfig.description
693 if _checkattr("notes"):
694 msg += " " + evgenConfig.notes
695 print("MetaData: %s = %s" % ("physicsComment", msg))
696if _checkattr("generators", required=True):
697 print ("MetaData: %s = %s" % ("generatorName", "+".join(gennamesvers)))
698if _checkattr("process"):
699 print ("MetaData: %s = %s" % ("physicsProcess", evgenConfig.process))
700if _checkattr("tune"):
701 print ("MetaData: %s = %s" % ("generatorTune", evgenConfig.tune))
702if _checkattr("hadronizationModel"):
703 print ("MetaData: %s = %s" % ("hadronizationModel", evgenConfig.hadronizationModel))
704if _checkattr("partonShowerModel"):
705 print ("MetaData: %s = %s" % ("partonShowerModel", evgenConfig.partonShowerModel))
706if _checkattr("hardPDF"):
707 print ("MetaData: %s = %s" % ("hardPDF", evgenConfig.hardPDF))
708if _checkattr("softPDF"):
709 print ("MetaData: %s = %s" % ("softPDF", evgenConfig.softPDF))
710if _checkattr("nEventsPerJob"):
711 print ("MetaData: %s = %s" % ("nEventsPerJob", evgenConfig.nEventsPerJob))
712if _checkattr("keywords"):
713 print ("MetaData: %s = %s" % ("keywords", ", ".join(evgenConfig.keywords).lower() ))
714if _checkattr("categories"):
715 print ( ", " + ", ".join(evgenConfig.categories))
716else:
717 print (" ")
718
719#if _checkattr("categories"): # will be uncommented when categories included into metadata
720# print "MetaData: %s = %s" % ("categories", ", ".join(evgenConfig.categories))
721if _checkattr("specialConfig"):
722 print ("MetaData: %s = %s" % ("specialConfig", evgenConfig.specialConfig))
723# TODO: Require that a contact / JO author is always set
724if _checkattr("contact"):
725 print ("MetaData: %s = %s" % ("contactPhysicist", ", ".join(evgenConfig.contact)))
726#if _checkattr( "randomSeed") : # comment out for the time being
727print ("MetaData: %s = %s" % ("randomSeed", str(runArgs.randomSeed)))
728
729
730
731
732# Output list of generator filters used
733filterNames = [alg.getType() for alg in acas.iter_algseq(filtSeq)]
734excludedNames = ['AthSequencer', 'PyAthena::Alg', 'TestHepMC']
735filterNames = list(set(filterNames) - set(excludedNames))
736print ("MetaData: %s = %s" % ("genFilterNames", ", ".join(filterNames)))
737
738
739
742
743from PyJobTransformsCore.runargs import RunArguments
744runPars = RunArguments()
745runPars.nEventsPerJob = evgenConfig.nEventsPerJob
746runPars.maxeventsstrategy = evgenConfig.maxeventsstrategy
747with open("config.pickle", "wb") as f:
748 import pickle
749 pickle.dump(runPars, f)
750
751
752
755
756evgenLog.debug("****************** STARTING EVENT GENERATION *****************")
757print ("****************** STARTING EVENT GENERATION *****************")
758print ("**************************************************************")
759print ("****************** PLEASE IGNORE THE LOG FROM PYTHIA ************")
760print ("****************** GENERATION OF ONE PYTHIA EVENT ***************")
761print ("******************** IS NEEDED TO MAKE *************")
762print ("****************** THE TRANSFORM WORK ***************************")
763print ("**************************************************************")
if(pathvar)
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:312
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:179
checkBlockList(relFlavour, cache, generatorName)
Add special config option (extended model info for BSM scenarios).
checkPurpleList(relFlavour, cache, generatorName)
_checkattr(attr, required=False)
==============================================================
mk_symlink(srcfile, dstfile)
IovVectorMap_t read(const Folder &theFolder, const SelectionCriterion &choice, const unsigned int limit=10)