00001
00002
00003 import os
00004 import sys
00005 import ConfigParser
00006 import optparse
00007 import datetime
00008 from pprint import pprint
00009
00010 import configTemplates
00011
00012
00013
00014 def replaceByMap(target, map):
00015 result = target
00016 for id in map:
00017
00018 lifeSaver = 10e3
00019 iteration = 0
00020 while ".oO[" in result and "]Oo." in result:
00021 for id in map:
00022 result = result.replace(".oO["+id+"]Oo.",map[id])
00023 iteration += 1
00024 if iteration > lifeSaver:
00025 problematicLines = ""
00026 print map.keys()
00027 for line in result.splitlines():
00028 if ".oO[" in result and "]Oo." in line:
00029 problematicLines += "%s\n"%line
00030 raise StandardError, "Oh Dear, there seems to be an endless loop in replaceByMap!!\n%s\nrepMap"%problematicLines
00031 return result
00032
00033
00034 def getCommandOutput2(command):
00035 child = os.popen(command)
00036 data = child.read()
00037 err = child.close()
00038 if err:
00039 raise RuntimeError, '%s failed w/ exit code %d' % (command, err)
00040 return data
00041
00042
00043 def castorDirExists(path):
00044 if path[-1] == "/":
00045 path = path[:-1]
00046 containingPath = os.path.join( *path.split("/")[:-1] )
00047 dirInQuestion = path.split("/")[-1]
00048 try:
00049 rawLines =getCommandOutput2("rfdir /"+containingPath).splitlines()
00050 except RuntimeError:
00051 return False
00052 for line in rawLines:
00053 if line.split()[0][0] == "d":
00054 if line.split()[8] == dirInQuestion:
00055 return True
00056 return False
00057
00058
00059 class BetterConfigParser(ConfigParser.ConfigParser):
00060 def optionxform(self, optionstr):
00061 return optionstr
00062
00063 def exists( self, section, option):
00064 try:
00065 items = self.items(section)
00066 except ConfigParser.NoSectionError:
00067 return False
00068 for item in items:
00069 if item[0] == option:
00070 return True
00071 return False
00072
00073 class Alignment:
00074 def __init__(self, name, config):
00075 section = "alignment:%s"%name
00076 self.name = name
00077 if not config.has_section( section ):
00078 raise StandardError, "section %s not found. Please define the alignment!"%section
00079 self.mode = config.get(section, "mode").split()
00080 self.dbpath = config.get(section, "dbpath")
00081 self.__testDbExist( self.dbpath )
00082
00083 self.errordbpath = "frontier://FrontierProd/CMS_COND_21X_ALIGNMENT"
00084 self.errortag = "TrackerIdealGeometryErrors210_mc"
00085 if config.has_option(section,"errordbpath") and config.has_option(section,"errortag"):
00086 self.errordbpath = config.get(section, "errordbpath")
00087 self.__testDbExist( self.errordbpath )
00088 self.errortag = config.get(section,"errortag")
00089 else:
00090 if config.has_option(section,"errordbpath") or config.has_option(section,"errortag"):
00091 raise StandardError, "in alignment:%s you have to provide either both errordbpath _and_ errortag or none of both."%name
00092 self.tag = config.get(section,"tag")
00093
00094 self.color = config.get(section,"color")
00095 self.style = config.get(section,"style")
00096 self.compareTo = {}
00097 for option in config.options( section ):
00098 if option.startswith("compare|"):
00099 alignmentName = option.split("compare|")[1]
00100 comparisonList = config.get( section, option ).split()
00101 if len(comparisonList) == 0:
00102 raise StandardError, "empty comaprison list '%s' given for %s"%(config.get( section, option ), alignmentName )
00103 self.compareTo[ alignmentName ] = comparisonList
00104 if self.compareTo == {}:
00105 self.compareTo = {
00106 "IDEAL":["Tracker","SubDets"]
00107 }
00108
00109 def __testDbExist(self, dbpath):
00110
00111 return
00112 if not dbpath.startswith("sqlite_file:"):
00113 print "WARNING: could not check existence for",dbpath
00114 else:
00115 if not os.path.exists( dbpath.split("sqlite_file:")[1] ):
00116 raise "could not find file: '%s'"%dbpath.split("sqlite_file:")[1]
00117
00118 def restrictTo( self, restriction ):
00119 result = []
00120 if not restriction == None:
00121 for mode in self.mode:
00122 if mode in restriction:
00123 result.append( mode )
00124 self.mode = result
00125
00126 def getRepMap( self ):
00127 result = {
00128 "name": self.name,
00129 "dbpath": self.dbpath,
00130 "errordbpath": self.errordbpath,
00131 "tag": self.tag,
00132 "errortag": self.errortag,
00133 "color": self.color,
00134 "style": self.style
00135
00136 }
00137 return result
00138
00139 def getLoadTemplate(self):
00140 return replaceByMap( configTemplates.dbLoadTemplate, self.getRepMap() )
00141
00142 def createValidations(self, config, options, allAlignments=[]):
00143 """
00144 config is the overall configuration
00145 options are the options as paresed from command line
00146 allAlignemts is a list of Alignment objects the is used to generate Alignment_vs_Alignemnt jobs
00147 """
00148 result = []
00149 for validationName in self.mode:
00150 if validationName == "compare":
00151 randomWorkdirPart = None
00152
00153 for alignmentName in self.compareTo:
00154 referenceAlignment = 'IDEAL'
00155 if not alignmentName == "IDEAL":
00156 foundAlignment = False
00157 for alignment in allAlignments:
00158 if alignment.name == alignmentName:
00159 referenceAlignment = alignment
00160 foundAlignment = True
00161 if not foundAlignment:
00162 raise StandardError, " could not find alignment called '%s'"%alignmentName
00163 result.append( GeometryComparision( self, referenceAlignment, config, options.getImages, randomWorkdirPart ) )
00164 if randomWorkdirPart == None:
00165 randomWorkdirPart = result[-1].randomWorkdirPart
00166 elif validationName == "offline":
00167 result.append( OfflineValidation( self, config ) )
00168 elif validationName == "offlineDQM":
00169 result.append( OfflineValidationDQM( self, config ) )
00170 elif validationName == "mcValidate":
00171 result.append( MonteCarloValidation( self, config ) )
00172 elif validationName == "split":
00173 result.append( TrackSplittingValidation( self, config ) )
00174 else:
00175 raise StandardError, "unknown validation mode '%s'"%validationName
00176 return result
00177
00178 class GenericValidation:
00179 defaultReferenceName = "DEFAULT"
00180
00181 def __init__(self, alignment, config):
00182 import random
00183 self.alignmentToValidate = alignment
00184 self.__general = readGeneral( config )
00185 self.randomWorkdirPart = "%0i"%random.randint(1,10e9)
00186 self.configFiles = []
00187 self.filesToCompare = {}
00188
00189
00190 def getRepMap(self, alignment = None):
00191 if alignment == None:
00192 alignment = self.alignmentToValidate
00193 result = alignment.getRepMap()
00194 result.update({
00195 "nEvents": str(self.__general["maxevents"]),
00196 "dataset": str(self.__general["dataset"]),
00197 "superPointingDataset": str(self.__general["superPointingDataset"]),
00198 "RelValSample": self.__general["relvalsample"],
00199 "TrackCollection": str(self.__general["trackcollection"]),
00200 "workdir": str(os.path.join(self.__general["workdir"],self.randomWorkdirPart)),
00201 "datadir": str(self.__general["datadir"]),
00202 "logdir": str(self.__general["logdir"]),
00203 "dbLoad": alignment.getLoadTemplate(),
00204 "CommandLineTemplate": """#run configfile and post-proccess it
00205 cmsRun %(cfgFile)s
00206 %(postProcess)s """,
00207 "GlobalTag": self.__general["globaltag"],
00208 "CMSSW_BASE": os.environ['CMSSW_BASE'],
00209 "alignmentName": alignment.name,
00210 "offlineModuleLevelHistsTransient": self.__general["offlineModuleLevelHistsTransient"]
00211 })
00212
00213
00214 return result
00215
00216 def getCompareStrings( self, requestId = None ):
00217 result = {}
00218 repMap = self.alignmentToValidate.getRepMap()
00219 for validationId in self.filesToCompare:
00220 repMap["file"] = self.filesToCompare[ validationId ]
00221 if repMap["file"].startswith( "/castor/" ):
00222 repMap["file"] = "rfio:%(file)s"%repMap
00223 result[ validationId ]= "%(file)s=%(name)s|%(color)s|%(style)s"%repMap
00224 if requestId == None:
00225 return result
00226 else:
00227 if not "." in requestId:
00228 requestId += ".%s"%GenericValidation.defaultReferenceName
00229 if not requestId.split(".")[-1] in result:
00230 raise StandardError, "could not find %s in reference Objects!"%requestId.split(".")[-1]
00231 return result[ requestId.split(".")[-1] ]
00232
00233 def createFiles( self, fileContents, path ):
00234 result = []
00235 for fileName in fileContents:
00236 filePath = os.path.join( path, fileName)
00237 theFile = open( filePath, "w" )
00238 theFile.write( fileContents[ fileName ] )
00239 theFile.close()
00240 result.append( filePath )
00241 return result
00242
00243 def createConfiguration(self, fileContents, path, schedule= None):
00244 self.configFiles = GenericValidation.createFiles( self, fileContents, path )
00245 if not schedule == None:
00246 schedule = [ os.path.join( path, cfgName) for cfgName in schedule]
00247 for cfgName in schedule:
00248 if not cfgName in self.configFiles:
00249 raise StandardError, "scheduled %s missing in generated configfiles: %s"% (cfgName, self.configFiles)
00250 for cfgName in self.configFiles:
00251 if not cfgName in schedule:
00252 raise StandardError, "generated configuration %s not scheduled: %s"% (cfgName, schedule)
00253 self.configFiles = schedule
00254 return self.configFiles
00255
00256 def createScript(self, fileContents, path, downloadFiles=[] ):
00257 self.scriptFiles = GenericValidation.createFiles( self, fileContents, path )
00258 for script in self.scriptFiles:
00259 os.chmod(script,0755)
00260 return self.scriptFiles
00261
00262
00263 class GeometryComparision(GenericValidation):
00264 """
00265 object representing a geometry comparison job
00266 alignemnt is the alignment to analyse
00267 config is the overall configuration
00268 copyImages indicates wether plot*.eps files should be copied back from the farm
00269 """
00270 def __init__(self, alignment, referenceAlignment, config, copyImages = True, randomWorkdirPart = None):
00271 GenericValidation.__init__(self, alignment, config)
00272 if not randomWorkdirPart == None:
00273 self.randomWorkdirPart = randomWorkdirPart
00274 self.referenceAlignment = referenceAlignment
00275 self.__compares = {}
00276 allCompares = readCompare(config)
00277 referenceName = "IDEAL"
00278 if not self.referenceAlignment == "IDEAL":
00279 referenceName = self.referenceAlignment.name
00280
00281
00282 for compareName in self.alignmentToValidate.compareTo[ referenceName ]:
00283 if compareName in allCompares:
00284 self.__compares[compareName] = allCompares[compareName]
00285 else:
00286 raise StandardError, "could not find compare section '%s' in '%s'"%(compareName, allCompares)
00287 self.copyImages = copyImages
00288
00289 def getRepMap(self, alignment = None):
00290 if alignment == None:
00291 alignment = self.alignmentToValidate
00292 repMap = GenericValidation.getRepMap( self, alignment )
00293 referenceName = "IDEAL"
00294 if not self.referenceAlignment == "IDEAL":
00295 referenceName = self.referenceAlignment.name
00296
00297 repMap.update({"comparedGeometry": ".oO[workdir]Oo./.oO[alignmentName]Oo.ROOTGeometry.root",
00298 "referenceGeometry": "IDEAL",
00299 "reference": referenceName,
00300 "APE": configTemplates.APETemplate
00301 })
00302 if not referenceName == "IDEAL":
00303 repMap["referenceGeometry"] = ".oO[workdir]Oo./.oO[reference]Oo.ROOTGeometry.root"
00304 repMap["name"] += "_vs_.oO[reference]Oo."
00305 return repMap
00306
00307 def createConfiguration(self, path ):
00308
00309 repMap = self.getRepMap()
00310 cfgs = {"TkAlCompareToNTuple.%s_cfg.py"%self.alignmentToValidate.name:
00311 replaceByMap( configTemplates.intoNTuplesTemplate, repMap)}
00312 if not self.referenceAlignment == "IDEAL":
00313 referenceRepMap = self.getRepMap( self.referenceAlignment )
00314 cfgFileName = "TkAlCompareToNTuple.%s.%s_cfg.py"%(self.referenceAlignment.name, self.randomWorkdirPart)
00315 cfgs[ cfgFileName ] = replaceByMap( configTemplates.intoNTuplesTemplate, referenceRepMap)
00316
00317 cfgSchedule = cfgs.keys()
00318 for common in self.__compares:
00319 repMap.update({"common": common,
00320 "levels": self.__compares[common][0],
00321 "dbOutput": self.__compares[common][1]
00322 })
00323 if self.__compares[common][1].split()[0] == "true":
00324 repMap["dbOutputService"] = configTemplates.dbOutputTemplate
00325 else:
00326 repMap["dbOutputService"] = ""
00327 cfgName = replaceByMap("TkAlCompareCommon.oO[common]Oo...oO[name]Oo._cfg.py",repMap)
00328 cfgs[ cfgName ] = replaceByMap(configTemplates.compareTemplate, repMap)
00329
00330 cfgSchedule.append( cfgName )
00331 GenericValidation.createConfiguration(self, cfgs, path, cfgSchedule)
00332
00333 def createScript(self, path):
00334 repMap = self.getRepMap()
00335 repMap["runComparisonScripts"] = ""
00336 scriptName = replaceByMap("TkAlGeomCompare..oO[name]Oo..sh",repMap)
00337 for name in self.__compares:
00338 if '"DetUnit"' in self.__compares[name][0].split(","):
00339 repMap["runComparisonScripts"] += "root -b -q 'comparisonScript.C(\".oO[workdir]Oo./.oO[name]Oo..Comparison_common"+name+".root\",\".oO[workdir]Oo./\")'\n"
00340 if self.copyImages:
00341 repMap["runComparisonScripts"] += "rfmkdir -p .oO[datadir]Oo./.oO[name]Oo..Comparison_common"+name+"_Images\n"
00342 repMap["runComparisonScripts"] += "find .oO[workdir]Oo. -maxdepth 1 -name \"plot*.eps\" -print | xargs -I {} bash -c \"rfcp {} .oO[datadir]Oo./.oO[name]Oo..Comparison_common"+name+"_Images/\" \n"
00343 repMap["runComparisonScripts"] += "rfmkdir -p .oO[workdir]Oo./.oO[name]Oo.."+name+"_ArrowPlots\n"
00344 repMap["runComparisonScripts"] += "root -b -q 'makeArrowPlots.C(\".oO[workdir]Oo./.oO[name]Oo..Comparison_common"+name+".root\",\".oO[workdir]Oo./.oO[name]Oo.."+name+"_ArrowPlots\")'\n"
00345 repMap["runComparisonScripts"] += "rfmkdir -p .oO[datadir]Oo./.oO[name]Oo..Comparison_common"+name+"_Images/ArrowPlots\n"
00346 repMap["runComparisonScripts"] += "find .oO[workdir]Oo./.oO[name]Oo.."+name+"_ArrowPlots -maxdepth 1 -name \"*.png\" -print | xargs -I {} bash -c \"rfcp {} .oO[datadir]Oo./.oO[name]Oo..Comparison_common"+name+"_Images/ArrowPlots\"\n"
00347
00348 resultingFile = replaceByMap(".oO[datadir]Oo./compared%s_.oO[name]Oo..root"%name,repMap)
00349 resultingFile = os.path.expandvars( resultingFile )
00350 resultingFile = os.path.abspath( resultingFile )
00351 repMap["runComparisonScripts"] += "rfcp .oO[workdir]Oo./OUTPUT_comparison.root %s\n"%resultingFile
00352 self.filesToCompare[ name ] = resultingFile
00353
00354 repMap["CommandLine"]=""
00355
00356 for cfg in self.configFiles:
00357
00358
00359 postProcess = "rfcp .oO[workdir]Oo./*.db .oO[datadir]Oo.\n"
00360 repMap["CommandLine"]+= repMap["CommandLineTemplate"]%{"cfgFile":cfg,
00361 "postProcess":postProcess
00362 }
00363 repMap["CommandLine"]+= """# overall postprocessing
00364 cd .oO[CMSSW_BASE]Oo./src/Alignment/OfflineValidation/scripts/
00365 .oO[runComparisonScripts]Oo.
00366 cd .oO[workdir]Oo.
00367 """
00368 scripts = {scriptName: replaceByMap( configTemplates.scriptTemplate, repMap ) }
00369 return GenericValidation.createScript(self, scripts, path)
00370
00371 class OfflineValidation(GenericValidation):
00372 def __init__(self, alignment,config):
00373 GenericValidation.__init__(self, alignment, config)
00374 general = readGeneral( config )
00375 self.__DMRMethod = general["DMRMethod"]
00376 self.__DMRMinimum = general["DMRMinimum"]
00377 self.__OfflineTreeBaseDir = general["OfflineTreeBaseDir"]
00378
00379 def createConfiguration(self, path, configBaseName = "TkAlOfflineValidation" ):
00380 cfgName = "%s.%s_cfg.py"%( configBaseName, self.alignmentToValidate.name )
00381 repMap = self.getRepMap()
00382
00383 cfgs = {cfgName:replaceByMap( configTemplates.offlineTemplate, repMap)}
00384 self.filesToCompare[ GenericValidation.defaultReferenceName ] = repMap["resultFile"]
00385 GenericValidation.createConfiguration(self, cfgs, path)
00386
00387 def createScript(self, path, scriptBaseName = "TkAlOfflineValidation"):
00388 scriptName = "%s.%s.sh"%(scriptBaseName, self.alignmentToValidate.name )
00389 repMap = GenericValidation.getRepMap(self)
00390 repMap["CommandLine"]=""
00391 for cfg in self.configFiles:
00392 repMap["CommandLine"]+= repMap["CommandLineTemplate"]%{"cfgFile":cfg,
00393 "postProcess":""
00394 }
00395 scripts = {scriptName: replaceByMap( configTemplates.scriptTemplate, repMap ) }
00396 return GenericValidation.createScript(self, scripts, path)
00397
00398 def getRepMap(self, alignment = None):
00399 repMap = GenericValidation.getRepMap(self, alignment)
00400 repMap.update({
00401 "OfflineTreeBaseDir": self.__OfflineTreeBaseDir,
00402 "DMRMethod":self.__DMRMethod,
00403 "DMRMinimum":self.__DMRMinimum,
00404 "APE": configTemplates.APETemplate,
00405 "outputFile": replaceByMap( ".oO[workdir]Oo./AlignmentValidation_.oO[name]Oo..root", repMap ),
00406 "resultFile": replaceByMap( ".oO[datadir]Oo./AlignmentValidation_.oO[name]Oo..root", repMap ),
00407 "TrackSelectionTemplate": configTemplates.TrackSelectionTemplate,
00408 "LorentzAngleTemplate": configTemplates.LorentzAngleTemplate,
00409 "offlineValidationMode": "Standalone",
00410 "offlineValidationFileOutput": configTemplates.offlineStandaloneFileOutputTemplate
00411 })
00412 repMap["outputFile"] = os.path.expandvars( repMap["outputFile"] )
00413 repMap["outputFile"] = os.path.abspath( repMap["outputFile"] )
00414 repMap["resultFile"] = os.path.expandvars( repMap["resultFile"] )
00415 repMap["resultFile"] = os.path.abspath( repMap["resultFile"] )
00416
00417 return repMap
00418
00419
00420 def appendToExtendedValidation( self, validationsSoFar = "" ):
00421 """
00422 if no argument or "" is passed a string with an instantiation is returned,
00423 else the validation is appended to the list
00424 """
00425 repMap = self.getRepMap()
00426 if validationsSoFar == "":
00427 validationsSoFar = 'PlotAlignmentValidation p("%(resultFile)s", "%(name)s", %(color)s, %(style)s);\n'%repMap
00428 else:
00429 validationsSoFar +='p.loadFileList("%(resultFile)s", "%(name)s", %(color)s, %(style)s);\n'%repMap
00430
00431
00432
00433 return validationsSoFar
00434
00435 class OfflineValidationDQM(OfflineValidation):
00436 def __init__(self, alignment, config):
00437 OfflineValidation.__init__(self, alignment, config)
00438 if not config.has_section("DQM"):
00439 raise StandardError, "You need to have a DQM section in your configfile!"
00440
00441 self.__PrimaryDataset = config.get("DQM", "primaryDataset")
00442 self.__firstRun = int(config.get("DQM", "firstRun"))
00443 self.__lastRun = int(config.get("DQM", "lastRun"))
00444
00445 def createConfiguration(self, path):
00446 OfflineValidation.createConfiguration(self, path, "TkAlOfflineValidationDQM")
00447
00448 def createScript(self, path):
00449 return OfflineValidation.createScript(self, path, "TkAlOfflineValidationDQM")
00450
00451 def getRepMap(self, alignment = None):
00452 repMap = OfflineValidation.getRepMap(self, alignment)
00453 repMap.update({
00454 "workdir": os.path.expandvars(repMap["workdir"]),
00455 "offlineValidationMode": "Dqm",
00456 "offlineValidationFileOutput": configTemplates.offlineDqmFileOutputTemplate,
00457 "workflow": "/%s/TkAl%s-.oO[alignmentName]Oo._R%09i_R%09i_ValSkim-v1/ALCARECO"%(self.__PrimaryDataset, datetime.datetime.now().strftime("%y"), self.__firstRun, self.__lastRun),
00458 "firstRunNumber": "%i"% self.__firstRun
00459 }
00460 )
00461 if "__" in repMap["workflow"]:
00462 raise StandardError, "the DQM workflow specefication must not contain '__'. it is: %s"%repMap["workflow"]
00463 return repMap
00464
00465 class MonteCarloValidation(GenericValidation):
00466 def __init__(self, alignment, config):
00467 GenericValidation.__init__(self, alignment, config)
00468
00469 def createConfiguration(self, path ):
00470 cfgName = "TkAlMcValidation.%s_cfg.py"%( self.alignmentToValidate.name )
00471 repMap = GenericValidation.getRepMap(self)
00472 repMap.update({
00473 "APE": configTemplates.APETemplate,
00474 "outputFile": replaceByMap( ".oO[workdir]Oo./McValidation_.oO[name]Oo..root", repMap )
00475 })
00476 repMap["outputFile"] = os.path.expandvars( repMap["outputFile"] )
00477 repMap["outputFile"] = os.path.abspath( repMap["outputFile"] )
00478 cfgs = {cfgName:replaceByMap( configTemplates.mcValidateTemplate, repMap)}
00479 self.filesToCompare[ GenericValidation.defaultReferenceName ] = repMap["outputFile"]
00480 GenericValidation.createConfiguration(self, cfgs, path)
00481
00482 def createScript(self, path):
00483 scriptName = "TkAlMcValidate.%s.sh"%( self.alignmentToValidate.name )
00484 repMap = GenericValidation.getRepMap(self)
00485 repMap["CommandLine"]=""
00486 for cfg in self.configFiles:
00487 repMap["CommandLine"]+= repMap["CommandLineTemplate"]%{"cfgFile":cfg,
00488 "postProcess":""
00489 }
00490
00491 scripts = {scriptName: replaceByMap( configTemplates.scriptTemplate, repMap ) }
00492 return GenericValidation.createScript(self, scripts, path)
00493
00494 class TrackSplittingValidation(GenericValidation):
00495 def __init__(self, alignment, config):
00496 GenericValidation.__init__(self, alignment, config)
00497
00498 def createConfiguration(self, path ):
00499 cfgName = "TkAlTrackSplitting.%s_cfg.py"%( self.alignmentToValidate.name )
00500 repMap = GenericValidation.getRepMap(self)
00501 repMap.update({
00502 "APE": configTemplates.APETemplate,
00503 "outputFile": replaceByMap( ".oO[workdir]Oo./TrackSplitting_.oO[name]Oo..root", repMap )
00504 })
00505 repMap["outputFile"] = os.path.expandvars( repMap["outputFile"] )
00506 repMap["outputFile"] = os.path.abspath( repMap["outputFile"] )
00507 cfgs = {cfgName:replaceByMap( configTemplates.TrackSplittingTemplate, repMap)}
00508 self.filesToCompare[ GenericValidation.defaultReferenceName ] = repMap["outputFile"]
00509 GenericValidation.createConfiguration(self, cfgs, path)
00510
00511 def createScript(self, path):
00512 scriptName = "TkAlTrackSplitting.%s.sh"%( self.alignmentToValidate.name )
00513 repMap = GenericValidation.getRepMap(self)
00514 repMap["CommandLine"]=""
00515 for cfg in self.configFiles:
00516 repMap["CommandLine"]+= repMap["CommandLineTemplate"]%{"cfgFile":cfg,
00517 "postProcess":""
00518 }
00519
00520 scripts = {scriptName: replaceByMap( configTemplates.scriptTemplate, repMap ) }
00521 return GenericValidation.createScript(self, scripts, path)
00522
00523
00524 def readAlignments( config ):
00525 result = []
00526 for section in config.sections():
00527 if "alignment:" in section:
00528 result.append( Alignment( section.split("alignment:")[1], config ) )
00529 return result
00530
00531 def readCompare( config ):
00532 result = {}
00533 for section in config.sections():
00534 if "compare:" in section:
00535 levels = config.get(section, "levels")
00536 dbOutput = config.get(section, "dbOutput")
00537 result[section.split(":")[1]] =(levels,dbOutput)
00538 return result
00539
00540 def readGeneral( config ):
00541 result = {
00542 "jobmode":"interactive",
00543 "superPointingDataset":"",
00544 "workdir":os.getcwd(),
00545 "datadir":os.getcwd(),
00546 "logdir":os.getcwd(),
00547 "offlineModuleLevelHistsTransient":"False",
00548 "OfflineTreeBaseDir":"TrackHitFilter",
00549 "DMRMethod":"medianX",
00550 "DMRMinimum":"30"
00551 }
00552 try:
00553 for option in config.options("general"):
00554 result[option] = config.get("general",option)
00555
00556 if "localGeneral" in config.sections():
00557 for option in result:
00558 if option in [item[0] for item in config.items("localGeneral")]:
00559 result[ option ] = config.get("localGeneral", option)
00560 except ConfigParser.NoSectionError, section:
00561 raise StandardError, "missing section '%s' in configuration files. This section is mandatory."%section
00562 return result
00563
00564 def runJob(jobName, script, config):
00565 general = readGeneral( config )
00566 log = "> Validating "+jobName
00567 print "> Validating "+jobName
00568 if general["jobmode"] == "interactive":
00569 log += getCommandOutput2( script )
00570 if general["jobmode"].split(",")[0] == "lxBatch":
00571 repMap = {
00572 "commands": general["jobmode"].split(",")[1],
00573 "logDir": general["logdir"],
00574 "jobName": jobName,
00575 "script": script,
00576 "bsub": "/afs/cern.ch/cms/caf/scripts/cmsbsub"
00577 }
00578
00579 log+=getCommandOutput2("%(bsub)s %(commands)s -J %(jobName)s -o %(logDir)s/%(jobName)s.stdout -e %(logDir)s/%(jobName)s.stderr %(script)s"%repMap)
00580 return log
00581
00582 def createExtendedValidationScript(offlineValidationList, outFilePath):
00583 repMap = offlineValidationList[0].getRepMap()
00584 repMap[ "extendedInstantiation" ] = ""
00585
00586 for validation in offlineValidationList:
00587 repMap[ "extendedInstantiation" ] = validation.appendToExtendedValidation( repMap[ "extendedInstantiation" ] )
00588
00589 theFile = open( outFilePath, "w" )
00590 theFile.write( replaceByMap( configTemplates.extendedVaidationTemplate ,repMap ) )
00591 theFile.close()
00592
00593 def createMergeScript( path, validations ):
00594 if( len(validations) == 0 ):
00595 raise StandardError, "cowardly refusing to merge nothing!"
00596
00597 repMap = validations[0].getRepMap()
00598 repMap.update({
00599 "DownloadData":"",
00600 "CompareAllignments":"",
00601 "RunExtendedOfflineValidation":""
00602 })
00603
00604 comparisonLists = {}
00605 for validation in validations:
00606 for referenceName in validation.filesToCompare:
00607 validationName = "%s.%s"%(validation.__class__.__name__, referenceName)
00608 validationName = validationName.split(".%s"%GenericValidation.defaultReferenceName )[0]
00609 if validationName in comparisonLists:
00610 comparisonLists[ validationName ].append( validation )
00611 else:
00612 comparisonLists[ validationName ] = [ validation ]
00613
00614 if "OfflineValidation" in comparisonLists:
00615 repMap["extendeValScriptPath"] = os.path.join(path, "TkAlExtendedOfflineValidation.C")
00616 createExtendedValidationScript( comparisonLists["OfflineValidation"], repMap["extendeValScriptPath"] )
00617 repMap["RunExtendedOfflineValidation"] = replaceByMap(configTemplates.extendedVaidationExecution, repMap)
00618
00619 repMap["CompareAllignments"] = "#run comparisons"
00620 for validationId in comparisonLists:
00621 compareStrings = [ val.getCompareStrings(validationId) for val in comparisonLists[validationId] ]
00622
00623 repMap.update({"validationId": validationId,
00624 "compareStrings": " , ".join(compareStrings) })
00625
00626 repMap["CompareAllignments"] += replaceByMap( configTemplates.compareAlignmentsExecution, repMap )
00627
00628 filePath = os.path.join(path, "TkAlMerge.sh")
00629 theFile = open( filePath, "w" )
00630 theFile.write( replaceByMap( configTemplates.mergeTemplate, repMap ) )
00631 theFile.close()
00632 os.chmod(filePath,0755)
00633
00634 return filePath
00635
00636 def loadTemplates( config ):
00637 if config.has_section("alternateTemplates"):
00638 for templateName in config.options("alternateTemplates"):
00639 newTemplateName = config.get("alternateTemplates", templateName )
00640
00641 configTemplates.alternateTemplate(templateName, newTemplateName)
00642
00643
00644 def main(argv = None):
00645 if argv == None:
00646 argv = sys.argv[1:]
00647 optParser = optparse.OptionParser()
00648 optParser.description = """ all-in-one alignment Validation
00649 This will run various validation procedures either on batch queues or interactviely.
00650
00651 If no name is given (-N parameter) a name containing time and date is created automatically
00652
00653 To merge the outcome of all validation procedures run TkAlMerge.sh in your validation's directory.
00654 """
00655 optParser.add_option("-n", "--dryRun", dest="dryRun", action="store_true", default=False,
00656 help="create all scripts and cfg File but do not start jobs (default=False)")
00657 optParser.add_option( "--getImages", dest="getImages", action="store_true", default=False,
00658 help="get all Images created during the process (default= False)")
00659 optParser.add_option("-c", "--config", dest="config",
00660 help="configuration to use (default compareConfig.ini) this can be a comma-seperated list of all .ini file you want to merge", metavar="CONFIG")
00661 optParser.add_option("-N", "--Name", dest="Name",
00662 help="Name of this validation (default: alignmentValidation_DATE_TIME)", metavar="NAME")
00663 optParser.add_option("-r", "--restrictTo", dest="restrictTo",
00664 help="restrict validations to given modes (comma seperated) (default: no restriction)", metavar="RESTRICTTO")
00665
00666 (options, args) = optParser.parse_args(argv)
00667
00668 if not options.restrictTo == None:
00669 options.restrictTo = options.restrictTo.split(",")
00670 if options.config == None:
00671 options.config = "compareConfig.ini"
00672 else:
00673 options.config = options.config.split(",")
00674 result = []
00675 for iniFile in options.config:
00676 result.append( os.path.abspath(iniFile) )
00677 options.config = result
00678 config = BetterConfigParser()
00679 config.read( options.config )
00680
00681 if options.Name == None:
00682 options.Name = "alignmentValidation_%s"%(datetime.datetime.now().strftime("%y%m%d_%H%M%S"))
00683
00684 outPath = os.path.abspath( options.Name )
00685 general = readGeneral( config )
00686 config.set("general","workdir",os.path.join(general["workdir"],options.Name) )
00687 config.set("general","datadir",os.path.join(general["datadir"],options.Name) )
00688 config.set("general","logdir",os.path.join(general["logdir"],options.Name) )
00689 if not os.path.exists( outPath ):
00690 os.makedirs( outPath )
00691 elif not os.path.isdir( outPath ):
00692 raise StandardError,"the file %s is in the way rename the Job or move it away"%outPath
00693
00694
00695 loadTemplates( config )
00696
00697 log = ""
00698 alignments = readAlignments( config )
00699 validations = []
00700 for alignment in alignments:
00701 alignment.restrictTo( options.restrictTo )
00702 validations.extend( alignment.createValidations( config, options, alignments ) )
00703
00704 scripts = []
00705 for validation in validations:
00706 validation.createConfiguration( outPath )
00707 scripts.extend( validation.createScript( outPath ) )
00708
00709 createMergeScript( outPath, validations )
00710
00711
00712 backupConfigFile = open( os.path.join( outPath, "usedConfiguration.ini" ) , "w" )
00713 config.write( backupConfigFile )
00714
00715 for script in scripts:
00716 name = os.path.splitext( os.path.basename( script ) )[0]
00717 if options.dryRun:
00718 print "%s would run: %s"%( name, script)
00719 else:
00720 runJob( name, script, config)
00721
00722 if __name__ == "__main__":
00723
00724 main()
00725