CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
validateAlignments.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #test execute: export CMSSW_BASE=/tmp/CMSSW && ./validateAlignments.py -c defaultCRAFTValidation.ini,test.ini -n -N test
3 import os
4 import sys
5 import optparse
6 import datetime
7 import shutil
8 import fnmatch
9 
10 import Alignment.OfflineValidation.TkAlAllInOneTool.configTemplates \
11  as configTemplates
12 import Alignment.OfflineValidation.TkAlAllInOneTool.crabWrapper as crabWrapper
13 from Alignment.OfflineValidation.TkAlAllInOneTool.TkAlExceptions \
14  import AllInOneError
15 from Alignment.OfflineValidation.TkAlAllInOneTool.helperFunctions \
16  import replaceByMap, getCommandOutput2, addIndex
17 from Alignment.OfflineValidation.TkAlAllInOneTool.betterConfigParser \
18  import BetterConfigParser
19 from Alignment.OfflineValidation.TkAlAllInOneTool.alignment import Alignment
20 
21 from Alignment.OfflineValidation.TkAlAllInOneTool.genericValidation \
22  import GenericValidation
23 from Alignment.OfflineValidation.TkAlAllInOneTool.geometryComparison \
24  import GeometryComparison
25 from Alignment.OfflineValidation.TkAlAllInOneTool.offlineValidation \
26  import OfflineValidation, OfflineValidationDQM
27 from Alignment.OfflineValidation.TkAlAllInOneTool.monteCarloValidation \
28  import MonteCarloValidation
29 from Alignment.OfflineValidation.TkAlAllInOneTool.trackSplittingValidation \
30  import TrackSplittingValidation
31 from Alignment.OfflineValidation.TkAlAllInOneTool.zMuMuValidation \
32  import ZMuMuValidation
33 from Alignment.OfflineValidation.TkAlAllInOneTool.preexistingValidation \
34  import *
35 import Alignment.OfflineValidation.TkAlAllInOneTool.globalDictionaries \
36  as globalDictionaries
37 
38 
39 ####################--- Classes ---############################
41 
42  # these count the jobs of different varieties that are being run
43  crabCount = 0
44  interactCount = 0
45  batchCount = 0
46  batchJobIds = []
47  jobCount = 0
48 
49  def __init__( self, validation, config, options ):
50  if validation[1] == "":
51  # intermediate syntax
52  valString = validation[0].split( "->" )[0]
53  alignments = validation[0].split( "->" )[1]
54  # force user to use the normal syntax
55  if "->" in validation[0]:
56  msg = ("Instead of using the intermediate syntax\n'"
57  +valString.strip()+"-> "+alignments.strip()
58  +":'\nyou have to use the now fully supported syntax \n'"
59  +valString.strip()+": "
60  +alignments.strip()+"'.")
61  raise AllInOneError(msg)
62  else:
63  valString = validation[0]
64  alignments = validation[1]
65  valString = valString.split()
66  self.__valType = valString[0]
67  self.__valName = valString[1]
68  self.__commandLineOptions = options
69  self.__config = config
70  # workaround for intermediate parallel version
71  if self.__valType == "offlineParallel":
72  print ("offlineParallel and offline are now the same. To run an offline parallel validation,\n"
73  "just set parallelJobs to something > 1. There is no reason to call it offlineParallel anymore.")
74  self.__valType = "offline"
75  section = self.__valType + ":" + self.__valName
76  if not self.__config.has_section( section ):
77  raise AllInOneError, ("Validation '%s' of type '%s' is requested in"
78  " '[validation]' section, but is not defined."
79  "\nYou have to add a '[%s]' section."
80  %( self.__valName, self.__valType, section ))
81  self.validation = self.__getValidation( self.__valType, self.__valName,
82  alignments, self.__config,
83  options )
84 
85  def __getValidation( self, valType, name, alignments, config, options ):
86  if valType == "compare":
87  alignmentsList = alignments.split( "," )
88  firstAlignList = alignmentsList[0].split()
89  firstAlignName = firstAlignList[0].strip()
90  if firstAlignName == "IDEAL":
91  raise AllInOneError, ("'IDEAL' has to be the second (reference)"
92  " alignment in 'compare <val_name>: "
93  "<alignment> <reference>'.")
94  if len( firstAlignList ) > 1:
95  firstRun = firstAlignList[1]
96  else:
97  firstRun = "1"
98  firstAlign = Alignment( firstAlignName, self.__config, firstRun )
99  firstAlignName = firstAlign.name
100  secondAlignList = alignmentsList[1].split()
101  secondAlignName = secondAlignList[0].strip()
102  if len( secondAlignList ) > 1:
103  secondRun = secondAlignList[1]
104  else:
105  secondRun = "1"
106  if secondAlignName == "IDEAL":
107  secondAlign = secondAlignName
108  else:
109  secondAlign = Alignment( secondAlignName, self.__config,
110  secondRun )
111  secondAlignName = secondAlign.name
112  # check if alignment was already compared previously
113  try:
114  randomWorkdirPart = \
115  globalDictionaries.alignRandDict[firstAlignName]
116  except KeyError:
117  randomWorkdirPart = None
118 
119  validation = GeometryComparison( name, firstAlign, secondAlign,
120  self.__config,
121  self.__commandLineOptions.getImages,
122  randomWorkdirPart )
123  globalDictionaries.alignRandDict[firstAlignName] = \
124  validation.randomWorkdirPart
125  if not secondAlignName == "IDEAL":
126  globalDictionaries.alignRandDict[secondAlignName] = \
127  validation.randomWorkdirPart
128  elif valType == "offline":
129  validation = OfflineValidation( name,
130  Alignment( alignments.strip(), self.__config ), self.__config )
131  elif valType == "preexistingoffline":
132  validation = PreexistingOfflineValidation(name, self.__config)
133  elif valType == "offlineDQM":
134  validation = OfflineValidationDQM( name,
135  Alignment( alignments.strip(), self.__config ), self.__config )
136  elif valType == "mcValidate":
137  validation = MonteCarloValidation( name,
138  Alignment( alignments.strip(), self.__config ), self.__config )
139  elif valType == "preexistingmcValidate":
140  validation = PreexistingMonteCarloValidation(name, self.__config)
141  elif valType == "split":
142  validation = TrackSplittingValidation( name,
143  Alignment( alignments.strip(), self.__config ), self.__config )
144  elif valType == "preexistingsplit":
145  validation = PreexistingTrackSplittingValidation(name, self.__config)
146  elif valType == "zmumu":
147  validation = ZMuMuValidation( name,
148  Alignment( alignments.strip(), self.__config ), self.__config )
149  else:
150  raise AllInOneError, "Unknown validation mode '%s'"%valType
151  self.preexisting = ("preexisting" in valType)
152  return validation
153 
154  def __createJob( self, jobMode, outpath ):
155  """This private method creates the needed files for the validation job.
156  """
157  self.validation.createConfiguration( outpath )
158  self.__scripts = sum([addIndex(script, self.validation.NJobs) for script in self.validation.createScript( outpath )], [])
159  if jobMode.split( ',' )[0] == "crab":
160  self.validation.createCrabCfg( outpath )
161  return None
162 
163  def createJob(self):
164  """This is the method called to create the job files."""
165  if self.preexisting:
166  return
167  self.__createJob( self.validation.jobmode,
168  os.path.abspath( self.__commandLineOptions.Name) )
169 
170  def runJob( self ):
171  if self.preexisting:
172  log = "> " + self.validation.name + " is already validated."
173  print log
174  return log
175 
176  general = self.__config.getGeneral()
177  log = ""
178  for script in self.__scripts:
179  name = os.path.splitext( os.path.basename( script) )[0]
180  ValidationJob.jobCount += 1
181  if self.__commandLineOptions.dryRun:
182  print "%s would run: %s"%( name, os.path.basename( script) )
183  continue
184  log = "> Validating "+name
185  print "> Validating "+name
186  if self.validation.jobmode == "interactive":
187  log += getCommandOutput2( script )
188  ValidationJob.interactCount += 1
189  elif self.validation.jobmode.split(",")[0] == "lxBatch":
190  repMap = {
191  "commands": self.validation.jobmode.split(",")[1],
192  "logDir": general["logdir"],
193  "jobName": name,
194  "script": script,
195  "bsub": "/afs/cern.ch/cms/caf/scripts/cmsbsub"
196  }
197  bsubOut=getCommandOutput2("%(bsub)s %(commands)s "
198  "-J %(jobName)s "
199  "-o %(logDir)s/%(jobName)s.stdout "
200  "-e %(logDir)s/%(jobName)s.stderr "
201  "%(script)s"%repMap)
202  #Attention: here it is assumed that bsub returns a string
203  #containing a job id like <123456789>
204  ValidationJob.batchJobIds.append(bsubOut.split("<")[1].split(">")[0])
205  log+=bsubOut
206  ValidationJob.batchCount += 1
207  elif self.validation.jobmode.split( "," )[0] == "crab":
208  os.chdir( general["logdir"] )
209  crabName = "crab." + os.path.basename( script )[:-3]
210  theCrab = crabWrapper.CrabWrapper()
211  options = { "-create": "",
212  "-cfg": crabName + ".cfg",
213  "-submit": "" }
214  try:
215  theCrab.run( options )
216  except AllInOneError, e:
217  print "crab:", str(e).split("\n")[0]
218  exit(1)
219  ValidationJob.crabCount += 1
220 
221  else:
222  raise AllInOneError, ("Unknown 'jobmode'!\n"
223  "Please change this parameter either in "
224  "the [general] or in the ["
225  + self.__valType + ":" + self.__valName
226  + "] section to one of the following "
227  "values:\n"
228  "\tinteractive\n\tlxBatch, -q <queue>\n"
229  "\tcrab, -q <queue>")
230 
231  return log
232 
233  def getValidation( self ):
234  return self.validation
235 
236 
237 ####################--- Functions ---############################
238 def createOfflineParJobsMergeScript(offlineValidationList, outFilePath):
239  repMap = offlineValidationList[0].getRepMap() # bit ugly since some special features are filled
240 
241  theFile = open( outFilePath, "w" )
242  theFile.write( replaceByMap( configTemplates.mergeOfflineParJobsTemplate ,repMap ) )
243  theFile.close()
244 
245 def createExtendedValidationScript(offlineValidationList, outFilePath, resultPlotFile):
246  repMap = offlineValidationList[0].getRepMap() # bit ugly since some special features are filled
247  repMap[ "CMSSW_BASE" ] = os.environ['CMSSW_BASE']
248  repMap[ "resultPlotFile" ] = resultPlotFile
249  repMap[ "extendedInstantiation" ] = "" #give it a "" at first in order to get the initialisation back
250 
251  for validation in offlineValidationList:
252  repMap[ "extendedInstantiation" ] = validation.appendToExtendedValidation( repMap[ "extendedInstantiation" ] )
253 
254  theFile = open( outFilePath, "w" )
255  # theFile.write( replaceByMap( configTemplates.extendedValidationTemplate ,repMap ) )
256  theFile.write( replaceByMap( configTemplates.extendedValidationTemplate ,repMap ) )
257  theFile.close()
258 
259 def createTrackSplitPlotScript(trackSplittingValidationList, outFilePath):
260  repMap = trackSplittingValidationList[0].getRepMap() # bit ugly since some special features are filled
261  repMap[ "CMSSW_BASE" ] = os.environ['CMSSW_BASE']
262  repMap[ "trackSplitPlotInstantiation" ] = "" #give it a "" at first in order to get the initialisation back
263 
264  for validation in trackSplittingValidationList:
265  repMap[ "trackSplitPlotInstantiation" ] = validation.appendToExtendedValidation( repMap[ "trackSplitPlotInstantiation" ] )
266 
267  theFile = open( outFilePath, "w" )
268  # theFile.write( replaceByMap( configTemplates.trackSplitPlotTemplate ,repMap ) )
269  theFile.write( replaceByMap( configTemplates.trackSplitPlotTemplate ,repMap ) )
270  theFile.close()
271 
272 def createMergeScript( path, validations ):
273  if(len(validations) == 0):
274  raise AllInOneError("Cowardly refusing to merge nothing!")
275 
276  repMap = validations[0].getRepMap() #FIXME - not nice this way
277  repMap.update({
278  "DownloadData":"",
279  "CompareAlignments":"",
280  "RunExtendedOfflineValidation":"",
281  "RunTrackSplitPlot":"",
282  "CMSSW_BASE": os.environ["CMSSW_BASE"],
283  "SCRAM_ARCH": os.environ["SCRAM_ARCH"],
284  "CMSSW_RELEASE_BASE": os.environ["CMSSW_RELEASE_BASE"],
285  })
286 
287  comparisonLists = {} # directory of lists containing the validations that are comparable
288  for validation in validations:
289  for referenceName in validation.filesToCompare:
290  validationName = "%s.%s"%(validation.__class__.__name__, referenceName)
291  validationName = validationName.split(".%s"%GenericValidation.defaultReferenceName )[0]
292  validationName = validationName.split("Preexisting")[-1]
293  if validationName in comparisonLists:
294  comparisonLists[ validationName ].append( validation )
295  else:
296  comparisonLists[ validationName ] = [ validation ]
297 
298  # introduced to merge individual validation outputs separately
299  # -> avoids problems with merge script
300  repMap["haddLoop"] = "mergeRetCode=0\n"
301  repMap["rmUnmerged"] = ("if [[ mergeRetCode -eq 0 ]]; then\n"
302  " echo -e \\n\"Merging succeeded, removing original files.\"\n")
303  repMap["copyMergeScripts"] = ""
304  repMap["mergeParallelFilePrefixes"] = ""
305 
306  anythingToMerge = []
307  for validationType in comparisonLists:
308  for validation in comparisonLists[validationType]:
309  if isinstance(validation, PreexistingValidation) or validation.NJobs == 1:
310  continue
311  if validationType not in anythingToMerge:
312  anythingToMerge += [validationType]
313  repMap["haddLoop"] += '\n\n\n\necho -e "\n\nMerging results from %s jobs"\n\n' % validationType
314  repMap["haddLoop"] = validation.appendToMerge(repMap["haddLoop"])
315  repMap["haddLoop"] += "tmpMergeRetCode=${?}\n"
316  repMap["haddLoop"] += ("if [[ tmpMergeRetCode -eq 0 ]]; then "
317  "cmsStage -f "
318  +validation.getRepMap()["finalOutputFile"]
319  +" "
320  +validation.getRepMap()["finalResultFile"]
321  +"; fi\n")
322  repMap["haddLoop"] += ("if [[ ${tmpMergeRetCode} -gt ${mergeRetCode} ]]; then "
323  "mergeRetCode=${tmpMergeRetCode}; fi\n")
324  for f in validation.getRepMap()["outputFiles"]:
325  longName = os.path.join("/store/caf/user/$USER/",
326  validation.getRepMap()["eosdir"], f)
327  repMap["rmUnmerged"] += " cmsRm "+longName+"\n"
328  repMap["rmUnmerged"] += ("else\n"
329  " echo -e \\n\"WARNING: Merging failed, unmerged"
330  " files won't be deleted.\\n"
331  "(Ignore this warning if merging was done earlier)\"\n"
332  "fi\n")
333 
334  if "OfflineValidation" in anythingToMerge:
335  repMap["mergeOfflineParJobsScriptPath"] = os.path.join(path, "TkAlOfflineJobsMerge.C")
336  createOfflineParJobsMergeScript( comparisonLists["OfflineValidation"],
337  repMap["mergeOfflineParJobsScriptPath"] )
338  repMap["copyMergeScripts"] += ("cp .oO[CMSSW_BASE]Oo./src/Alignment/OfflineValidation/scripts/merge_TrackerOfflineValidation.C .\n"
339  "rfcp %s .\n" % repMap["mergeOfflineParJobsScriptPath"])
340 
341  if anythingToMerge:
342  # DownloadData is the section which merges output files from parallel jobs
343  # it uses the file TkAlOfflineJobsMerge.C
344  repMap["DownloadData"] += replaceByMap( configTemplates.mergeParallelResults, repMap )
345  else:
346  repMap["DownloadData"] = ""
347 
348 
349  if "OfflineValidation" in comparisonLists:
350  repMap["extendedValScriptPath"] = os.path.join(path, "TkAlExtendedOfflineValidation.C")
351  createExtendedValidationScript(comparisonLists["OfflineValidation"],
352  repMap["extendedValScriptPath"],
353  "OfflineValidation")
354  repMap["RunExtendedOfflineValidation"] = \
355  replaceByMap(configTemplates.extendedValidationExecution, repMap)
356 
357  if "TrackSplittingValidation" in comparisonLists:
358  repMap["trackSplitPlotScriptPath"] = \
359  os.path.join(path, "TkAlTrackSplitPlot.C")
360  createTrackSplitPlotScript(comparisonLists["TrackSplittingValidation"],
361  repMap["trackSplitPlotScriptPath"] )
362  repMap["RunTrackSplitPlot"] = \
363  replaceByMap(configTemplates.trackSplitPlotExecution, repMap)
364 
365  repMap["CompareAlignments"] = "#run comparisons"
366  for validationId in comparisonLists:
367  compareStrings = [ val.getCompareStrings(validationId) for val in comparisonLists[validationId] ]
368  compareStringsPlain = [ val.getCompareStrings(validationId, plain=True) for val in comparisonLists[validationId] ]
369 
370  repMap.update({"validationId": validationId,
371  "compareStrings": " , ".join(compareStrings),
372  "compareStringsPlain": " ".join(compareStringsPlain) })
373 
374  repMap["CompareAlignments"] += \
375  replaceByMap(configTemplates.compareAlignmentsExecution, repMap)
376 
377  filePath = os.path.join(path, "TkAlMerge.sh")
378  theFile = open( filePath, "w" )
379  theFile.write( replaceByMap( configTemplates.mergeTemplate, repMap ) )
380  theFile.close()
381  os.chmod(filePath,0755)
382 
383  return filePath
384 
385 def loadTemplates( config ):
386  if config.has_section("alternateTemplates"):
387  for templateName in config.options("alternateTemplates"):
388  if templateName == "AutoAlternates":
389  continue
390  newTemplateName = config.get("alternateTemplates", templateName )
391  #print "replacing default %s template by %s"%( templateName, newTemplateName)
392  configTemplates.alternateTemplate(templateName, newTemplateName)
393 
394 
395 ####################--- Main ---############################
396 def main(argv = None):
397  if argv == None:
398  argv = sys.argv[1:]
399  optParser = optparse.OptionParser()
400  optParser.description = """All-in-one Alignment Validation.
401 This will run various validation procedures either on batch queues or interactviely.
402 If no name is given (-N parameter) a name containing time and date is created automatically.
403 To merge the outcome of all validation procedures run TkAlMerge.sh in your validation's directory.
404 """
405  optParser.add_option("-n", "--dryRun", dest="dryRun", action="store_true", default=False,
406  help="create all scripts and cfg File but do not start jobs (default=False)")
407  optParser.add_option( "--getImages", dest="getImages", action="store_true", default=False,
408  help="get all Images created during the process (default= False)")
409  defaultConfig = "TkAlConfig.ini"
410  optParser.add_option("-c", "--config", dest="config", default = defaultConfig,
411  help="configuration to use (default TkAlConfig.ini) this can be a comma-seperated list of all .ini file you want to merge", metavar="CONFIG")
412  optParser.add_option("-N", "--Name", dest="Name",
413  help="Name of this validation (default: alignmentValidation_DATE_TIME)", metavar="NAME")
414  optParser.add_option("-r", "--restrictTo", dest="restrictTo",
415  help="restrict validations to given modes (comma seperated) (default: no restriction)", metavar="RESTRICTTO")
416  optParser.add_option("-s", "--status", dest="crabStatus", action="store_true", default = False,
417  help="get the status of the crab jobs", metavar="STATUS")
418  optParser.add_option("-d", "--debug", dest="debugMode", action="store_true",
419  default = False,
420  help="run the tool to get full traceback of errors",
421  metavar="DEBUG")
422  optParser.add_option("-m", "--autoMerge", dest="autoMerge", action="store_true", default = False,
423  help="submit TkAlMerge.sh to run automatically when all jobs have finished (default=False)."
424  " Works only for batch jobs")
425 
426  (options, args) = optParser.parse_args(argv)
427 
428  if not options.restrictTo == None:
429  options.restrictTo = options.restrictTo.split(",")
430 
431  options.config = [ os.path.abspath( iniFile ) for iniFile in \
432  options.config.split( "," ) ]
433  config = BetterConfigParser()
434  outputIniFileSet = set( config.read( options.config ) )
435  failedIniFiles = [ iniFile for iniFile in options.config if iniFile not in outputIniFileSet ]
436 
437  # Check for missing ini file
438  if options.config == [ os.path.abspath( defaultConfig ) ]:
439  if ( not options.crabStatus ) and \
440  ( not os.path.exists( defaultConfig ) ):
441  raise AllInOneError, ( "Default 'ini' file '%s' not found!\n"
442  "You can specify another name with the "
443  "command line option '-c'/'--config'."
444  %( defaultConfig ))
445  else:
446  for iniFile in failedIniFiles:
447  if not os.path.exists( iniFile ):
448  raise AllInOneError, ( "'%s' does not exist. Please check for "
449  "typos in the filename passed to the "
450  "'-c'/'--config' option!"
451  %( iniFile ) )
452  else:
453  raise AllInOneError, ( "'%s' does exist, but parsing of the "
454  "content failed!" ) % iniFile
455 
456  # get the job name
457  if options.Name == None:
458  if not options.crabStatus:
459  options.Name = "alignmentValidation_%s"%(datetime.datetime.now().strftime("%y%m%d_%H%M%S"))
460  else:
461  existingValDirs = fnmatch.filter( os.walk( '.' ).next()[1],
462  "alignmentValidation_*" )
463  if len( existingValDirs ) > 0:
464  options.Name = existingValDirs[-1]
465  else:
466  print "Cannot guess last working directory!"
467  print ( "Please use the parameter '-N' or '--Name' to specify "
468  "the task for which you want a status report." )
469  return 1
470 
471  # set output path
472  outPath = os.path.abspath( options.Name )
473 
474  # Check status of submitted jobs and return
475  if options.crabStatus:
476  os.chdir( outPath )
477  crabLogDirs = fnmatch.filter( os.walk('.').next()[1], "crab.*" )
478  if len( crabLogDirs ) == 0:
479  print "Found no crab tasks for job name '%s'"%( options.Name )
480  return 1
481  theCrab = crabWrapper.CrabWrapper()
482  for crabLogDir in crabLogDirs:
483  print
484  print "*" + "=" * 78 + "*"
485  print ( "| Status report and output retrieval for:"
486  + " " * (77 - len( "Status report and output retrieval for:" ) )
487  + "|" )
488  taskName = crabLogDir.replace( "crab.", "" )
489  print "| " + taskName + " " * (77 - len( taskName ) ) + "|"
490  print "*" + "=" * 78 + "*"
491  print
492  crabOptions = { "-getoutput":"",
493  "-c": crabLogDir }
494  try:
495  theCrab.run( crabOptions )
496  except AllInOneError, e:
497  print "crab: No output retrieved for this task."
498  crabOptions = { "-status": "",
499  "-c": crabLogDir }
500  theCrab.run( crabOptions )
501  return
502 
503  general = config.getGeneral()
504  config.set("internals","workdir",os.path.join(general["workdir"],options.Name) )
505  config.set("general","datadir",os.path.join(general["datadir"],options.Name) )
506  config.set("general","logdir",os.path.join(general["logdir"],options.Name) )
507  config.set("general","eosdir",os.path.join("AlignmentValidation", general["eosdir"], options.Name) )
508 
509  # clean up of log directory to avoid cluttering with files with different
510  # random numbers for geometry comparison
511  if os.path.isdir( outPath ):
512  shutil.rmtree( outPath )
513 
514  if not os.path.exists( outPath ):
515  os.makedirs( outPath )
516  elif not os.path.isdir( outPath ):
517  raise AllInOneError,"the file %s is in the way rename the Job or move it away"%outPath
518 
519  # replace default templates by the ones specified in the "alternateTemplates" section
520  loadTemplates( config )
521 
522  #save backup configuration file
523  backupConfigFile = open( os.path.join( outPath, "usedConfiguration.ini" ) , "w" )
524  config.write( backupConfigFile )
525 
526  validations = []
527  for validation in config.items("validation"):
528  alignmentList = [validation[1]]
529  validationsToAdd = [(validation[0],alignment) \
530  for alignment in alignmentList]
531  validations.extend(validationsToAdd)
532  jobs = [ ValidationJob( validation, config, options) \
533  for validation in validations ]
534  map( lambda job: job.createJob(), jobs )
535  validations = [ job.getValidation() for job in jobs ]
536 
537  createMergeScript(outPath, validations)
538 
539  print
540  map( lambda job: job.runJob(), jobs )
541 
542  if options.autoMerge:
543  # if everything is done as batch job, also submit TkAlMerge.sh to be run
544  # after the jobs have finished
545  if ValidationJob.jobCount == ValidationJob.batchCount and config.getGeneral()["jobmode"].split(",")[0] == "lxBatch":
546  print "> Automatically merging jobs when they have ended"
547  repMap = {
548  "commands": config.getGeneral()["jobmode"].split(",")[1],
549  "jobName": "TkAlMerge",
550  "logDir": config.getGeneral()["logdir"],
551  "script": "TkAlMerge.sh",
552  "bsub": "/afs/cern.ch/cms/caf/scripts/cmsbsub",
553  "conditions": '"' + " && ".join(["ended(" + jobId + ")" for jobId in ValidationJob.batchJobIds]) + '"'
554  }
555  getCommandOutput2("%(bsub)s %(commands)s "
556  "-o %(logDir)s/%(jobName)s.stdout "
557  "-e %(logDir)s/%(jobName)s.stderr "
558  "-w %(conditions)s "
559  "%(logDir)s/%(script)s"%repMap)
560 
561 if __name__ == "__main__":
562  # main(["-n","-N","test","-c","defaultCRAFTValidation.ini,latestObjects.ini","--getImages"])
563  if "-d" in sys.argv[1:] or "--debug" in sys.argv[1:]:
564  main()
565  else:
566  try:
567  main()
568  except AllInOneError, e:
569  print "\nAll-In-One Tool:", str(e)
570  exit(1)
— Classes —############################
def main
— Main —############################
def alternateTemplate
### Alternate Templates ###
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def replaceByMap
— Helpers —############################
Definition: main.py:1
if(conf.exists("allCellsPositionCalc"))
double split
Definition: MVATrainer.cc:139