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