CMS 3D CMS Logo

cmsRelvalreportInput.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 # GBenelli Dec 21, 2007 and JNicolson July 23, 2008
4 # This script is designed to run on a local directory
5 # after the user has created a local CMSSW release,
6 # initialized its environment variables by executing
7 # in the release /src directory:
8 # eval `scramv1 runtime -csh`
9 # project CMSSW
10 # The script will create a SimulationCandles_$CMSSW_VERSION.txt ASCII
11 # file, input to cmsRelvalreport.py, to launch the
12 # Performance Suite.
13 
14 # Input arguments are three:
15 # 1-Number of events to put in the cfg files
16 # 2-Name of the candle(s) to process (either AllCandles, or NameOfTheCandle)
17 # 3-Profiles to run (with code below)
18 # E.g.: ./cmsRelValReportInput.py 50 AllCandles 012
19 
20 ###############
21 # Import modules and define functions
22 #
23 
24 from __future__ import print_function
25 from builtins import range
26 import sys, os, re, operator
27 import optparse as opt
28 from cmsPerfCommons import Candles, CandDesc, FileName, KeywordToCfi, CustomiseFragment, CandFname, EventContents
29 from functools import reduce
30 ################
31 # Global variables
32 #
33 
34 THIS_PROG_NAME = os.path.basename(sys.argv[0])
35 cmsDriver = 'cmsDriver.py' #cmsDriver.py path
36 hypreg = re.compile('-')
37 debug = False
38 DEF_STEPS = ['GEN,SIM', 'DIGI']
39 AllSteps = ["GEN,SIM", "DIGI", "L1", "DIGI2RAW", "HLT", "RAW2DIGI","RECO"]
40 AfterPileUpSteps=[]
41 
42 # Global variables used by writeCommandsToReport and dependents
43 
44 # Hash for the profiler to run
45 
46 Profiler = {
47  'TimingReport' : 'Timing_Parser',
48  'TimingReport @@@ reuse' : 'Timing_Parser',
49  'TimeReport' : 'Timereport_Parser',
50  'TimeReport @@@ reuse' : 'Timereport_Parser',
51  'SimpleMemReport' : 'SimpleMem_Parser',
52  'EdmSize' : 'Edm_Size',
53  'IgProfperf' : 'IgProf_perf.PERF_TICKS',
54  'IgProfperf @@@ reuse' : 'IgProf_perf.PERF_TICKS',
55  'IgProfMemTotal' : 'IgProf_mem.MEM_TOTAL',
56  'IgProfMemTotal @@@ reuse': 'IgProf_mem.MEM_TOTAL',
57  'IgProfMemLive' : 'IgProf_mem.MEM_LIVE',
58  'IgProfMemLive @@@ reuse' : 'IgProf_mem.MEM_LIVE',
59  'IgProfMemMax' : 'IgProf_mem.MEM_MAX',
60  'IgProfMemMax @@@ reuse' : 'IgProf_mem.MEM_MAX',
61  'IgProfMemAnalyse' : 'IgProf_mem.ANALYSE',
62  'valgrind' : 'ValgrindFCE',
63  'memcheck_valgrind' : 'Memcheck_Valgrind',
64  'None' : 'None',
65 }
66 
67 
68 
69 def getFstOccur(item, list):
70  return filter(item.__eq__,list)[0]
71 
72 def getLstIndex(item, list):
73  lenlist = len(list)
74  for x in range(lenlist - 1,0,-1):
75  if list[x] == item:
76  return x
77 
78 def checkSteps(steps):
79  '''Checks user steps <steps> for order against steps defined in AllSteps list.
80  If they are not, prints a warning and exits.
81  No return value.'''
82 
83  #print steps
84  #if ":" in steps:
85  # steps.split(
86  idx = -2
87  lstidx = -2
88  for step in steps:
89  astep = step
90  split = []
91  #Added special workflow for GEN-FASTSIM, bypass the check of step order:
92  if step=="GEN,FASTSIM":
93  pass
94  else:
95  if "-" in step:
96  split = astep.split("-")
97  astep = split[0].split(":")[0]
98  # print "This is astep:%s"%astep
99  #idx =AllSteps.index("GEN,SIM")
100  #print idx
101  #print astep
102  idx = AllSteps.index(astep.split(":")[0])
103  if not ( idx == -2 ):
104  if lstidx > idx:
105  print("ERROR: Your user defined steps are not in a valid order")
106  sys.exit()
107  lstidx = idx
108  if "-" in step:
109  lstidx = AllSteps.index(split[1].split(":")[0])
110 
111 
112 def getSteps(userSteps):
113  '''Analyzes the steps in <userSteps> to translate the cmsRelvalreportInput.py --step option into the cmsDriver.py one. Expanding hyphens for combined steps.
114  Handle the exceptional cases of GEN-, GEN-SIM and GEN-FASTSIM (GEN is never profiled by itself).
115  Returns a list of steps <steps>.'''
116  #Add handling of ":" in steps
117  #print userSteps
118  # Then split the user steps into "steps"
119  gsreg = re.compile('GEN-SIM')
120  greg = re.compile('GEN') #Add a second hack (due to the first) to handle the step 1 case GEN-HLT
121  gfsreg = re.compile('GEN-FASTSIM') #Add a third hack to handle the case GEN-FASTSIM workflow
122  StepsTokens = userSteps.split(",")
123  steps = []
124  for astep in StepsTokens:
125 
126  # Then transform the combined steps (GEN-SIM, RAW2DIGI-RECO)
127  # from using the "-" to using the "," to match cmsDriver.py convention
128 
129  if gsreg.search(astep):
130  astep = gsreg.sub(r"GEN,SIM", astep)
131  elif gfsreg.search(astep):
132  astep = gfsreg.sub(r"GEN,FASTSIM", astep) #could add protection for user screw-ups
133  elif greg.search(astep):
134  astep = greg.sub(r"GEN,SIM", astep)
135 
136 
137  #print astep
138  # Finally collect all the steps into the steps list:
139 
140  steps.append(astep)
141 
142  #steps = expandHypens(steps)
143  checkSteps(steps)
144  return steps
145 
147  global _noprof
148  explanations = map(lambda x: " " + x, Candles)
149  explanation = ""
150  for x in range(len(explanations)):
151  explanation += "%-*s %s\n" % (30, explanations[x],CandDesc[x])
152  parser = opt.OptionParser(usage=("""%s NUM_EVENTS_PER_CFG CANDLES PROFILE [--cmsdriver=cmsDriverOptions] [--usersteps=processingStepsOption]
153 
154  Description - This program creates a configuration file for cmsRelvalreport.py that describes the order in which cmsDriver.py should be run with which candles, steps and profiling so that time spent running cmsDriver.py is minimised. Without this correct ordering we would have to re-run parts of the profiling steps.
155 
156  Arguments:
157  NUM_EVENTS_PER_CFG - The number of events per config file
158 
159  CANDLES - The simulation type to perform profiling on
160  Candles Description
161  AllCandles Run all of the candles below
162 %s
163 
164  PROFILE - the type of profiling to perform (multiple codes can be used):
165  Code Profile Type
166  0 TimingReport
167  1 TimeReport
168  2 SimpleMemoryCheck
169  3 EdmSize
170  4 IgProfPerf
171  5 IgProfMemTotal
172  6 IgProfMemLive
173  7 IgProfAnalyse
174  8 ValgrindFCE
175  9 ValgrindMemCheck
176 
177  Examples (could be obsolete!):
178  Perform Timing Report profiling for all candles, all steps and 10 events per cfg.
179  ./%s 10 AllCandles 1 \"--conditions FakeConditions --eventcontent FEVTDEBUGHLT\"
180  Perform Timing Report, Time Report and SimpleMemoryCheck profiling for HiggsZZ4LM200, all steps and 50 events.
181  ./%s 50 \"HiggsZZ4LM200\" 012 \"--conditions FakeConditions --eventcontent FEVTDEBUGHLT\"
182  Perform IgProfPerf and IgProfMemTotal profiling for TTbar, all steps and 100 events.
183  ./%s 100 \"TTbar\" 45 --cmsdriver=\"--conditions FakeConditions --eventcontent RAWRECO\"
184  Perform ValgrindFCE ValgrindMemCheck profiling for Minimum bias and 100 events. Only on GEN,SIM and DIGI steps.
185  ./%s 100 \"MinBias\" 89 --cmsdriver=\"--conditions FakeConditions --eventcontent RAWSIM\" \"--usersteps=GEN-SIM,DIGI"""
186  % ( THIS_PROG_NAME, explanation, THIS_PROG_NAME,THIS_PROG_NAME,THIS_PROG_NAME,THIS_PROG_NAME)))
187 
188  devel = opt.OptionGroup(parser, "Developer Options",
189  "Caution: use these options at your own risk."
190  "It is believed that some of them bite.\n")
191  #parser.set_defaults(debug=False)
192 
193  parser.add_option(
194  '-b',
195  '--bypass-hlt',
196  action="store_true",
197  dest='bypasshlt',
198  default=False,
199  help='Should we bypass using the HLT root file?'
200  )
201 
202  parser.add_option(
203  '-u',
204  '--usersteps',
205  type='string',
206  dest='userSteps',
207  help='Which steps to run',
208  metavar='<STEPS>',
209  )
210  parser.add_option(
211  '-c',
212  '--cmsdriver',
213  type='string',
214  dest='cmsDriverOptions',
215  help='Option for cmsDriver.py can be specified as a string to be added to all cmsDriver.py commands',
216  metavar='<CONDITION>',
217  )
218  parser.add_option(
219  '-i',
220  '--filein',
221  type='string',
222  dest='userInputFile',
223  help='Eventual input file (for now to be only used with HLT and RAW2DIGI-RECO workflows)',
224  default='',
225  metavar='<INPUTFILE>',
226  )
227  devel.add_option(
228  '-1',
229  '--no-profile',
230  action="store_true",
231  dest='noprof',
232  help='Do not perform profiling, ever',
233  #metavar='DEBUG',
234  )
235 
236  devel.add_option(
237  '-d',
238  '--debug',
239  action="store_true",
240  dest='debug',
241  help='Show debug output',
242  #metavar='DEBUG',
243  )
244 
245  parser.set_defaults(debug=False,noprof=False)
246  parser.add_option_group(devel)
247 
248  (options, args) = parser.parse_args()
249 
250 
251  _noprof = options.noprof
252  debug = options.debug
253  numofargs = len(args)
254 # print "runtime cmsinput " + str(numofargs) + " noprof " + str(_noprof)
255  if ((not numofargs == 3) and (not _noprof)) or (_noprof and not (numofargs == 2)):
256  parser.error("There are not enough arguments specified to run this program."
257  " Please determine the correct arguments from the usage information above."
258  " Run with --help option for more information.")
259  sys.exit()
260 
261  return (options, args)
262 
263 def expandHyphens(step):
264  newsteps = []
265 # for step in steps:
266  if "-" in step:
267  hypsteps = step.split(r"-")
268  #if not (len(hypsteps) == 2):
269  # print "ERROR: Could not parse usersteps. You have too many hypens between commas"
270  # sys.exit()
271  #el
272  if not reduce(lambda x,y,: x and y,map(lambda x: x.split(":")[0] in AllSteps, hypsteps)):
273  #(hypsteps[0].split(":")[0] in AllSteps and hypsteps[1].split(":") in AllSteps):
274  print("ERROR: One of the steps you defined is invalid")
275  sys.exit()
276  else:
277  if (hypsteps[0] == hypsteps[1]):
278  print("WARNING: You should not add a hypenated step that as the same source and destination step, ignoring")
279  newsteps.append(hypsteps[0])
280  else:
281  newsteps.append(hypsteps[0])
282 
283  srt = AllSteps.index(hypsteps[0].split(":")[0]) + 1
284  for n in range(srt,AllSteps.index(hypsteps[-1].split(":")[0])):
285  astep = AllSteps[n]
286  if astep in ( hypsteps[i].split(":")[0] for i in range(1,len(hypsteps))):
287  #break
288  astep=filter(lambda x: astep == x.split(":")[0],hypsteps)[0]
289  if astep==hypsteps[-1].split(":")[0]:
290  break
291  newsteps.append(astep)
292  newsteps.append(hypsteps[-1])
293  else:
294  if not (step.split(":")[0] in AllSteps):
295  print("ERROR: One of the steps you defined is invalid")
296  sys.exit()
297  else:
298  newsteps.append(step)
299 
300  return newsteps
301 
302 def setupProgramParameters(options,args):
303  steps = []
304  cmsDriverOptions = ""
305  global AfterPileUpSteps
306  NumberOfEvents = int(args[0]) # first arg
307  WhichCandles = str(args[1]) # second arg
308  ProfileCode = ""
309  if not _noprof:
310  ProfileCode = str(args[2]) # third arg
311 
312  if options.cmsDriverOptions:
313 
314  cmsDriverOptions = options.cmsDriverOptions
315  print('Using user-specified cmsDriver.py options: ' + cmsDriverOptions)
316 
317  if options.userSteps:
318 
319  userSteps = options.userSteps
320  steps = getSteps(userSteps)
321 
322  if WhichCandles.lower() == 'allcandles':
323  Candle = Candles
324  print('ALL standard simulation candles will be PROCESSED:')
325  else:
326  Candle = [WhichCandles]
327  print('Candle %s will be PROCESSED' % Candle[0])
328 
329  # For now the two steps are built in, this can be added as an argument later
330  # Added the argument option so now this will only be defined if it was not defined already:
331 
332  if not steps:
333  print('The default steps will be run:')
334  steps = DEF_STEPS
335  else:
336  print("You defined your own steps to run:")
337 
338  for astep in steps:
339  print(astep)
340 
341  return (NumberOfEvents, ProfileCode, cmsDriverOptions, steps, Candle, options.bypasshlt,options.userInputFile)
342 
343 def init_vars():
344 
345  ####################
346  # Obtain required environment variables
347  #
348 
349  try:
350  CMSSW_BASE = os.environ['CMSSW_BASE']
351  CMSSW_RELEASE_BASE = os.environ['CMSSW_RELEASE_BASE']
352  CMSSW_VERSION = os.environ['CMSSW_VERSION']
353  except KeyError:
354  print('Error: An environment variable either CMSSW_{BASE, RELEASE_BASE or VERSION} is not available.')
355  print(' Please run eval `scramv1 runtime -csh` to set your environment variables')
356  sys.exit()
357 
358  return ( CMSSW_BASE,
359  CMSSW_RELEASE_BASE,
360  CMSSW_VERSION)
361 
362 def writeReportFileHeader(CMSSW_VERSION,CMSSW_RELEASE_BASE,CMSSW_BASE):
363 
364  SimCandlesFile = 'SimulationCandles_%s.txt' % CMSSW_VERSION
365 
366  try:
367  simcandles = open(SimCandlesFile, 'w')
368  except IOError:
369  print("Couldn't open %s to save" % SimCandlesFile)
370 
371  simcandles.write('#Candles file automatically generated by %s for %s\n'
372  % (THIS_PROG_NAME, CMSSW_VERSION))
373  simcandles.write("#CMSSW Base : %s\n" % CMSSW_BASE)
374  simcandles.write("#Release Base: %s\n" % CMSSW_RELEASE_BASE)
375  simcandles.write("#Version : %s\n\n" % CMSSW_VERSION)
376 
377  return simcandles
378 
379 def getProfileArray(ProfileCode):
380 
381  Profile = []
382 
383  # The allowed profiles are:
384 
385  AllowedProfile = [
386  'TimingReport',
387  'TimeReport',
388  'SimpleMemReport',
389  'EdmSize',
390  'IgProfperf',
391  'IgProfMemTotal',
392  'IgProfMemLive',
393  #'IgProfMemMax', #Should add this here... but instead of changing the profile code numbers (really should, using options instead of numbers...) I am hacking the IgProfMemLive one: when this one is selected I will also include the IgProfMemMax profile (and analysis is analyse is there)
394  'IgProfMemAnalyse',
395  'valgrind',
396  'memcheck_valgrind',
397  'None',
398  ]
399 
400  if _noprof:
401  Profile.append(AllowedProfile[-1])
402  else:
403  #FIXME:
404  #Horrible code!
405  for i in range(10):
406  if str(i) in ProfileCode:
407  firstCase = (i == 0 and (str(1) in ProfileCode or str(2) in ProfileCode)) \
408  or (i == 1 and str(2) in ProfileCode)
409  secCase = (i==4 and str(7) in ProfileCode) \
410  or (i == 5 and (str(6) in ProfileCode or str(7) in ProfileCode)) \
411  or (i == 6 and str(7) in ProfileCode)
412 
413  if firstCase or secCase:
414  Profile.append(AllowedProfile[i] + ' @@@ reuse')
415  #Here's the hack:
416  if i==6: #i.e. IgProfMemLive
417  Profile.append("IgProfMemMax @@@ reuse")
418  else:
419  Profile.append(AllowedProfile[i])
420  if i==6: #i.e. IgProfMemLive
421  Profile.append("IgProfMemMax")
422 
423  return Profile
424 
425 def writeStepHead(simcandles,acandle,step):
426  simcandles.write('#%s\n' % FileName[acandle])
427  simcandles.write('#Step %s\n' % step)
428  #print step
429 
430 
431 def determineNewProfile(step,Profile,SavedProfile):
432  if 'DIGI2RAW' in step:
433  SavedProfile = Profile
434  Profile = [ ]
435  if 'HLT' in step:
436  Profile = SavedProfile
437 
438  return (Profile, SavedProfile)
439 
440 def pythonFragment(step,cmsdriverOptions):
441  # Convenient CustomiseFragment dictionary to map the correct customise Python fragment for cmsDriver.py:
442  #It is now living in cmsPerfCommons.py!
443 
444  if "--pileup" in cmsdriverOptions and not (step == "HLT" or step.startswith("RAW2DIGI")):
445  return CustomiseFragment['DIGI-PILEUP']
446  elif step in CustomiseFragment:
447  return CustomiseFragment[step]
448  else:
449  #This is a safe default in any case,
450  #the maintenance of the customise python fragments goes into cmsPerfCommons.py
451  return CustomiseFragment['DIGI']
452 
453 
454 def setInputFile(steps,step,acandle,stepIndex,pileup=False,bypasshlt=False):
455  #print "StepIndex 2:%s"%stepIndex
456  InputFileOption = ""
457  if pileup and stepIndex == 0:
458  InputFileOption = "--filein file:%s_%s" % ( FileName[acandle],"DIGI" )
459  else:
460  InputFileOption = "--filein file:%s_%s" % ( FileName[acandle],steps[stepIndex - 1] )
461 
462  if pileup:
463  pass
464  else :
465  if 'GEN,SIM' in step: # there is no input file for GEN,SIM!
466  InputFileOption = ''
467  if 'GEN,FASTSIM' in step: # there is no input file for GEN,FASTSIM!
468  InputFileOption = ''
469  elif 'HLT' in steps[stepIndex - 1] and bypasshlt:
470 
471  # Special hand skipping of HLT since it is not stable enough, so it will not prevent
472  # RAW2DIGI,RECO from running
473 
474  InputFileOption = "--filein file:%s_%s" % ( FileName[acandle],steps[stepIndex - 2] )
475 
476  if not InputFileOption == "" :
477  InputFileOption += ".root "
478 
479  return InputFileOption
480 
481 def writeUnprofiledSteps(simcandles,CustomisePythonFragment,cmsDriverOptions,unprofiledSteps,previousOutputFile,acandle,NumberOfEvents, stepIndex, pileup,bypasshlt):
482  # reduce(lambda x,y : x + "," + "y",unprofiledSteps)
483  #stepsStr = ",".join(unprofiledSteps)
484 
485 
486  #print "unprofiledSteps is %s"%unprofiledSteps
487  #print "22acandle is %s"%acandle
488  #Kludge in case -b option to skip HLT is used...
489  if bypasshlt and unprofiledSteps[-1]=="HLT":
490  stepsStr = ",".join(unprofiledSteps[:-1])
491  OutputFile = "%s_%s.root" % ( FileName[acandle],unprofiledSteps[-2])
492  else:
493  stepsStr = ",".join(unprofiledSteps)
494  OutputFile = "%s_%s.root" % ( FileName[acandle],unprofiledSteps[-1])
495  simcandles.write("\n#Run a %s step(s) that has not been selected for profiling but is needed to run the next step to be profiled\n" % (stepsStr))
496  OutputFileOption = "--fileout=%s" % OutputFile
497  #Bug here: should take into account the flag --bypass-hlt instead of assuming hlt should be bypassed
498  #This affects the Step1/Step2 running since Step1 will produce an HLT.root file and Step2 should start from there!
499  #Adding the argument bypasshlt to the calls...
500  #PreviousInputFile=AllSteps[AllSteps.index(unprofiledSteps[0])-1]
501  #print "StepIndex 1:%s"%stepIndex
502  #Correcting a bug: when unprofiled intermediate steps are present it would skip 1 step...
503  #stepIndexAdjust=stepIndex - 2
504  #if stepIndexAdjust < 0: #To avoid issues with negative indeces
505  # stepIndexAdjust=0
506  #InputFileOption = setInputFile(AllSteps,unprofiledSteps[0],acandle,stepIndexAdjust,bypasshlt=bypasshlt)
507  #Use an argument to make it easier:
508  InputFileOption = "--filein file:" + previousOutputFile
509  if previousOutputFile =="":
510  InputFileOption = setInputFile(AllSteps,unprofiledSteps[0],acandle,stepIndex,pileup=pileup,bypasshlt=bypasshlt)
511  #Introduce an over-ride of cmsDriverOptions:
512  #For the case of unprofiled steps, always run them with FEVTDEBUGHLT eventcontent
513  #At the moment the only use case is when running step2 on its own...
514  for eventcontent in EventContents:
515  cmsDriverOptions=re.sub(eventcontent,'FEVTDEBUGHLT',cmsDriverOptions)
516  Command = ("%s %s -n %s --step=%s %s %s --customise=%s %s"
517  % (cmsDriver,
518  KeywordToCfi[acandle],
519  NumberOfEvents,
520  stepsStr,
521  InputFileOption,
522  OutputFileOption,
523  CustomisePythonFragment,
524  cmsDriverOptions) )
525  simcandles.write( "%s @@@ None @@@ None\n\n" % (Command))
526  return OutputFile
527 
528 def writePrerequisteSteps(simcandles,steps,acandle,NumberOfEvents,cmsDriverOptions,pileup,bypasshlt):
529  fstIdx = -1
530  #Hack for GEN-FASTSIM workflow:
531  #if steps=="GEN,FASTSIM":
532  #if "-" in steps[0]:
533  fstIdx = AllSteps.index(steps[0].split("-")[0].split(":")[0])
534  #else:
535  # fstIdx = AllSteps.index(steps[0])
536  CustomisePythonFragment = pythonFragment("GEN,SIM",cmsDriverOptions)
537  previousOutputFile=""
538  OutputFile = writeUnprofiledSteps(simcandles, CustomisePythonFragment, cmsDriverOptions,AllSteps[0:fstIdx],previousOutputFile,acandle,NumberOfEvents, 0,pileup,bypasshlt)
539  return (fstIdx, OutputFile)
540 
541 def setOutputFileOption(acandle,endstep):
542  return "%s_%s.root" % ( FileName[acandle],endstep)
543 
544 def writeCommands(simcandles,
545  Profile,
546  acandle,
547  steps,
548  NumberOfEvents,
549  cmsDriverOptions,
550  bypasshlt,
551  stepIndex = 0,
552  pileup = False,
553  userInputFile=""):
554  #print "a:%s,b:%s,c:%s"%(stepIndex,pileup,userInputFile)
555  OutputStep = ""
556 
557  stopIndex = len(steps)
558  start = 0
559 
560  userSteps = steps
561  SavedProfile = []
562  fstROOTfile = True
563  fstROOTfileStr = ""
564 
565  #Handling the case of the first user step not being the first step (GEN,SIM):
566  #print "Steps passed to writeCommands %s",steps
567  #Special case for FASTSIM:
568  if (steps[0] == "GEN,FASTSIM"):
569  start=-1
570  stopIndex=1
571  steps = ["GEN,FASTSIM"]
572  else:
573  if not (steps[0] == AllSteps[0]) and (steps[0].split("-")[0] != "GEN,SIM"):
574  #print "userInputFile: %s"%userInputFile
575  if ("--pileup" in cmsDriverOptions) and (steps[0]=="HLT" or steps[0].startswith("RAW2DIGI")) :
576  userInputFile = "../INPUT_PILEUP_EVENTS.root"
577  stepIndex=AllSteps.index(steps[0].split("-")[0].split(":")[0])
578  rootFileStr=""
579 
580  elif userInputFile == "":
581  #Write the necessary line to run without profiling all the steps before the wanted ones in one shot:
582  (stepIndex, rootFileStr) = writePrerequisteSteps(simcandles,steps,acandle,NumberOfEvents,cmsDriverOptions,pileup,bypasshlt)
583  else: #To be implemented if we want to have input file capability beyond the HLT and RAW2DIGI-RECO workflows
584  #if "-" in steps[0]:
585  stepIndex=AllSteps.index(steps[0].split("-")[0].split(":")[0])
586  #print "Here!"
587  #else:
588  #print "There!"
589  # stepIndex=AllSteps.index(steps[0])
590  rootFileStr=""
591  #Now take care of setting the indeces and input root file name right for the profiling part...
592  if fstROOTfile:
593  fstROOTfileStr = rootFileStr
594  fstROOTfile = False
595  start = -1
596  #if "-" in steps[0]:
597  start = AllSteps.index(steps[0].split("-")[0].split(":")[0])
598  #else:
599  # start = AllSteps.index(steps[0])
600  lst = - 1
601  if "-" in steps[-1]:
602  lst = AllSteps.index(steps[-1].split("-")[1].split(":")[0]) #here we are assuming that - is always between two steps no GEN-SIM-DIGI, this is GEN-DIGI
603  else:
604  lst = AllSteps.index(steps[-1])
605  runSteps = AllSteps[start:lst]
606  numOfSteps = (lst - start) + 1
607  stopIndex = start + numOfSteps
608  #Handling the case in which the first user step is the same as the first step (GEN,SIM)
609  #elif not (steps[0] == AllSteps[0]) and (steps[0].split("-")[0] == "GEN"):
610  else:
611  #Handling the case of the last step being a composite one:
612  if "-" in steps[-1]:
613  #Set the stop index at the last step of the composite step (WHY???)
614  stopIndex = AllSteps.index(steps[-1].split("-")[1].split(":")[0]) + 1
615  else:
616 
617  stopIndex = AllSteps.index(steps[-1].split(":")[0]) + 1
618  #print "Last step is %s and stopIndex is %s"%(steps[-1],stopIndex)
619  steps = AllSteps
620 
621  unprofiledSteps = []
622  rawreg = re.compile("^RAW2DIGI")
623 
624 #Horrible structure... to be rewritten sooner or later...
625 
626 # FOR step in steps
627 
628  prevPrevOutputFile = ""
629  #Add if to introduce the possibility to run on user selected input file.
630  if userInputFile!="":
631  previousOutputFile=userInputFile
632  else:
633  previousOutputFile = ""
634 
635  for x in range(start,stopIndex,1):
636  if stepIndex >= stopIndex:
637  break
638  step = steps[stepIndex]
639 
640  # One shot Profiling variables
641  befStep = step
642  aftStep = step
643  # We need this in case we are running one-shot profiling or for DIGI-PILEUP
644  stepToWrite = step
645 
646  CustomisePythonFragment = pythonFragment(step,cmsDriverOptions)
647  oneShotProf = False
648  hypsteps = []
649 
650  #Looking for step in userSteps, or for composite steps that step matches the first of a composite step in userSteps
651  if step in userSteps or reduce(lambda x,y : x or y,map(lambda x: step == x.split("-")[0].split(":")[0],userSteps)):
652 
653  if "GEN,FASTSIM" in userSteps: # HLT/L1 menu workaround
654  stepToWrite = stepToWrite + ",HLT:GRun"
655  elif "HLT" in userSteps:
656  stepToWrite = stepToWrite.replace("HLT", "HLT:GRun")
657 
658  #Checking now if the current step matches the first of a composite step in userSteps
659  hypMatch = [x for x in [x for x in userSteps if step == x.split("-")[0]] if "-" in x]
660  if not len(hypMatch) == 0 :
661  hypsteps = expandHyphens(hypMatch[0])
662  #print hypsteps
663  #print hypMatch[0]
664  stepToWrite = ",".join(hypsteps)
665  if "GEN,SIM-HLT" in userSteps: # HLT/L1 menu workaround
666  stepToWrite = stepToWrite.replace("HLT","HLT:GRun")
667  befStep = hypsteps[0]
668  #Kludge to avoid running HLT in composite steps if the -b option is chosen
669  if bypasshlt and hypsteps[-1]=='HLT':
670  aftStep = hypsteps[-2]
671  else:
672  aftStep = hypsteps[-1]
673  oneShotProf = True
674  if [x for x in userSteps if stepToWrite==x.split(":")[0]]:
675  #print "Inside the filter if!"
676  #print stepToWrite
677  #Here we are assuming that the steps specified with : are not duplicate in the userSteps command:
678  #i.e. GEN-DIGI:SequenceA,HLT:1E31 is OK
679  #GEN-DIGI:SequenceA,HLT:SequenceB,HLT:1E31 IS NOT (OF COURSE!)
680  stepToWrite=filter(lambda x: stepToWrite==x.split(":")[0],userSteps)[0]
681  #print stepToWrite
682 
683  writeStepHead(simcandles,acandle,stepToWrite)
684 
685  #Set the output file name for Pile up and for regular case:
686  if "GEN,SIM-HLT" or "GEN,FASTSIM" or "HLT" in userSteps: # change to make root file output work (without colons)
687  stepToWrite = stepToWrite.replace(":","=")
688 
689  if '--pileup' in cmsDriverOptions:
690  outfile = stepToWrite + "_PILEUP"
691  else:
692  outfile = stepToWrite
693 
694  #print stepToWrite
695 
696  if "GEN,SIM-HLT" or "GEN,FASTSIM" or "HLT" in userSteps: # change it back
697  stepToWrite = stepToWrite.replace("=",":")
698 
699  OutputFile = setOutputFileOption(acandle,outfile)
700  if fstROOTfile:
701  fstROOTfileStr = OutputFile
702  fstROOTfile = False
703  OutputFileOption = "--fileout=" + OutputFile
704 
705  for prof in Profile:
706  #First prepare the cmsDriver.py command
707 
708  #Special case of EventEdmSize profiling
709  if 'EdmSize' in prof:
710  EdmFile = "%s_%s.root" % (FileName[acandle],outfile) #stepToWrite) #Bug in the filename for EdmSize for PileUp corrected.
711  #EventEdmSize needs a pre-requisite step that just produces the root file if one decided to run with only EdmSize profiling!
712  if prof == Profile[0] and not os.path.exists("./" + EdmFile):
713  # insert command to generate required state ( need to run one more step
714  # so that EDM can actually check the size of the root file
715  # If the first step to be profiled is something later on in the steps such
716  # as HLT then writePrerequisteSteps() should have got you to the step prior to
717  # HLT, therefore the only thing left to run to profile EDMSIZE is HLT itself
718 
719  InputFileOption = "--filein file:" + previousOutputFile
720  #Kludge to bypass HLT output... here's a problem... since the unprofiled steps could contain HLT!
721  if rawreg.search(step) and bypasshlt and 'DIGI2RAW.root' in prevPrevOutputFile:
722  InputFileOption = "--filein file:" + prevPrevOutputFile
723  if previousOutputFile == "":
724  InputFileOption = setInputFile(steps,stepToWrite,acandle,stepIndex,pileup=pileup,bypasshlt=bypasshlt)
725  Command = ("%s %s -n %s --step=%s %s %s --customise=%s %s"
726  % (cmsDriver,
727  KeywordToCfi[acandle],
728  NumberOfEvents,
729  stepToWrite,
730  InputFileOption,
731  OutputFileOption,
732  CustomisePythonFragment,
733  cmsDriverOptions) )
734  simcandles.write( "%s @@@ None @@@ None\n" % (Command))
735 
736  Command = EdmFile
737  #all other profiles:
738  else:
739  InputFileOption = "--filein file:" + previousOutputFile
740  if rawreg.search(step) and bypasshlt and 'DIGI2RAW.root' in prevPrevOutputFile:
741  InputFileOption = "--filein file:" + prevPrevOutputFile
742 
743  if previousOutputFile == "":
744  InputFileOption = setInputFile(steps,befStep,acandle,stepIndex,pileup,bypasshlt)
745 
746  #if '--pileup' in cmsDriverOptions:
747  # stepToWrite = pileupStep
748  if '--pileup' in cmsDriverOptions and ( stepToWrite=='GEN,SIM' or stepToWrite=='SIM'):
749  Command = ("%s %s -n %s --step=%s %s %s --customise=%s %s" % (
750  cmsDriver,
751  KeywordToCfi[acandle],
752  NumberOfEvents,
753  stepToWrite,
754  InputFileOption,
755  OutputFileOption,
756  CustomiseFragment['GEN,SIM'],#Done by hand to avoid silly use of MixinModule.py for pre-digi individual steps
757  cmsDriverOptions[:cmsDriverOptions.index('--pileup')]
758  ))
759  elif '--pileup' in cmsDriverOptions and (stepToWrite=='GEN,FASTSIM' or stepToWrite=='GEN,FASTSIM,HLT:GRun'): #Adding GEN,FASTIM case exception and use the CustomiseFragment['DIGI']
760  #+exception to the HLT:GRun case
761  Command = ("%s %s -n %s --step=%s %s %s --customise=%s %s" % (
762  cmsDriver,
763  KeywordToCfi[acandle],
764  NumberOfEvents,
765  stepToWrite,
766  InputFileOption,
767  OutputFileOption,
768  CustomiseFragment['DIGI'],#Done by hand to avoid silly use of MixinModule.py for pre-digi individual steps
769  cmsDriverOptions #For FASTSIM PU need the whole cmsDriverOptions! [:cmsDriverOptions.index('--pileup')]
770  ))
771 
772  else:
773  Command = ("%s %s -n %s --step=%s %s %s --customise=%s %s" % (
774  cmsDriver,
775  KeywordToCfi[acandle],
776  NumberOfEvents,
777  stepToWrite,
778  InputFileOption,
779  OutputFileOption,
780  CustomisePythonFragment,
781  cmsDriverOptions
782  ))
783  #Now the cmsDriver command is ready in Command, we just edit the rest of the line and write it to the file!
784  if _noprof:
785  simcandles.write("%s @@@ None @@@ None\n" % Command)
786  else:
787  if 'valgrind' in prof:
788  #I think the if is safer even though all commands in this "else" (i.e. non EdmSize) should be OK.
789  if 'TimeMemoryInfo.py' in Command:
790  Command=Command.replace('--customise=Validation/Performance/TimeMemoryInfo.py', '')
791  #There is actually also the SIM case to take care of:
792  elif 'TimeMemoryG4Info.py' in Command:
793  Command=Command.replace('--customise=Validation/Performance/TimeMemoryG4Info.py', '')
794  stepLabel=stepToWrite
795  #print "stepLabel is %s"%stepLabel
796  if '--pileup' in cmsDriverOptions and not "_PILEUP" in stepToWrite:
797  stepLabel = stepToWrite+"_PILEUP"
798  #Add kludge here to make the IGPROF ANALYSE work:
799  #The idea is to:
800  #1-Check if ANALYSE is there everytime we're handling IGPROF profiles
801  #2-If it is there then write 2 lines instead of 1: add a @@@ reuse to the first line and a second line with ANALYSE @@@ the same metadata
802  #[3-Catch the case of ANALYSE by itself and raise an exception]
803  #4-Catch the case of ANALYSE proper, and do nothing in that case (already taken care by the second lines done after PERF_TICKS, MEM_TOTAL and MEM_LIVE.
804  #print "EEEEEEE %s"%prof
805  #We actually want the analyse to be used also for IgProf perf!
806  if 'IgProf' in prof: # and 'perf' not in prof:
807  #New IgProf naming scheme:
808  #Add a new naming scheme to simplify the handling in igprof-navigator:
809  #Candle___Step___Conditions__PileUpOption__IgProfProfile___Event.gz (and .sql3)
810 
811  #Creating the IgProfProfile variable, to be either IgProfMem or IgProfPerf, the two types of profiling:
812  IgProfProfile="IgProf"
813  if "Mem" in prof:
814  if "reuse" in prof:
815  IgProfProfile="IgProfMem @@@ reuse"
816  else:
817  IgProfProfile="IgProfMem"
818  else:
819  if "reuse" in prof:
820  IgProfProfile="IgProfPerf @@@ reuse"
821  else:
822  IgProfProfile="IgProfPerf"
823 
824  #Conditions and PileUpOption are extracted from the cmsDriverOptions:
825  Conditions="UNKNOWN_CONDITIONS"
826  PileUp="NOPILEUP"
827  EventContent="UNKNOWN_EVENTCONTENT"
828  tokens=cmsDriverOptions.split("--")
829  for token in tokens:
830  keywords=token.split(" ")
831  if "=" in keywords[0]:
832  keywords=keywords[0].split("=")
833  if "conditions" in keywords[0]:
834  # check if we are using the autoCond style of flexible conditions
835  # if so, expand the condition here so that the file names contain the real conditions
836  if "auto:" in keywords[1]:
837  from Configuration.AlCa.autoCond import autoCond
838  fileConditionsOption = autoCond[ keywords[1].split(':')[1] ]
839  Conditions = autoCond[ keywords[1].split(':')[1] ].split("::")[0]
840  else:
841  # old style, hardcoded, conditions ...
842  # Complicated expression, just to get rid of FrontierConditions_GlobalTag,
843  # and ::All at the end:
844  # Added if to handle new --conditions convention for cmsDriver.py (no more
845  # FrontierConditions... in front of it)
846  if "," in keywords[1]:
847  Conditions=keywords[1].split(",")[1].split("::")[0] #"backward" compatibility...
848  else:
849  Conditions=keywords[1].split("::")[0]
850  elif "pileup" in keywords[0]:
851  PileUp=keywords[1]
852  elif "eventcontent" in keywords[0]:
853  EventContent=keywords[1]
854 
855  #so here's our new MetaName:
856  MetaName=acandle+"___"+stepToWrite+"___"+PileUp+"___"+Conditions+"___"+EventContent+"___"+IgProfProfile
857 
858  if 'Analyse' not in prof and (lambda x: 'Analyse' in x,Profile):
859 
860  simcandles.write("%s @@@ %s @@@ %s\n" % (Command,
861  Profiler[prof],
862  MetaName))
863  #FileName[acandle],
864  #stepLabel,
865  #prof))
866  analyse_command = ("%s @@@ %s @@@ %s\n" % (Command,
867  Profiler[prof].split(".")[0]+'.ANALYSE.'+Profiler[prof].split(".")[1], #Add the IgProf counter in here (e.g. IgProfMem.ANALYSE.MEM_TOTAL)
868  MetaName))
869  #FileName[acandle],
870  #stepLabel,
871  #prof))
872 
873  #for the relval case, GEN-SIM,HLT get rid of the last " @@@ reuse":
874  if Profiler[prof] == 'IgProf_mem.MEM_MAX' or Profiler[prof] == 'IgProf_perf.PERF_TICKS':
875  analyse_command = analyse_command.replace("@@@ reuse", "")
876 
877  simcandles.write(analyse_command)
878 
879  elif 'Analyse' in prof:
880  pass
881  else:
882  simcandles.write("%s @@@ %s @@@ %s_%s_%s\n" % (Command,
883  Profiler[prof],
884  FileName[acandle],
885  stepLabel,
886  prof))
887 
888  if debug:
889  print(InputFileOption, step, 'GEN,SIM' in step, 'HLT' in steps[stepIndex - 1], steps)
890  print("cmsDriveroptions : " + cmsDriverOption)
891  prevPrevOutputFile = previousOutputFile
892  previousOutputFile = OutputFile
893  else:
894  unprofiledSteps.append(step)
895  isNextStepForProfile = False # Just an initialization for scoping. don't worry about it being false
896 
897  try:
898  isNextStepForProfile = steps[stepIndex + 1] in userSteps or reduce(lambda x,y : x or y,map(lambda z: steps[ stepIndex + 1 ] == z.split("-")[0].split(":")[0],userSteps))
899  #print "YES found Step %s when looking with standard step %s"%(steps[stepIndex],steps[stepIndex])
900  except IndexError:
901  # This loop should have terminated if x + 1 is out of bounds!
902  print("Error: Something is wrong we shouldn't have come this far")
903  break
904 
905  if isNextStepForProfile:
906  #Minimum intervention solution is to fix it here: I think we need to pass the before and after steps...
907  OutputFile=writeUnprofiledSteps(simcandles,CustomisePythonFragment,cmsDriverOptions,unprofiledSteps,previousOutputFile,acandle,NumberOfEvents,stepIndex,pileup,bypasshlt)
908  unprofiledSteps = []
909  prevPrevOutputFile = previousOutputFile
910  previousOutputFile = OutputFile
911  #Dangerous index handling when looping over index x!
912  if oneShotProf:
913  stepIndex += len(hypsteps)
914  else:
915  stepIndex +=1
916  return fstROOTfileStr
917 
918 def writeCommandsToReport(simcandles,Candle,Profile,debug,NumberOfEvents,cmsDriverOptions,steps,bypasshlt,userInputFile):
919 
920  OutputStep = ''
921 
922  # This option will not be used for now since the event content names keep changing, it can be
923  # edited by hand pre-release by pre-release if wanted (Still moved all to FEVTDEBUGHLT for now, except RECO, left alone).
924  #
925  #EventContent = {'GEN,SIM': 'FEVTDEBUGHLT', 'DIGI': 'FEVTDEBUGHLT'}
926 
927  for acandle in Candle:
928  print('*Candle ' + acandle)
929 
930  ##################
931  # If the first profiling we run is EdmSize we need to create the root file first
932  #
933 
934  #Here all candles are processed with all the same command, and in the pileup case they will have the pileup settings set correctly already:
935  #print "1-userInputFile: %s"%userInputFile
936 
937  fstoutfile = writeCommands(simcandles,
938  Profile,
939  acandle,
940  steps,
941  NumberOfEvents,
942  cmsDriverOptions,
943  bypasshlt,
944  0,
945  False,
946  userInputFile)
947 
948 
949 def main(argv=sys.argv):
950 
951  #####################
952  # Options Parser
953  #
954 
955  (options, args) = optionparse()
956 
957  #####################
958  # Set up arguments and option handling
959  #
960 
961  (NumberOfEvents, ProfileCode, cmsDriverOptions, steps, Candle, bypasshlt, userInputFile ) = setupProgramParameters(options,args)
962  #print setupProgramParameters(options,args)
963 
964  ######################
965  # Initialize a few variables
966  #
967 
968  (CMSSW_BASE, CMSSW_RELEASE_BASE, CMSSW_VERSION ) = init_vars()
969 
970  ##################
971  # Ok everything is ready now we need to create the input file for the relvalreport script
972  #
973 
974  simcandles = writeReportFileHeader(CMSSW_VERSION,CMSSW_RELEASE_BASE,CMSSW_BASE)
975 
976  ##################
977  # Based on the profile code create the array of profiles to run:
978  #
979 
980  Profile = getProfileArray(ProfileCode)
981 
982 
983  ##################
984  # Write the commands for the report to the file
985  #
986 
987  writeCommandsToReport(simcandles,Candle,Profile,debug,NumberOfEvents,cmsDriverOptions,steps,bypasshlt,userInputFile)
988 
989  print("Written out cmsRelvalreport.py input file at:\n%s"%os.path.abspath('./'+simcandles.name))
990 
991  simcandles.close()
992 
993 if __name__ == "__main__":
994  main()
def setupProgramParameters(options, args)
def setInputFile(steps, step, acandle, stepIndex, pileup=False, bypasshlt=False)
def writeStepHead(simcandles, acandle, step)
def writeCommands(simcandles, Profile, acandle, steps, NumberOfEvents, cmsDriverOptions, bypasshlt, stepIndex=0, pileup=False, userInputFile="")
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:66
def writeReportFileHeader(CMSSW_VERSION, CMSSW_RELEASE_BASE, CMSSW_BASE)
def determineNewProfile(step, Profile, SavedProfile)
def setOutputFileOption(acandle, endstep)
def writeUnprofiledSteps(simcandles, CustomisePythonFragment, cmsDriverOptions, unprofiledSteps, previousOutputFile, acandle, NumberOfEvents, stepIndex, pileup, bypasshlt)
def getLstIndex(item, list)
def getFstOccur(item, list)
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def writePrerequisteSteps(simcandles, steps, acandle, NumberOfEvents, cmsDriverOptions, pileup, bypasshlt)
def pythonFragment(step, cmsdriverOptions)
def getProfileArray(ProfileCode)
Definition: main.py:1
def main(argv=sys.argv)
def writeCommandsToReport(simcandles, Candle, Profile, debug, NumberOfEvents, cmsDriverOptions, steps, bypasshlt, userInputFile)
#define str(s)
double split
Definition: MVATrainer.cc:139