CMS 3D CMS Logo

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