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 284 of file validateAlignments.py.

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

Referenced by main().

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

Definition at line 449 of file validateAlignments.py.

References configTemplates.alternateTemplate().

Referenced by main().

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

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

Definition at line 460 of file validateAlignments.py.

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

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