CMS 3D CMS Logo

Classes | Functions
validateAlignments Namespace Reference

Classes

class  ParallelMergeJob
 — Classes —############################ More...
 
class  ValidationJob
 

Functions

def createMergeScript (path, validations, options)
 
def loadTemplates (config)
 
def main (argv=None)
 — Main —############################ More...
 

Function Documentation

def validateAlignments.createMergeScript (   path,
  validations,
  options 
)

Definition at line 289 of file validateAlignments.py.

References mps_setup.append, and helperFunctions.replaceByMap().

Referenced by main().

289 def createMergeScript( path, validations, options ):
290  if(len(validations) == 0):
291  raise AllInOneError("Cowardly refusing to merge nothing!")
292 
293  config = validations[0].config
294  repMap = config.getGeneral()
295  repMap.update({
296  "DownloadData":"",
297  "CompareAlignments":"",
298  "RunValidationPlots":"",
299  "CMSSW_BASE": os.environ["CMSSW_BASE"],
300  "SCRAM_ARCH": os.environ["SCRAM_ARCH"],
301  "CMSSW_RELEASE_BASE": os.environ["CMSSW_RELEASE_BASE"],
302  })
303 
304  comparisonLists = {} # directory of lists containing the validations that are comparable
305  for validation in validations:
306  for referenceName in validation.filesToCompare:
307  validationtype = type(validation)
308  if issubclass(validationtype, PreexistingValidation):
309  #find the actual validationtype
310  for parentclass in validationtype.mro():
311  if not issubclass(parentclass, PreexistingValidation):
312  validationtype = parentclass
313  break
314  key = (validationtype, referenceName)
315  if key in comparisonLists:
316  comparisonLists[key].append(validation)
317  else:
318  comparisonLists[key] = [validation]
319 
320  # introduced to merge individual validation outputs separately
321  # -> avoids problems with merge script
322  repMap["doMerge"] = "mergeRetCode=0\n"
323  repMap["rmUnmerged"] = ("if [[ mergeRetCode -eq 0 ]]; then\n"
324  " echo -e \\n\"Merging succeeded, removing original files.\"\n")
325  repMap["beforeMerge"] = ""
326  repMap["mergeParallelFilePrefixes"] = ""
327  repMap["createResultsDirectory"]=""
328 
329 
330  anythingToMerge = []
331 
332 
333  #prepare dictionary containing handle objects for parallel merge batch jobs
334  if options.mergeOfflineParallel:
335  parallelMergeObjects={}
336  for (validationType, referencename), validations in six.iteritems(comparisonLists):
337  for validation in validations:
338  #parallel merging
339  if (isinstance(validation, PreexistingValidation)
340  or validation.NJobs == 1
341  or not isinstance(validation, ParallelValidation)):
342  continue
343  if options.mergeOfflineParallel and validationType.valType=='offline' and validation.jobmode.split(",")[0]=="lxBatch":
344  repMapTemp=repMap.copy()
345  if validationType not in anythingToMerge:
346  anythingToMerge += [validationType]
347  #create init script
348  fileName="TkAlMergeInit"
349  filePath = os.path.join(path, fileName+".sh")
350  theFile = open( filePath, "w" )
351  repMapTemp["createResultsDirectory"]="#!/bin/bash"
352  repMapTemp["createResultsDirectory"]+=replaceByMap(configTemplates.createResultsDirectoryTemplate, repMapTemp)
353  theFile.write( replaceByMap( configTemplates.createResultsDirectoryTemplate, repMapTemp ) )
354  theFile.close()
355  os.chmod(filePath,0o755)
356  #create handle
357  parallelMergeObjects["init"]=ParallelMergeJob(fileName, filePath,[])
358  #clear 'create result directory' code
359  repMapTemp["createResultsDirectory"]=""
360 
361  #edit repMapTmp as necessary:
362  #fill contents of mergeParallelResults
363  repMapTemp["beforeMerge"] += validationType.doInitMerge()
364  repMapTemp["doMerge"] += '\n\n\n\necho -e "\n\nMerging results from %s jobs with alignment %s"\n\n' % (validationType.valType,validation.alignmentToValidate.name)
365  repMapTemp["doMerge"] += validation.doMerge()
366  for f in validation.getRepMap()["outputFiles"]:
367  longName = os.path.join("/eos/cms/store/group/alca_trackeralign/AlignmentValidation/",
368  validation.getRepMap()["eosdir"], f)
369  repMapTemp["rmUnmerged"] += " rm "+longName+"\n"
370 
371  repMapTemp["rmUnmerged"] += ("else\n"
372  " echo -e \\n\"WARNING: Merging failed, unmerged"
373  " files won't be deleted.\\n"
374  "(Ignore this warning if merging was done earlier)\"\n"
375  "fi\n")
376 
377  #fill mergeParallelResults area of mergeTemplate
378  repMapTemp["DownloadData"] = replaceByMap( configTemplates.mergeParallelResults, repMapTemp )
379  #fill runValidationPlots area of mergeTemplate
380  repMapTemp["RunValidationPlots"] = validationType.doRunPlots(validations)
381 
382  #create script file
383  fileName="TkAlMergeOfflineValidation"+validation.name+validation.alignmentToValidate.name
384  filePath = os.path.join(path, fileName+".sh")
385  theFile = open( filePath, "w" )
386  theFile.write( replaceByMap( configTemplates.mergeParallelOfflineTemplate, repMapTemp ) )
387  theFile.close()
388  os.chmod(filePath,0o755)
389  #create handle object
390  if "parallel" in parallelMergeObjects:
391  parallelMergeObjects["parallel"].append(ParallelMergeJob(fileName, filePath,[]))
392  else:
393  parallelMergeObjects["parallel"]=[ParallelMergeJob(fileName, filePath,[])]
394  continue
395 
396 
397  else:
398  if validationType not in anythingToMerge:
399  anythingToMerge += [validationType]
400  repMap["doMerge"] += '\n\n\n\necho -e "\n\nMerging results from %s jobs"\n\n' % validationType.valType
401  repMap["beforeMerge"] += validationType.doInitMerge()
402  repMap["doMerge"] += validation.doMerge()
403  for f in validation.getRepMap()["outputFiles"]:
404  longName = os.path.join("/eos/cms/store/group/alca_trackeralign/AlignmentValidation/",
405  validation.getRepMap()["eosdir"], f)
406  repMap["rmUnmerged"] += " rm "+longName+"\n"
407 
408 
409 
410  repMap["rmUnmerged"] += ("else\n"
411  " echo -e \\n\"WARNING: Merging failed, unmerged"
412  " files won't be deleted.\\n"
413  "(Ignore this warning if merging was done earlier)\"\n"
414  "fi\n")
415 
416 
417 
418  if anythingToMerge:
419  repMap["DownloadData"] += replaceByMap( configTemplates.mergeParallelResults, repMap )
420  else:
421  repMap["DownloadData"] = ""
422 
423  repMap["RunValidationPlots"] = ""
424  for (validationType, referencename), validations in six.iteritems(comparisonLists):
425  if issubclass(validationType, ValidationWithPlots):
426  repMap["RunValidationPlots"] += validationType.doRunPlots(validations)
427 
428  repMap["CompareAlignments"] = "#run comparisons"
429  for (validationType, referencename), validations in six.iteritems(comparisonLists):
430  if issubclass(validationType, ValidationWithComparison):
431  repMap["CompareAlignments"] += validationType.doComparison(validations)
432 
433  #if user wants to merge parallely and if there are valid parallel scripts, create handle for plotting job and set merge script name accordingly
434  if options.mergeOfflineParallel and parallelMergeObjects!={}:
435  parallelMergeObjects["continue"]=ParallelMergeJob("TkAlMergeFinal",os.path.join(path, "TkAlMergeFinal.sh"),[])
436  filePath = os.path.join(path, "TkAlMergeFinal.sh")
437  #if not merging parallel, add code to create results directory and set merge script name accordingly
438  else:
439  repMap["createResultsDirectory"]=replaceByMap(configTemplates.createResultsDirectoryTemplate, repMap)
440  filePath = os.path.join(path, "TkAlMerge.sh")
441 
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  if options.mergeOfflineParallel:
450  return {'TkAlMerge.sh':filePath, 'parallelMergeObjects':parallelMergeObjects}
451  else:
452  return filePath
453 
def createMergeScript(path, validations, options)
— Classes —############################
def replaceByMap(target, the_map)
— Helpers —############################
def validateAlignments.loadTemplates (   config)

