10 import Alignment.OfflineValidation.TkAlAllInOneTool.configTemplates \
12 import Alignment.OfflineValidation.TkAlAllInOneTool.crabWrapper
as crabWrapper
13 from Alignment.OfflineValidation.TkAlAllInOneTool.TkAlExceptions \
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
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 \
37 from Alignment.OfflineValidation.TkAlAllInOneTool.plottingOptions \
38 import PlottingOptions
39 import Alignment.OfflineValidation.TkAlAllInOneTool.globalDictionaries \
53 def __init__( self, validation, config, options ):
54 if validation[1] ==
"":
56 valString = validation[0].
split(
"->" )[0]
57 alignments = validation[0].
split(
"->" )[1]
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)
67 valString = validation[0]
68 alignments = validation[1]
69 valString = valString.split()
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.")
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."
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]
108 firstAlignName = firstAlign.name
109 secondAlignList = alignmentsList[1].
split()
110 secondAlignName = secondAlignList[0].strip()
111 if len( secondAlignList ) > 1:
112 secondRun = secondAlignList[1]
115 if secondAlignName ==
"IDEAL":
116 secondAlign = secondAlignName
120 secondAlignName = secondAlign.name
122 validation = GeometryComparison( name, firstAlign, secondAlign,
124 self.__commandLineOptions.getImages)
125 elif valType ==
"offline":
126 validation = OfflineValidation( name,
128 elif valType ==
"preexistingoffline":
129 validation = PreexistingOfflineValidation(name, self.
__config)
130 elif valType ==
"offlineDQM":
131 validation = OfflineValidationDQM( name,
133 elif valType ==
"mcValidate":
134 validation = MonteCarloValidation( name,
136 elif valType ==
"preexistingmcValidate":
137 validation = PreexistingMonteCarloValidation(name, self.
__config)
138 elif valType ==
"split":
139 validation = TrackSplittingValidation( name,
141 elif valType ==
"preexistingsplit":
142 validation = PreexistingTrackSplittingValidation(name, self.
__config)
143 elif valType ==
"zmumu":
144 validation = ZMuMuValidation( name,
146 elif valType ==
"primaryvertex":
150 raise AllInOneError(
"Unknown validation mode '%s'"%valType)
155 """This private method creates the needed files for the validation job.
157 self.validation.createConfiguration( outpath )
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 )
166 """This is the method called to create the job files."""
168 os.path.abspath( self.__commandLineOptions.Name) )
172 if self.validation.jobid:
173 self.batchJobIds.append(self.validation.jobid)
174 log =
"> " + self.validation.name +
" is already validated."
178 general = self.__config.getGeneral()
181 name = os.path.splitext( os.path.basename( script) )[0]
182 ValidationJob.jobCount += 1
183 if self.__commandLineOptions.dryRun:
184 print "%s would run: %s"%( name, os.path.basename( script) )
186 log =
"> Validating "+name
187 print "> Validating "+name
188 if self.validation.jobmode ==
"interactive":
190 ValidationJob.interactCount += 1
191 elif self.validation.jobmode.split(
",")[0] ==
"lxBatch":
193 "commands": self.validation.jobmode.split(
",")[1],
194 "logDir": general[
"logdir"],
197 "bsub":
"/afs/cern.ch/cms/caf/scripts/cmsbsub"
199 for ext
in (
"stdout",
"stderr",
"stdout.gz",
"stderr.gz"):
200 oldlog =
"%(logDir)s/%(jobName)s."%repMap + ext
201 if os.path.exists(oldlog):
205 "-o %(logDir)s/%(jobName)s.stdout "
206 "-e %(logDir)s/%(jobName)s.stderr "
210 ValidationJob.batchJobIds.append(bsubOut.split(
"<")[1].
split(
">")[0])
212 ValidationJob.batchCount += 1
213 elif self.validation.jobmode.split(
"," )[0] ==
"crab":
214 os.chdir( general[
"logdir"] )
215 crabName =
"crab." + os.path.basename( script )[:-3]
217 options = {
"-create":
"",
218 "-cfg": crabName +
".cfg",
221 theCrab.run( options )
222 except AllInOneError
as e:
223 print "crab:", str(e).
split(
"\n")[0]
225 ValidationJob.crabCount += 1
228 raise AllInOneError(
"Unknown 'jobmode'!\n"
229 "Please change this parameter either in "
230 "the [general] or in the ["
232 +
"] section to one of the following "
234 "\tinteractive\n\tlxBatch, -q <queue>\n"
235 "\tcrab, -q <queue>")
245 repMap = offlineValidationList[0].getRepMap()
247 theFile = open( outFilePath,
"w" )
248 theFile.write(
replaceByMap( configTemplates.mergeOfflineParJobsTemplate ,repMap ) )
252 config = offlineValidationList[0].config
254 repMap[
"resultPlotFile" ] = resultPlotFile
255 repMap[
"extendedInstantiation" ] =
""
257 for validation
in offlineValidationList:
258 repMap[
"extendedInstantiation" ] = validation.appendToExtendedValidation( repMap[
"extendedInstantiation" ] )
260 theFile = open( outFilePath,
"w" )
261 theFile.write(
replaceByMap( configTemplates.extendedValidationTemplate ,repMap ) )
265 config = trackSplittingValidationList[0].config
267 repMap[
"trackSplitPlotInstantiation" ] =
""
269 for validation
in trackSplittingValidationList:
270 repMap[
"trackSplitPlotInstantiation" ] = validation.appendToExtendedValidation( repMap[
"trackSplitPlotInstantiation" ] )
272 theFile = open( outFilePath,
"w" )
273 theFile.write(
replaceByMap( configTemplates.trackSplitPlotTemplate ,repMap ) )
277 repMap = PrimaryVertexValidationList[0].getRepMap()
278 repMap[
"CMSSW_BASE" ] = os.environ[
'CMSSW_BASE']
279 repMap[
"PrimaryVertexPlotInstantiation" ] =
""
281 for validation
in PrimaryVertexValidationList:
282 repMap[
"PrimaryVertexPlotInstantiation" ] = validation.appendToExtendedValidation( repMap[
"PrimaryVertexPlotInstantiation" ] )
284 theFile = open( outFilePath,
"w" )
285 theFile.write(
replaceByMap( configTemplates.PrimaryVertexPlotTemplate ,repMap ) )
289 config = zMuMuValidationList[0].config
291 repMap[
"mergeZmumuPlotsInstantiation" ] =
""
293 for validation
in zMuMuValidationList:
294 repMap[
"mergeZmumuPlotsInstantiation" ] = validation.appendToExtendedValidation( repMap[
"mergeZmumuPlotsInstantiation" ] )
296 theFile = open( outFilePath,
"w" )
297 theFile.write(
replaceByMap( configTemplates.mergeZmumuPlotsTemplate ,repMap ) )
301 if(len(validations) == 0):
302 raise AllInOneError(
"Cowardly refusing to merge nothing!")
304 config = validations[0].config
305 repMap = config.getGeneral()
308 "CompareAlignments":
"",
309 "RunExtendedOfflineValidation":
"",
310 "RunTrackSplitPlot":
"",
311 "MergeZmumuPlots":
"",
312 "RunPrimaryVertexPlot":
"",
313 "CMSSW_BASE": os.environ[
"CMSSW_BASE"],
314 "SCRAM_ARCH": os.environ[
"SCRAM_ARCH"],
315 "CMSSW_RELEASE_BASE": os.environ[
"CMSSW_RELEASE_BASE"],
319 for validation
in validations:
320 for referenceName
in validation.filesToCompare:
321 validationName =
"%s.%s"%(validation.__class__.__name__, referenceName)
322 validationName = validationName.split(
".%s"%GenericValidation.defaultReferenceName )[0]
323 validationName = validationName.split(
"Preexisting")[-1]
324 if validationName
in comparisonLists:
325 comparisonLists[ validationName ].
append( validation )
327 comparisonLists[ validationName ] = [ validation ]
331 repMap[
"haddLoop"] =
"mergeRetCode=0\n"
332 repMap[
"rmUnmerged"] = (
"if [[ mergeRetCode -eq 0 ]]; then\n"
333 " echo -e \\n\"Merging succeeded, removing original files.\"\n")
334 repMap[
"copyMergeScripts"] =
""
335 repMap[
"mergeParallelFilePrefixes"] =
""
339 for validationType
in comparisonLists:
340 for validation
in comparisonLists[validationType]:
341 if isinstance(validation, PreexistingValidation)
or validation.NJobs == 1:
343 if validationType
not in anythingToMerge:
344 anythingToMerge += [validationType]
345 repMap[
"haddLoop"] +=
'\n\n\n\necho -e "\n\nMerging results from %s jobs"\n\n' % validationType
346 repMap[
"haddLoop"] = validation.appendToMerge(repMap[
"haddLoop"])
347 repMap[
"haddLoop"] +=
"tmpMergeRetCode=${?}\n"
348 repMap[
"haddLoop"] += (
"if [[ tmpMergeRetCode -eq 0 ]]; then "
350 +validation.getRepMap()[
"finalOutputFile"]
351 +
" root://eoscms//eos/cms"
352 +validation.getRepMap()[
"finalResultFile"]
354 repMap[
"haddLoop"] += (
"if [[ ${tmpMergeRetCode} -gt ${mergeRetCode} ]]; then "
355 "mergeRetCode=${tmpMergeRetCode}; fi\n")
356 for f
in validation.getRepMap()[
"outputFiles"]:
357 longName = os.path.join(
"/store/caf/user/$USER/",
358 validation.getRepMap()[
"eosdir"], f)
359 repMap[
"rmUnmerged"] +=
" $eos rm "+longName+
"\n"
360 repMap[
"rmUnmerged"] += (
"else\n"
361 " echo -e \\n\"WARNING: Merging failed, unmerged"
362 " files won't be deleted.\\n"
363 "(Ignore this warning if merging was done earlier)\"\n"
366 if "OfflineValidation" in anythingToMerge:
367 repMap[
"mergeOfflineParJobsScriptPath"] = os.path.join(path,
"TkAlOfflineJobsMerge.C")
370 repMap[
"mergeOfflineParJobsScriptPath"] )
371 repMap[
"copyMergeScripts"] += (
"cp .oO[Alignment/OfflineValidation]Oo./scripts/merge_TrackerOfflineValidation.C .\n"
372 "rfcp %s .\n" % repMap[
"mergeOfflineParJobsScriptPath"])
373 repMap_offline = repMap.copy()
375 repMap[
"copyMergeScripts"] = \
376 replaceByMap(repMap[
"copyMergeScripts"], repMap_offline)
381 repMap[
"DownloadData"] +=
replaceByMap( configTemplates.mergeParallelResults, repMap )
383 repMap[
"DownloadData"] =
""
385 if "OfflineValidation" in comparisonLists:
386 repMap[
"extendedValScriptPath"] = os.path.join(path,
"TkAlExtendedOfflineValidation.C")
388 repMap[
"extendedValScriptPath"],
390 repMap_offline = repMap.copy()
392 repMap[
"RunExtendedOfflineValidation"] = \
393 replaceByMap(configTemplates.extendedValidationExecution, repMap_offline)
395 if "TrackSplittingValidation" in comparisonLists:
396 repMap[
"trackSplitPlotScriptPath"] = \
397 os.path.join(path,
"TkAlTrackSplitPlot.C")
399 repMap[
"trackSplitPlotScriptPath"] )
400 repMap_split = repMap.copy()
402 repMap[
"RunTrackSplitPlot"] = \
403 replaceByMap(configTemplates.trackSplitPlotExecution, repMap_split)
405 if "ZMuMuValidation" in comparisonLists:
406 repMap[
"mergeZmumuPlotsScriptPath"] = \
407 os.path.join(path,
"TkAlMergeZmumuPlots.C")
409 repMap[
"mergeZmumuPlotsScriptPath"] )
410 repMap_zMuMu = repMap.copy()
412 repMap[
"MergeZmumuPlots"] = \
413 replaceByMap(configTemplates.mergeZmumuPlotsExecution, repMap_zMuMu)
415 if "PrimaryVertexValidation" in comparisonLists:
416 repMap[
"PrimaryVertexPlotScriptPath"] = \
417 os.path.join(path,
"TkAlPrimaryVertexValidationPlot.C")
420 repMap[
"PrimaryVertexPlotScriptPath"] )
421 repMap_PVVal = repMap.copy()
423 repMap[
"RunPrimaryVertexPlot"] = \
424 replaceByMap(configTemplates.PrimaryVertexPlotExecution, repMap_PVVal)
426 repMap[
"CompareAlignments"] =
"#run comparisons"
427 if "OfflineValidation" in comparisonLists:
428 compareStrings = [ val.getCompareStrings(
"OfflineValidation")
for val
in comparisonLists[
"OfflineValidation"] ]
429 compareStringsPlain = [ val.getCompareStrings(
"OfflineValidation", plain=
True)
for val
in comparisonLists[
"OfflineValidation"] ]
431 repMap_offline = repMap.copy()
433 repMap_offline.update({
"validationId":
"OfflineValidation",
434 "compareStrings":
" , ".
join(compareStrings),
435 "compareStringsPlain":
" ".
join(compareStringsPlain) })
437 repMap[
"CompareAlignments"] += \
438 replaceByMap(configTemplates.compareAlignmentsExecution, repMap_offline)
440 filePath = os.path.join(path,
"TkAlMerge.sh")
441 theFile = open( filePath,
"w" )
442 theFile.write(
replaceByMap( configTemplates.mergeTemplate, repMap ) )
444 os.chmod(filePath,0o755)
449 if config.has_section(
"alternateTemplates"):
450 for templateName
in config.options(
"alternateTemplates"):
451 if templateName ==
"AutoAlternates":
453 newTemplateName = config.get(
"alternateTemplates", templateName )
462 optParser = optparse.OptionParser()
463 optParser.description =
"""All-in-one Alignment Validation.
464 This will run various validation procedures either on batch queues or interactively.
465 If no name is given (-N parameter) a name containing time and date is created automatically.
466 To merge the outcome of all validation procedures run TkAlMerge.sh in your validation's directory.
468 optParser.add_option(
"-n",
"--dryRun", dest=
"dryRun", action=
"store_true", default=
False,
469 help=
"create all scripts and cfg File but do not start jobs (default=False)")
470 optParser.add_option(
"--getImages", dest=
"getImages", action=
"store_true", default=
True,
471 help=
"get all Images created during the process (default= True)")
472 defaultConfig =
"TkAlConfig.ini"
473 optParser.add_option(
"-c",
"--config", dest=
"config", default = defaultConfig,
474 help=
"configuration to use (default TkAlConfig.ini) this can be a comma-seperated list of all .ini file you want to merge", metavar=
"CONFIG")
475 optParser.add_option(
"-N",
"--Name", dest=
"Name",
476 help=
"Name of this validation (default: alignmentValidation_DATE_TIME)", metavar=
"NAME")
477 optParser.add_option(
"-r",
"--restrictTo", dest=
"restrictTo",
478 help=
"restrict validations to given modes (comma seperated) (default: no restriction)", metavar=
"RESTRICTTO")
479 optParser.add_option(
"-s",
"--status", dest=
"crabStatus", action=
"store_true", default =
False,
480 help=
"get the status of the crab jobs", metavar=
"STATUS")
481 optParser.add_option(
"-d",
"--debug", dest=
"debugMode", action=
"store_true",
483 help=
"run the tool to get full traceback of errors",
485 optParser.add_option(
"-m",
"--autoMerge", dest=
"autoMerge", action=
"store_true", default =
False,
486 help=
"submit TkAlMerge.sh to run automatically when all jobs have finished (default=False)."
487 " Works only for batch jobs")
489 (options, args) = optParser.parse_args(argv)
491 if not options.restrictTo ==
None:
492 options.restrictTo = options.restrictTo.split(
",")
494 options.config = [ os.path.abspath( iniFile )
for iniFile
in \
495 options.config.split(
"," ) ]
496 config = BetterConfigParser()
497 outputIniFileSet = set( config.read( options.config ) )
498 failedIniFiles = [ iniFile
for iniFile
in options.config
if iniFile
not in outputIniFileSet ]
501 if options.config == [ os.path.abspath( defaultConfig ) ]:
502 if (
not options.crabStatus )
and \
503 (
not os.path.exists( defaultConfig ) ):
504 raise AllInOneError(
"Default 'ini' file '%s' not found!\n"
505 "You can specify another name with the "
506 "command line option '-c'/'--config'."
509 for iniFile
in failedIniFiles:
510 if not os.path.exists( iniFile ):
511 raise AllInOneError(
"'%s' does not exist. Please check for "
512 "typos in the filename passed to the "
513 "'-c'/'--config' option!"
516 raise AllInOneError((
"'%s' does exist, but parsing of the "
517 "content failed!" ) % iniFile)
520 if options.Name ==
None:
521 if not options.crabStatus:
522 options.Name =
"alignmentValidation_%s"%(datetime.datetime.now().strftime(
"%y%m%d_%H%M%S"))
524 existingValDirs = fnmatch.filter( os.walk(
'.' ).
next()[1],
525 "alignmentValidation_*" )
526 if len( existingValDirs ) > 0:
527 options.Name = existingValDirs[-1]
529 print "Cannot guess last working directory!"
530 print (
"Please use the parameter '-N' or '--Name' to specify "
531 "the task for which you want a status report." )
535 outPath = os.path.abspath( options.Name )
538 if options.crabStatus:
540 crabLogDirs = fnmatch.filter( os.walk(
'.').
next()[1],
"crab.*" )
541 if len( crabLogDirs ) == 0:
542 print "Found no crab tasks for job name '%s'"%( options.Name )
545 for crabLogDir
in crabLogDirs:
547 print "*" +
"=" * 78 +
"*"
548 print (
"| Status report and output retrieval for:"
549 +
" " * (77 - len(
"Status report and output retrieval for:" ) )
551 taskName = crabLogDir.replace(
"crab.",
"" )
552 print "| " + taskName +
" " * (77 - len( taskName ) ) +
"|"
553 print "*" +
"=" * 78 +
"*"
555 crabOptions = {
"-getoutput":
"",
558 theCrab.run( crabOptions )
559 except AllInOneError
as e:
560 print "crab: No output retrieved for this task."
561 crabOptions = {
"-status":
"",
563 theCrab.run( crabOptions )
566 general = config.getGeneral()
567 config.set(
"internals",
"workdir",os.path.join(general[
"workdir"],options.Name) )
568 config.set(
"general",
"datadir",os.path.join(general[
"datadir"],options.Name) )
569 config.set(
"general",
"logdir",os.path.join(general[
"logdir"],options.Name) )
570 config.set(
"general",
"eosdir",os.path.join(
"AlignmentValidation", general[
"eosdir"], options.Name) )
572 if not os.path.exists( outPath ):
573 os.makedirs( outPath )
574 elif not os.path.isdir( outPath ):
575 raise AllInOneError(
"the file %s is in the way rename the Job or move it away"%outPath)
581 backupConfigFile = open( os.path.join( outPath,
"usedConfiguration.ini" ) ,
"w" )
582 config.write( backupConfigFile )
585 for validation
in config.items(
"validation"):
586 alignmentList = [validation[1]]
587 validationsToAdd = [(validation[0],alignment) \
588 for alignment
in alignmentList]
589 validations.extend(validationsToAdd)
591 for validation
in validations ]
592 map(
lambda job: job.createJob(), jobs )
593 validations = [ job.getValidation()
for job
in jobs ]
598 map(
lambda job: job.runJob(), jobs )
600 if options.autoMerge:
603 if ValidationJob.jobCount == ValidationJob.batchCount
and config.getGeneral()[
"jobmode"].
split(
",")[0] ==
"lxBatch":
604 print "> Automatically merging jobs when they have ended"
606 "commands": config.getGeneral()[
"jobmode"].
split(
",")[1],
607 "jobName":
"TkAlMerge",
608 "logDir": config.getGeneral()[
"logdir"],
609 "script":
"TkAlMerge.sh",
610 "bsub":
"/afs/cern.ch/cms/caf/scripts/cmsbsub",
611 "conditions":
'"' +
" && ".
join([
"ended(" + jobId +
")" for jobId
in ValidationJob.batchJobIds]) +
'"'
613 for ext
in (
"stdout",
"stderr",
"stdout.gz",
"stderr.gz"):
614 oldlog =
"%(logDir)s/%(jobName)s."%repMap + ext
615 if os.path.exists(oldlog):
619 "-o %(logDir)s/%(jobName)s.stdout "
620 "-e %(logDir)s/%(jobName)s.stderr "
622 "%(logDir)s/%(script)s"%repMap)
624 if __name__ ==
"__main__":
626 if "-d" in sys.argv[1:]
or "--debug" in sys.argv[1:]:
631 except AllInOneError
as e:
632 print "\nAll-In-One Tool:", str(e)
def createTrackSplitPlotScript
— Classes —############################
def createMergeZmumuPlotsScript
boost::dynamic_bitset append(const boost::dynamic_bitset<> &bs1, const boost::dynamic_bitset<> &bs2)
this method takes two bitsets bs1 and bs2 and returns result of bs2 appended to the end of bs1 ...
def createOfflineParJobsMergeScript
def main
— Main —############################
def createExtendedValidationScript
def createPrimaryVertexPlotScript
def alternateTemplate
### Alternate Templates ###
static std::string join(char **cmd)
def replaceByMap
— Helpers —############################