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
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, OfflineValidationParallel
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 import Alignment.OfflineValidation.TkAlAllInOneTool.globalDictionaries \
39 def __init__( self, validation, config, options ):
40 if validation[1] ==
"":
42 valString = validation[0].
split(
"->" )[0]
43 alignments = validation[0].
split(
"->" )[1]
45 if "->" in validation[0]:
46 msg = (
"Instead of using the intermediate syntax\n'"
47 +valString.strip()+
"-> "+alignments.strip()
48 +
":'\nyou have to use the now fully supported syntax \n'"
49 +valString.strip()+
": "
50 +alignments.strip()+
"'.")
51 raise AllInOneError(msg)
53 valString = validation[0]
54 alignments = validation[1]
55 valString = valString.split()
62 section =
"offline" +
":" + self.
__valName
65 if not self.__config.has_section( section ):
66 raise AllInOneError, (
"Validation '%s' of type '%s' is requested in"
67 " '[validation]' section, but is not defined."
68 "\nYou have to add a '[%s]' section."
75 if valType ==
"compare":
76 alignmentsList = alignments.split(
"," )
77 firstAlignList = alignmentsList[0].
split()
78 firstAlignName = firstAlignList[0].strip()
79 if firstAlignName ==
"IDEAL":
80 raise AllInOneError, (
"'IDEAL' has to be the second (reference)"
81 " alignment in 'compare <val_name>: "
82 "<alignment> <reference>'.")
83 if len( firstAlignList ) > 1:
84 firstRun = firstAlignList[1]
87 firstAlign = Alignment( firstAlignName, self.
__config, firstRun )
88 secondAlignList = alignmentsList[1].
split()
89 secondAlignName = secondAlignList[0].strip()
90 if len( secondAlignList ) > 1:
91 secondRun = secondAlignList[1]
94 if secondAlignName ==
"IDEAL":
95 secondAlign = secondAlignName
97 secondAlign = Alignment( secondAlignName, self.
__config,
101 randomWorkdirPart = \
102 globalDictionaries.alignRandDict[firstAlignName]
104 randomWorkdirPart =
None
106 validation = GeometryComparison( name, firstAlign, secondAlign,
108 self.__commandLineOptions.getImages,
110 globalDictionaries.alignRandDict[firstAlignName] = \
111 validation.randomWorkdirPart
112 if not secondAlignName ==
"IDEAL":
113 globalDictionaries.alignRandDict[secondAlignName] = \
114 validation.randomWorkdirPart
115 elif valType ==
"offline":
116 validation = OfflineValidation( name,
118 elif valType ==
"offlineDQM":
119 validation = OfflineValidationDQM( name,
121 elif valType ==
"offlineParallel":
122 validation = OfflineValidationParallel( name,
124 elif valType ==
"mcValidate":
125 validation = MonteCarloValidation( name,
127 elif valType ==
"split":
128 validation = TrackSplittingValidation( name,
130 elif valType ==
"zmumu":
131 validation = ZMuMuValidation( name,
134 raise AllInOneError,
"Unknown validation mode '%s'"%valType
138 """This private method creates the needed files for the validation job.
140 self.validation.createConfiguration( outpath )
141 self.
__scripts = self.validation.createScript( outpath )
142 if jobMode.split(
',' )[0] ==
"crab":
143 self.validation.createCrabCfg( outpath )
147 """This is the method called to create the job files."""
149 os.path.abspath( self.__commandLineOptions.Name) )
152 general = self.__config.getGeneral()
155 name = os.path.splitext( os.path.basename( script) )[0]
156 if self.__commandLineOptions.dryRun:
157 print "%s would run: %s"%( name, os.path.basename( script) )
159 log =
"> Validating "+name
160 print "> Validating "+name
161 if self.validation.jobmode ==
"interactive":
163 elif self.validation.jobmode.split(
",")[0] ==
"lxBatch":
165 "commands": self.validation.jobmode.split(
",")[1],
166 "logDir": general[
"logdir"],
169 "bsub":
"/afs/cern.ch/cms/caf/scripts/cmsbsub"
172 "-o %(logDir)s/%(jobName)s.stdout -e "
173 "%(logDir)s/%(jobName)s.stderr "
175 elif self.validation.jobmode.split(
"," )[0] ==
"crab":
176 os.chdir( general[
"logdir"] )
177 crabName =
"crab." + os.path.basename( script )[:-3]
179 options = {
"-create":
"",
180 "-cfg": crabName +
".cfg",
183 theCrab.run( options )
184 except AllInOneError, e:
185 print "crab:", str(e).
split(
"\n")[0]
188 raise AllInOneError, (
"Unknown 'jobmode'!\n"
189 "Please change this parameter either in "
190 "the [general] or in the ["
192 +
"] section to one of the following "
194 "\tinteractive\n\tlxBatch, -q <queue>\n"
195 "\tcrab, -q <queue>")
204 repMap = offlineValidationList[0].getRepMap()
205 repMap[
"mergeOfflinParJobsInstantiation" ] =
""
207 theFile = open( outFilePath,
"w" )
208 theFile.write(
replaceByMap( configTemplates.mergeOfflineParJobsTemplate ,repMap ) )
212 repMap = offlineValidationList[0].getRepMap()
213 repMap[
"resultPlotFile" ] = resultPlotFile
214 repMap[
"extendedInstantiation" ] =
""
216 for validation
in offlineValidationList:
217 repMap[
"extendedInstantiation" ] = validation.appendToExtendedValidation( repMap[
"extendedInstantiation" ] )
219 theFile = open( outFilePath,
"w" )
221 theFile.write(
replaceByMap( configTemplates.extendedValidationTemplate ,repMap ) )
225 repMap = trackSplittingValidationList[0].getRepMap()
226 repMap[
"trackSplitPlotInstantiation" ] =
""
228 for validation
in trackSplittingValidationList:
229 repMap[
"trackSplitPlotInstantiation" ] = validation.appendToExtendedValidation( repMap[
"trackSplitPlotInstantiation" ] )
231 theFile = open( outFilePath,
"w" )
233 theFile.write(
replaceByMap( configTemplates.trackSplitPlotTemplate ,repMap ) )
237 if(len(validations) == 0):
238 msg =
"Cowardly refusing to merge nothing!"
239 raise AllInOneError(msg)
241 repMap = validations[0].getRepMap()
244 "CompareAlignments":
"",
245 "RunExtendedOfflineValidation":
"",
246 "RunTrackSplitPlot":
""
251 for validation
in validations:
252 for referenceName
in validation.filesToCompare:
253 validationName =
"%s.%s"%(validation.__class__.__name__, referenceName)
254 validationName = validationName.split(
".%s"%GenericValidation.defaultReferenceName )[0]
255 if validationName
in comparisonLists:
256 comparisonLists[ validationName ].
append( validation )
258 comparisonLists[ validationName ] = [ validation ]
259 if validationName ==
"OfflineValidation":
260 resultPlotFile = validationName
262 if "OfflineValidation" in comparisonLists:
263 repMap[
"extendeValScriptPath"] = \
264 os.path.join(path,
"TkAlExtendedOfflineValidation.C")
266 repMap[
"extendeValScriptPath"],
268 repMap[
"RunExtendedOfflineValidation"] = \
269 replaceByMap(configTemplates.extendedValidationExecution, repMap)
271 if "TrackSplittingValidation" in comparisonLists:
272 repMap[
"trackSplitPlotScriptPath"] = \
273 os.path.join(path,
"TkAlTrackSplitPlot.C")
275 repMap[
"trackSplitPlotScriptPath"] )
276 repMap[
"RunTrackSplitPlot"] = \
277 replaceByMap(configTemplates.trackSplitPlotExecution, repMap)
279 repMap[
"CompareAlignments"] =
"#run comparisons"
280 for validationId
in comparisonLists:
281 compareStrings = [ val.getCompareStrings(validationId)
for val
in comparisonLists[validationId] ]
283 repMap.update({
"validationId": validationId,
284 "compareStrings":
" , ".
join(compareStrings) })
286 repMap[
"CompareAlignments"] += \
287 replaceByMap(configTemplates.compareAlignmentsExecution, repMap)
289 filePath = os.path.join(path,
"TkAlMerge.sh")
290 theFile = open( filePath,
"w" )
291 theFile.write(
replaceByMap( configTemplates.mergeTemplate, repMap ) )
293 os.chmod(filePath,0755)
298 if( len(validations) == 0 ):
299 raise AllInOneError,
"cowardly refusing to merge nothing!"
301 repMap = validations[0].getRepMap()
304 "CompareAlignments":
"",
305 "RunExtendedOfflineValidation":
""
310 for validation
in validations:
311 for referenceName
in validation.filesToCompare:
312 validationName =
"%s.%s"%(validation.__class__.__name__, referenceName)
313 validationName = validationName.split(
".%s"%GenericValidation.defaultReferenceName )[0]
314 if validationName
in comparisonLists:
315 comparisonLists[ validationName ].
append( validation )
317 comparisonLists[ validationName ] = [ validation ]
318 if validationName ==
"OfflineValidationParallel":
319 resultPlotFile = validationName
321 if "OfflineValidationParallel" in comparisonLists:
322 repMap[
"extendeValScriptPath"] = os.path.join(path,
"TkAlExtendedOfflineValidation.C")
324 repMap[
"mergeOfflineParJobsScriptPath"] = os.path.join(path,
"TkAlOfflineJobsMerge.C")
326 repMap[
"mergeOfflineParJobsScriptPath"] )
330 repMap[
"haddLoop"] =
"mergeRetCode=0\n"
331 repMap[
"rmUnmerged"] =
"if [[ mergeRetCode -eq 0 ]]; then\n"
332 for validation
in comparisonLists[
"OfflineValidationParallel"]:
333 repMap[
"haddLoop"] = validation.appendToMergeParJobs(repMap[
"haddLoop"])
334 repMap[
"haddLoop"] +=
"tmpMergeRetCode=${?}\n"
335 repMap[
"haddLoop"] += (
"if [[ mergeRetCode -eq 0 ]]; "
336 "then mergeRetCode=${tmpMergeRetCode}; "
338 repMap[
"haddLoop"] += (
"cmsStage -f "
339 +validation.getRepMap()[
"outputFile"]
341 +validation.getRepMap()[
"resultFile"]
343 for f
in validation.outputFiles:
344 longName = os.path.join(
"/store/caf/user/$USER/",
345 validation.getRepMap()[
"eosdir"], f)
346 repMap[
"rmUnmerged"] +=
" cmsRm "+longName+
"\n"
347 repMap[
"rmUnmerged"] += (
"else\n"
348 " echo \"WARNING: Merging failed, unmerged"
349 " files won't be deleted.\"\n"
352 repMap[
"RunExtendedOfflineValidation"] = \
353 replaceByMap(configTemplates.extendedValidationExecution, repMap)
357 repMap[
"DownloadData"] +=
replaceByMap(
"rfcp .oO[mergeOfflineParJobsScriptPath]Oo. .", repMap)
358 repMap[
"DownloadData"] +=
replaceByMap( configTemplates.mergeOfflineParallelResults, repMap )
360 repMap[
"CompareAlignments"] =
"#run comparisons"
361 for validationId
in comparisonLists:
362 compareStrings = [ val.getCompareStrings(validationId)
for val
in comparisonLists[validationId] ]
364 repMap.update({
"validationId": validationId,
365 "compareStrings":
" , ".
join(compareStrings) })
367 repMap[
"CompareAlignments"] += \
368 replaceByMap(configTemplates.compareAlignmentsExecution, repMap)
370 filePath = os.path.join(path,
"TkAlMerge.sh")
371 theFile = open( filePath,
"w" )
372 theFile.write(
replaceByMap( configTemplates.mergeTemplate, repMap ) )
374 os.chmod(filePath,0755)
379 if config.has_section(
"alternateTemplates"):
380 for templateName
in config.options(
"alternateTemplates"):
381 newTemplateName = config.get(
"alternateTemplates", templateName )
390 optParser = optparse.OptionParser()
391 optParser.description =
""" all-in-one alignment Validation
392 This will run various validation procedures either on batch queues or interactviely.
394 If no name is given (-N parameter) a name containing time and date is created automatically
396 To merge the outcome of all validation procedures run TkAlMerge.sh in your validation's directory.
398 optParser.add_option(
"-n",
"--dryRun", dest=
"dryRun", action=
"store_true", default=
False,
399 help=
"create all scripts and cfg File but do not start jobs (default=False)")
400 optParser.add_option(
"--getImages", dest=
"getImages", action=
"store_true", default=
False,
401 help=
"get all Images created during the process (default= False)")
402 defaultConfig =
"TkAlConfig.ini"
403 optParser.add_option(
"-c",
"--config", dest=
"config", default = defaultConfig,
404 help=
"configuration to use (default TkAlConfig.ini) this can be a comma-seperated list of all .ini file you want to merge", metavar=
"CONFIG")
405 optParser.add_option(
"-N",
"--Name", dest=
"Name",
406 help=
"Name of this validation (default: alignmentValidation_DATE_TIME)", metavar=
"NAME")
407 optParser.add_option(
"-r",
"--restrictTo", dest=
"restrictTo",
408 help=
"restrict validations to given modes (comma seperated) (default: no restriction)", metavar=
"RESTRICTTO")
409 optParser.add_option(
"-s",
"--status", dest=
"crabStatus", action=
"store_true", default =
False,
410 help=
"get the status of the crab jobs", metavar=
"STATUS")
411 optParser.add_option(
"-d",
"--debug", dest=
"debugMode", action=
"store_true",
413 help=
"Run the tool to get full traceback of errors.",
416 (options, args) = optParser.parse_args(argv)
418 if not options.restrictTo ==
None:
419 options.restrictTo = options.restrictTo.split(
",")
421 options.config = [ os.path.abspath( iniFile )
for iniFile
in \
422 options.config.split(
"," ) ]
423 config = BetterConfigParser()
424 outputIniFileSet = set( config.read( options.config ) )
425 failedIniFiles = [ iniFile
for iniFile
in options.config
if iniFile
not in outputIniFileSet ]
428 if options.config == [ os.path.abspath( defaultConfig ) ]:
429 if (
not options.crabStatus )
and \
430 (
not os.path.exists( defaultConfig ) ):
431 raise AllInOneError, (
"Default 'ini' file '%s' not found!\n"
432 "You can specify another name with the "
433 "command line option '-c'/'--config'."
436 for iniFile
in failedIniFiles:
437 if not os.path.exists( iniFile ):
438 raise AllInOneError, (
"'%s' does not exist. Please check for "
439 "typos in the filename passed to the "
440 "'-c'/'--config' option!"
443 raise AllInOneError, (
"'%s' does exist, but parsing of the "
447 if options.Name ==
None:
448 if not options.crabStatus:
449 options.Name =
"alignmentValidation_%s"%(datetime.datetime.now().strftime(
"%y%m%d_%H%M%S"))
451 existingValDirs = fnmatch.filter( os.walk(
'.' ).
next()[1],
452 "alignmentValidation_*" )
453 if len( existingValDirs ) > 0:
454 options.Name = existingValDirs[-1]
456 print "Cannot guess last working directory!"
457 print (
"Please use the parameter '-N' or '--Name' to specify "
458 "the task for which you want a status report." )
462 outPath = os.path.abspath( options.Name )
465 if options.crabStatus:
467 crabLogDirs = fnmatch.filter( os.walk(
'.').
next()[1],
"crab.*" )
468 if len( crabLogDirs ) == 0:
469 print "Found no crab tasks for job name '%s'"%( options.Name )
472 for crabLogDir
in crabLogDirs:
474 print "*" +
"=" * 78 +
"*"
475 print (
"| Status report and output retrieval for:"
476 +
" " * (77 - len(
"Status report and output retrieval for:" ) )
478 taskName = crabLogDir.replace(
"crab.",
"" )
479 print "| " + taskName +
" " * (77 - len( taskName ) ) +
"|"
480 print "*" +
"=" * 78 +
"*"
482 crabOptions = {
"-getoutput":
"",
485 theCrab.run( crabOptions )
486 except AllInOneError, e:
487 print "crab: No output retrieved for this task."
488 crabOptions = {
"-status":
"",
490 theCrab.run( crabOptions )
493 general = config.getGeneral()
494 config.set(
"internals",
"workdir",os.path.join(general[
"workdir"],options.Name) )
495 config.set(
"general",
"datadir",os.path.join(general[
"datadir"],options.Name) )
496 config.set(
"general",
"logdir",os.path.join(general[
"logdir"],options.Name) )
497 config.set(
"general",
"eosdir",os.path.join(
"AlignmentValidation", general[
"eosdir"], options.Name) )
501 if os.path.isdir( outPath ):
502 shutil.rmtree( outPath )
504 if not os.path.exists( outPath ):
505 os.makedirs( outPath )
506 elif not os.path.isdir( outPath ):
507 raise AllInOneError,
"the file %s is in the way rename the Job or move it away"%outPath
513 backupConfigFile = open( os.path.join( outPath,
"usedConfiguration.ini" ) ,
"w" )
514 config.write( backupConfigFile )
517 for validation
in config.items(
"validation"):
518 alignmentList = validation[1].
split(config.getSep())
519 validationsToAdd = [(validation[0],alignment) \
520 for alignment
in alignmentList]
521 validations.extend(validationsToAdd)
523 for validation
in validations ]
524 map(
lambda job: job.createJob(), jobs )
525 validations = [ job.getValidation()
for job
in jobs ]
527 if "OfflineValidationParallel" not in [val.__class__.__name__
for val
in validations]:
533 map(
lambda job: job.runJob(), jobs )
536 if __name__ ==
"__main__":
538 if "-d" in sys.argv[1:]
or "--debug" in sys.argv[1:]:
543 except AllInOneError, e:
544 print "\nAll-In-One Tool:", str(e)
def createOfflineJobsMergeScript
def createParallelMergeScript
def createTrackSplitPlotScript
— Classes —############################
def main
— Main —############################
def createExtendedValidationScript
def alternateTemplate
### Alternate Templates ###
static std::string join(char **cmd)
def replaceByMap
— Helpers —############################