Definition at line 454 of file validateAlignments.py.

References configTemplates.alternateTemplate().

Referenced by main().

454 def loadTemplates( config ):
455  if config.has_section("alternateTemplates"):
456  for templateName in config.options("alternateTemplates"):
457  if templateName == "AutoAlternates":
458  continue
459  newTemplateName = config.get("alternateTemplates", templateName )
460  #print "replacing default %s template by %s"%( templateName, newTemplateName)
461  configTemplates.alternateTemplate(templateName, newTemplateName)
462 
463 
def alternateTemplate(templateName, alternateTemplateName)
Alternate Templates ###
def validateAlignments.main (   argv = None)

— Main —############################

Definition at line 465 of file validateAlignments.py.

References createMergeScript(), cmsRelvalreport.exit, helperFunctions.getCommandOutput2(), createfilelist.int, join(), loadTemplates(), genParticles_cff.map, GetRecoTauVFromDQM_MC_cff.next, edm.print(), split, str, and digitizers_cfi.strip.

465 def main(argv = None):
466  if argv == None:
467  argv = sys.argv[1:]
468  optParser = optparse.OptionParser()
469  optParser.description = """All-in-one Alignment Validation.
470 This will run various validation procedures either on batch queues or interactively.
471 If no name is given (-N parameter) a name containing time and date is created automatically.
472 To merge the outcome of all validation procedures run TkAlMerge.sh in your validation's directory.
473 """
474  optParser.add_option("-n", "--dryRun", dest="dryRun", action="store_true", default=False,
475  help="create all scripts and cfg File but do not start jobs (default=False)")
476  optParser.add_option( "--getImages", dest="getImages", action="store_true", default=True,
477  help="get all Images created during the process (default= True)")
478  defaultConfig = "TkAlConfig.ini"
479  optParser.add_option("-c", "--config", dest="config", default = defaultConfig,
480  help="configuration to use (default TkAlConfig.ini) this can be a comma-seperated list of all .ini file you want to merge", metavar="CONFIG")
481  optParser.add_option("-N", "--Name", dest="Name",
482  help="Name of this validation (default: alignmentValidation_DATE_TIME)", metavar="NAME")
483  optParser.add_option("-r", "--restrictTo", dest="restrictTo",
484  help="restrict validations to given modes (comma seperated) (default: no restriction)", metavar="RESTRICTTO")
485  optParser.add_option("-s", "--status", dest="crabStatus", action="store_true", default = False,
486  help="get the status of the crab jobs", metavar="STATUS")
487  optParser.add_option("-d", "--debug", dest="debugMode", action="store_true",
488  default = False,
489  help="run the tool to get full traceback of errors",
490  metavar="DEBUG")
491  optParser.add_option("-m", "--autoMerge", dest="autoMerge", action="store_true", default = False,
492  help="submit TkAlMerge.sh to run automatically when all jobs have finished (default=False)."
493  " Works only for batch jobs")
494  optParser.add_option("--mergeOfflineParallel", dest="mergeOfflineParallel", action="store_true", default = False,
495  help="Enable parallel merging of offline data. Best used with -m option. Only works with lxBatch-jobmode", metavar="MERGE_PARALLEL")
496 
497 
498  (options, args) = optParser.parse_args(argv)
499 
500  if not options.restrictTo == None:
501  options.restrictTo = options.restrictTo.split(",")
502 
503  options.config = [ os.path.abspath( iniFile ) for iniFile in \
504  options.config.split( "," ) ]
505  config = BetterConfigParser()
506  outputIniFileSet = set( config.read( options.config ) )
507  failedIniFiles = [ iniFile for iniFile in options.config if iniFile not in outputIniFileSet ]
508 
509  # Check for missing ini file
510  if options.config == [ os.path.abspath( defaultConfig ) ]:
511  if ( not options.crabStatus ) and \
512  ( not os.path.exists( defaultConfig ) ):
513  raise AllInOneError( "Default 'ini' file '%s' not found!\n"
514  "You can specify another name with the "
515  "command line option '-c'/'--config'."
516  %( defaultConfig ))
517  else:
518  for iniFile in failedIniFiles:
519  if not os.path.exists( iniFile ):
520  raise AllInOneError( "'%s' does not exist. Please check for "
521  "typos in the filename passed to the "
522  "'-c'/'--config' option!"
523  %( iniFile ))
524  else:
525  raise AllInOneError(( "'%s' does exist, but parsing of the "
526  "content failed!" ) % iniFile)
527 
528  # get the job name
529  if options.Name == None:
530  if not options.crabStatus:
531  options.Name = "alignmentValidation_%s"%(datetime.datetime.now().strftime("%y%m%d_%H%M%S"))
532  else:
533  existingValDirs = fnmatch.filter( os.walk( '.' ).next()[1],
534  "alignmentValidation_*" )
535  if len( existingValDirs ) > 0:
536  options.Name = existingValDirs[-1]
537  else:
538  print("Cannot guess last working directory!")
539  print ( "Please use the parameter '-N' or '--Name' to specify "
540  "the task for which you want a status report." )
541  return 1
542 
543  # set output path
544  outPath = os.path.abspath( options.Name )
545 
546  # Check status of submitted jobs and return
547  if options.crabStatus:
548  os.chdir( outPath )
549  crabLogDirs = fnmatch.filter( os.walk('.').next()[1], "crab.*" )
550  if len( crabLogDirs ) == 0:
551  print("Found no crab tasks for job name '%s'"%( options.Name ))
552  return 1
553  theCrab = crabWrapper.CrabWrapper()
554  for crabLogDir in crabLogDirs:
555  print()
556  print("*" + "=" * 78 + "*")
557  print ( "| Status report and output retrieval for:"
558  + " " * (77 - len( "Status report and output retrieval for:" ) )
559  + "|" )
560  taskName = crabLogDir.replace( "crab.", "" )
561  print("| " + taskName + " " * (77 - len( taskName ) ) + "|")
562  print("*" + "=" * 78 + "*")
563  print()
564  crabOptions = { "-getoutput":"",
565  "-c": crabLogDir }
566  try:
567  theCrab.run( crabOptions )
568  except AllInOneError as e:
569  print("crab: No output retrieved for this task.")
570  crabOptions = { "-status": "",
571  "-c": crabLogDir }
572  theCrab.run( crabOptions )
573  return
574 
575  general = config.getGeneral()
576  config.set("internals","workdir",os.path.join(general["workdir"],options.Name) )
577  config.set("internals","scriptsdir",outPath)
578  config.set("general","datadir",os.path.join(general["datadir"],options.Name) )
579  config.set("general","logdir",os.path.join(general["logdir"],options.Name) )
580  config.set("general","eosdir",os.path.join("AlignmentValidation", general["eosdir"], options.Name) )
581 
582  if not os.path.exists( outPath ):
583  os.makedirs( outPath )
584  elif not os.path.isdir( outPath ):
585  raise AllInOneError("the file %s is in the way rename the Job or move it away"%outPath)
586 
587  # replace default templates by the ones specified in the "alternateTemplates" section
588  loadTemplates( config )
589 
590  #save backup configuration file
591  backupConfigFile = open( os.path.join( outPath, "usedConfiguration.ini" ) , "w" )
592  config.write( backupConfigFile )
593 
594  #copy proxy, if there is one
595  try:
596  proxyexists = int(getCommandOutput2("voms-proxy-info --timeleft")) > 10
597  except RuntimeError:
598  proxyexists = False
599 
600  if proxyexists:
601  shutil.copyfile(getCommandOutput2("voms-proxy-info --path").strip(), os.path.join(outPath, ".user_proxy"))
602 
603  validations = []
604  for validation in config.items("validation"):
605  alignmentList = [validation[1]]
606  validationsToAdd = [(validation[0],alignment) \
607  for alignment in alignmentList]
608  validations.extend(validationsToAdd)
609  jobs = [ ValidationJob( validation, config, options) \
610  for validation in validations ]
611  for job in jobs:
612  if job.needsproxy and not proxyexists:
613  raise AllInOneError("At least one job needs a grid proxy, please init one.")
614  map( lambda job: job.createJob(), jobs )
615  validations = [ job.getValidation() for job in jobs ]
616 
617  if options.mergeOfflineParallel:
618  parallelMergeObjects=createMergeScript(outPath, validations, options)['parallelMergeObjects']
619  else:
620  createMergeScript(outPath, validations, options)
621 
622 
623  print()
624  map( lambda job: job.runJob(), jobs )
625 
626  if options.autoMerge and ValidationJob.jobCount == ValidationJob.batchCount and config.getGeneral()["jobmode"].split(",")[0] == "lxBatch":
627  print("> Automatically merging jobs when they have ended")
628  # if everything is done as batch job, also submit TkAlMerge.sh to be run
629  # after the jobs have finished
630 
631  #if parallel merge scripts: manage dependencies
632  if options.mergeOfflineParallel and parallelMergeObjects!={}:
633  initID=parallelMergeObjects["init"].runJob(config).split("<")[1].split(">")[0]
634  parallelIDs=[]
635  for parallelMergeScript in parallelMergeObjects["parallel"]:
636  parallelMergeScript.addDependency(initID)
637  for job in jobs:
638  if isinstance(job.validation, OfflineValidation) and "TkAlMerge"+job.validation.alignmentToValidate.name==parallelMergeScript.name:
639  parallelMergeScript.addDependency(job.JobId)
640  parallelIDs.append(parallelMergeScript.runJob(config).split("<")[1].split(">")[0])
641  parallelMergeObjects["continue"].addDependency(parallelIDs)
642  parallelMergeObjects["continue"].addDependency(ValidationJob.batchJobIds)
643  parallelMergeObjects["continue"].runJob(config)
644 
645 
646 
647 
648  else:
649  repMap = {
650  "commands": config.getGeneral()["jobmode"].split(",")[1],
651  "jobName": "TkAlMerge",
652  "logDir": config.getGeneral()["logdir"],
653  "script": "TkAlMerge.sh",
654  "bsub": "/afs/cern.ch/cms/caf/scripts/cmsbsub",
655  "conditions": '"' + " && ".join(["ended(" + jobId + ")" for jobId in ValidationJob.batchJobIds]) + '"'
656  }
657  for ext in ("stdout", "stderr", "stdout.gz", "stderr.gz"):
658  oldlog = "%(logDir)s/%(jobName)s."%repMap + ext
659  if os.path.exists(oldlog):
660  os.remove(oldlog)
661 
662  #issue job
663  getCommandOutput2("%(bsub)s %(commands)s "
664  "-o %(logDir)s/%(jobName)s.stdout "
665  "-e %(logDir)s/%(jobName)s.stderr "
666  "-w %(conditions)s "
667  "%(logDir)s/%(script)s"%repMap)
668 
def main(argv=None)
— Main —############################
def createMergeScript(path, validations, options)
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:66
def getCommandOutput2(command)
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
double split
Definition: MVATrainer.cc:139