CMS 3D CMS Logo

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