00001
00002
00003 import os
00004 import sys
00005 import ConfigParser
00006 import optparse
00007 import datetime
00008 from pprint import pprint
00009 import shutil
00010
00011 import configTemplates
00012
00013
00014
00015 def replaceByMap(target, map):
00016 result = target
00017 for id in map:
00018
00019 lifeSaver = 10e3
00020 iteration = 0
00021 while ".oO[" in result and "]Oo." in result:
00022 for id in map:
00023 result = result.replace(".oO["+id+"]Oo.",map[id])
00024 iteration += 1
00025 if iteration > lifeSaver:
00026 problematicLines = ""
00027 print map.keys()
00028 for line in result.splitlines():
00029 if ".oO[" in result and "]Oo." in line:
00030 problematicLines += "%s\n"%line
00031 raise StandardError, "Oh Dear, there seems to be an endless loop in replaceByMap!!\n%s\nrepMap"%problematicLines
00032 return result
00033
00034
00035 def getCommandOutput2(command):
00036 child = os.popen(command)
00037 data = child.read()
00038 err = child.close()
00039 if err:
00040 raise RuntimeError, '%s failed w/ exit code %d' % (command, err)
00041 return data
00042
00043
00044 def castorDirExists(path):
00045 if path[-1] == "/":
00046 path = path[:-1]
00047 containingPath = os.path.join( *path.split("/")[:-1] )
00048 dirInQuestion = path.split("/")[-1]
00049 try:
00050 rawLines =getCommandOutput2("rfdir /"+containingPath).splitlines()
00051 except RuntimeError:
00052 return False
00053 for line in rawLines:
00054 if line.split()[0][0] == "d":
00055 if line.split()[8] == dirInQuestion:
00056 return True
00057 return False
00058
00059
00060 class BetterConfigParser(ConfigParser.ConfigParser):
00061 def optionxform(self, optionstr):
00062 return optionstr
00063
00064 def exists( self, section, option):
00065 try:
00066 items = self.items(section)
00067 except ConfigParser.NoSectionError:
00068 return False
00069 for item in items:
00070 if item[0] == option:
00071 return True
00072 return False
00073
00074 def __updateDict( self, dictionary, section ):
00075 result = dictionary
00076 try:
00077 for option in self.options( section ):
00078 result[option] = self.get( section, option )
00079 if "local"+section.title() in self.sections():
00080 for option in self.options( "local"+section.title() ):
00081 result[option] = self.get( "local"+section.title(),
00082 option )
00083 except ConfigParser.NoSectionError, section:
00084 raise StandardError, ("%s in configuration files. This section is "
00085 "mandatory."
00086 %( str( section ).replace( ":", "", 1 ) ) )
00087 return result
00088
00089 def getResultingSection( self, section, defaultDict = {}, demandPars = [] ):
00090 result = defaultDict
00091 for option in demandPars:
00092 try:
00093 result[option] = self.get( section, option )
00094 except ConfigParser.NoOptionError, globalSectionError:
00095 globalSection = str( globalSectionError ).split( "'" )[-2]
00096 splittedSectionName = section.split( ":" )
00097 if len( splittedSectionName ) > 1:
00098 localSection = ("local"+section.split( ":" )[0].title()+":"
00099 +section.split(":")[1])
00100 else:
00101 localSection = ("local"+section.split( ":" )[0].title())
00102 if self.has_section( localSection ):
00103 try:
00104 result[option] = self.get( localSection, option )
00105 except ConfigParser.NoOptionError, option:
00106 raise StandardError, ("%s. This option is mandatory."
00107 %( str( option )\
00108 .replace( ":", "", 1 )\
00109 .replace( "section", "section '"\
00110 +globalSection+"' or", 1 )
00111 )
00112 )
00113 else:
00114 raise StandardError, ("%s. This option is mandatory."
00115 %( str( globalSectionError )\
00116 .replace( ":", "", 1 )
00117 )
00118 )
00119 result = self.__updateDict( result, section )
00120 return result
00121
00122 def getAlignments( self ):
00123 alignments = []
00124 for section in self.sections():
00125 if "alignment:" in section:
00126 alignments.append( Alignment( section.split( "alignment:" )[1],
00127 self ) )
00128 return alignments
00129
00130 def getCompares( self ):
00131 compares = {}
00132 for section in self.sections():
00133 if "compare:" in section:
00134 levels = self.get( section, "levels" )
00135 dbOutput = self.get( section, "dbOutput" )
00136 compares[section.split(":")[1]] = ( levels, dbOutput )
00137 return compares
00138
00139 def getGeneral( self ):
00140 defaults = {
00141 "jobmode":"interactive",
00142 "workdir":os.getcwd(),
00143 "datadir":os.getcwd(),
00144 "logdir":os.getcwd()
00145 }
00146 general = self.getResultingSection( "general", defaultDict = defaults )
00147 return general
00148
00149
00150 class Alignment:
00151 def __init__(self, name, config, runGeomComp = "1"):
00152 section = "alignment:%s"%name
00153 if not config.has_section( section ):
00154 raise StandardError, ("section %s not found. Please define the "
00155 "alignment!"%section)
00156
00157
00158 knownSimpleParameters = [ 'globaltag', 'style', 'color' ]
00159 knownKeywords = [ 'condition' ]
00160 for option in config.options( section ):
00161 if option in knownSimpleParameters:
00162 continue
00163 elif option.split()[0] in knownKeywords:
00164 continue
00165 else:
00166 raise StandardError, ("Invalid or unknown parameter '%s' in "
00167 "section '%s'!")%( option, section )
00168
00169 self.name = name
00170 self.runGeomComp = runGeomComp
00171 self.globaltag = config.get( section, "globaltag" )
00172 self.conditions = self.__getConditions( config, section )
00173 self.color = config.get(section,"color")
00174 self.style = config.get(section,"style")
00175
00176
00177
00178
00179 self.dbpath = ""
00180 self.tag = ""
00181 self.errordbpath = "frontier://FrontierProd/CMS_COND_31X_FROM21X"
00182 self.errortag = "TrackerIdealGeometryErrors210_mc"
00183 self.kinksAndBows = ""
00184 self.kbdbpath = ""
00185 self.kbtag = ""
00186
00187 def __getConditions( self, theConfig, theSection ):
00188 conditions = []
00189 for option in theConfig.options( theSection ):
00190 if option.startswith( "condition " ):
00191 rcdName = option.split( "condition " )[1]
00192 condParameters = theConfig.get( theSection, option ).split( "," )
00193 if len( condParameters ) < 2:
00194 raise StandardError, ("'%s' is used with too few arguments."
00195 "A connect_string and a tag are "
00196 "required!"%option)
00197 if len( condParameters ) < 3:
00198 condParameters.append( "" )
00199 conditions.append({"rcdName": rcdName.strip(),
00200 "connectString": condParameters[0].strip(),
00201 "tagName": condParameters[1].strip(),
00202 "labelName": condParameters[2].strip()})
00203 return conditions
00204
00205 def __testDbExist(self, dbpath):
00206
00207 return
00208 if not dbpath.startswith("sqlite_file:"):
00209 print "WARNING: could not check existence for",dbpath
00210 else:
00211 if not os.path.exists( dbpath.split("sqlite_file:")[1] ):
00212 raise "could not find file: '%s'"%dbpath.split("sqlite_file:")[1]
00213
00214 def restrictTo( self, restriction ):
00215 result = []
00216 if not restriction == None:
00217 for mode in self.mode:
00218 if mode in restriction:
00219 result.append( mode )
00220 self.mode = result
00221
00222 def getRepMap( self ):
00223 result = {
00224 "name": self.name,
00225 "dbpath": self.dbpath,
00226 "errordbpath": self.errordbpath,
00227 "tag": self.tag,
00228 "errortag": self.errortag,
00229 "color": self.color,
00230 "style": self.style,
00231 "runGeomComp": self.runGeomComp,
00232 "kinksAndBows": self.kinksAndBows,
00233 "kbdbpath": self.kbdbpath,
00234 "kbtag": self.kbtag,
00235 "GlobalTag": self.globaltag
00236 }
00237 return result
00238
00239 def getLoadTemplate(self):
00240 """This function still exists only for historical reasons.
00241 Will be removed, when the templates are adjusted.
00242 """
00243 return ""
00244
00245 def getAPETemplate(self):
00246 """This function still exists only for historical reasons.
00247 Will be removed, when the templates are adjusted.
00248 """
00249 return ""
00250
00251 def getConditions(self):
00252 """This function creates the configuration snippet to override
00253 global tag conditions.
00254 """
00255 if len( self.conditions ):
00256 loadCond = ("\nimport CalibTracker.Configuration."
00257 "Common.PoolDBESSource_cfi\n")
00258 for cond in self.conditions:
00259 if not cond["labelName"] == "":
00260 temp = configTemplates.conditionsTemplate.replace(
00261 "tag = cms.string('.oO[tagName]Oo.')",
00262 ("tag = cms.string('.oO[tagName]Oo.'),"
00263 "\nlabel = cms.untracked.string('.oO[labelName]Oo.')"))
00264 else:
00265 temp = configTemplates.conditionsTemplate
00266 loadCond += replaceByMap( temp, cond )
00267 else:
00268 loadCond = ""
00269 return loadCond
00270
00271
00272 class GenericValidation:
00273 defaultReferenceName = "DEFAULT"
00274 def __init__(self, valName, alignment, config):
00275 import random
00276 self.name = valName
00277 self.alignmentToValidate = alignment
00278 self.general = config.getGeneral()
00279 self.randomWorkdirPart = "%0i"%random.randint(1,10e9)
00280 self.configFiles = []
00281 self.filesToCompare = {}
00282 self.jobmode = self.general["jobmode"]
00283
00284 def getRepMap(self, alignment = None):
00285 if alignment == None:
00286 alignment = self.alignmentToValidate
00287 result = alignment.getRepMap()
00288 result.update( self.general )
00289 result.update({
00290 "workdir": os.path.join( self.general["workdir"],
00291 self.randomWorkdirPart ),
00292 "datadir": self.general["datadir"],
00293 "logdir": self.general["logdir"],
00294 "dbLoad": alignment.getLoadTemplate(),
00295 "APE": alignment.getAPETemplate(),
00296 "CommandLineTemplate": ("#run configfile and post-proccess it\n"
00297 "cmsRun %(cfgFile)s\n"
00298 "%(postProcess)s "),
00299 "CMSSW_BASE": os.environ['CMSSW_BASE'],
00300 "SCRAM_ARCH": os.environ['SCRAM_ARCH'],
00301 "alignmentName": alignment.name,
00302 "condLoad": alignment.getConditions()
00303 })
00304 return result
00305
00306 def getCompareStrings( self, requestId = None ):
00307 result = {}
00308 repMap = self.alignmentToValidate.getRepMap()
00309 for validationId in self.filesToCompare:
00310 repMap["file"] = self.filesToCompare[ validationId ]
00311 if repMap["file"].startswith( "/castor/" ):
00312 repMap["file"] = "rfio:%(file)s"%repMap
00313 result[ validationId ]= "%(file)s=%(name)s|%(color)s|%(style)s"%repMap
00314 if requestId == None:
00315 return result
00316 else:
00317 if not "." in requestId:
00318 requestId += ".%s"%GenericValidation.defaultReferenceName
00319 if not requestId.split(".")[-1] in result:
00320 raise StandardError, "could not find %s in reference Objects!"%requestId.split(".")[-1]
00321 return result[ requestId.split(".")[-1] ]
00322
00323 def createFiles( self, fileContents, path ):
00324 result = []
00325 for fileName in fileContents:
00326 filePath = os.path.join( path, fileName)
00327 theFile = open( filePath, "w" )
00328 theFile.write( fileContents[ fileName ] )
00329 theFile.close()
00330 result.append( filePath )
00331 return result
00332
00333 def createConfiguration(self, fileContents, path, schedule= None):
00334 self.configFiles = GenericValidation.createFiles( self, fileContents, path )
00335 if not schedule == None:
00336 schedule = [ os.path.join( path, cfgName) for cfgName in schedule]
00337 for cfgName in schedule:
00338 if not cfgName in self.configFiles:
00339 raise StandardError, "scheduled %s missing in generated configfiles: %s"% (cfgName, self.configFiles)
00340 for cfgName in self.configFiles:
00341 if not cfgName in schedule:
00342 raise StandardError, "generated configuration %s not scheduled: %s"% (cfgName, schedule)
00343 self.configFiles = schedule
00344 return self.configFiles
00345
00346 def createScript(self, fileContents, path, downloadFiles=[] ):
00347 self.scriptFiles = GenericValidation.createFiles( self, fileContents, path )
00348 for script in self.scriptFiles:
00349 os.chmod(script,0755)
00350 return self.scriptFiles
00351
00352 def createCrabCfg(self, fileContents, path ):
00353 self.crabConfigurationFiles = GenericValidation.createFiles( self, fileContents, path )
00354 return self.crabConfigurationFiles
00355
00356
00357 class GeometryComparison(GenericValidation):
00358 """
00359 object representing a geometry comparison job
00360 alignemnt is the alignment to analyse
00361 config is the overall configuration
00362 copyImages indicates wether plot*.eps files should be copied back from the farm
00363 """
00364 def __init__( self, valName, alignment, referenceAlignment,
00365 config, copyImages = True, randomWorkdirPart = None):
00366 GenericValidation.__init__(self, valName, alignment, config)
00367 if not randomWorkdirPart == None:
00368 self.randomWorkdirPart = randomWorkdirPart
00369 self.referenceAlignment = referenceAlignment
00370 try:
00371 self.jobmode = config.get( "compare:"+self.name, "jobmode" )
00372 except ConfigParser.NoOptionError:
00373 pass
00374 referenceName = "IDEAL"
00375 if not self.referenceAlignment == "IDEAL":
00376 referenceName = self.referenceAlignment.name
00377
00378 allCompares = config.getCompares()
00379 self.__compares = {}
00380 if valName in allCompares:
00381 self.__compares[valName] = allCompares[valName]
00382 else:
00383 raise StandardError, "Could not find compare section '%s' in '%s'"%(valName, allCompares)
00384 self.copyImages = copyImages
00385
00386 def getRepMap(self, alignment = None):
00387 if alignment == None:
00388 alignment = self.alignmentToValidate
00389 repMap = GenericValidation.getRepMap( self, alignment )
00390 referenceName = "IDEAL"
00391 if not self.referenceAlignment == "IDEAL":
00392 referenceName = self.referenceAlignment.name
00393
00394 repMap.update({
00395 "comparedGeometry": (".oO[workdir]Oo./.oO[alignmentName]Oo."
00396 "ROOTGeometry.root"),
00397 "referenceGeometry": "IDEAL",
00398
00399 "reference": referenceName
00400 })
00401 if not referenceName == "IDEAL":
00402 repMap["referenceGeometry"] = (".oO[workdir]Oo./.oO[reference]Oo."
00403 "ROOTGeometry.root")
00404 repMap["name"] += "_vs_.oO[reference]Oo."
00405 return repMap
00406
00407 def createConfiguration(self, path ):
00408
00409 repMap = self.getRepMap()
00410 cfgs = { "TkAlCompareToNTuple.%s.%s_cfg.py"%(
00411 self.alignmentToValidate.name, self.randomWorkdirPart ):
00412 replaceByMap( configTemplates.intoNTuplesTemplate, repMap)}
00413 if not self.referenceAlignment == "IDEAL":
00414 referenceRepMap = self.getRepMap( self.referenceAlignment )
00415 cfgFileName = "TkAlCompareToNTuple.%s.%s_cfg.py"%(
00416 self.referenceAlignment.name, self.randomWorkdirPart )
00417 cfgs[ cfgFileName ] = replaceByMap( configTemplates.intoNTuplesTemplate, referenceRepMap)
00418
00419 cfgSchedule = cfgs.keys()
00420 for common in self.__compares:
00421 repMap.update({"common": common,
00422 "levels": self.__compares[common][0],
00423 "dbOutput": self.__compares[common][1]
00424 })
00425 if self.__compares[common][1].split()[0] == "true":
00426 repMap["dbOutputService"] = configTemplates.dbOutputTemplate
00427 else:
00428 repMap["dbOutputService"] = ""
00429 cfgName = replaceByMap("TkAlCompareCommon.oO[common]Oo...oO[name]Oo._cfg.py",repMap)
00430 cfgs[ cfgName ] = replaceByMap(configTemplates.compareTemplate, repMap)
00431
00432 cfgSchedule.append( cfgName )
00433 GenericValidation.createConfiguration(self, cfgs, path, cfgSchedule)
00434
00435 def createScript(self, path):
00436 repMap = self.getRepMap()
00437 repMap["runComparisonScripts"] = ""
00438 scriptName = replaceByMap( "TkAlGeomCompare.%s..oO[name]Oo..sh"%( self.name ),
00439 repMap)
00440 for name in self.__compares:
00441 if '"DetUnit"' in self.__compares[name][0].split(","):
00442 repMap["runComparisonScripts"] += "root -b -q 'comparisonScript.C(\".oO[workdir]Oo./.oO[name]Oo..Comparison_common"+name+".root\",\".oO[workdir]Oo./\")'\n"
00443 if self.copyImages:
00444 repMap["runComparisonScripts"] += "rfmkdir -p .oO[datadir]Oo./.oO[name]Oo..Comparison_common"+name+"_Images\n"
00445 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"
00446 repMap["runComparisonScripts"] += "find .oO[workdir]Oo. -maxdepth 1 -name \"plot*.pdf\" -print | xargs -I {} bash -c \"rfcp {} .oO[datadir]Oo./.oO[name]Oo..Comparison_common"+name+"_Images/\" \n"
00447 repMap["runComparisonScripts"] += "rfmkdir -p .oO[workdir]Oo./.oO[name]Oo.."+name+"_ArrowPlots\n"
00448 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"
00449 repMap["runComparisonScripts"] += "rfmkdir -p .oO[datadir]Oo./.oO[name]Oo..Comparison_common"+name+"_Images/ArrowPlots\n"
00450 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"
00451
00452 resultingFile = replaceByMap(".oO[datadir]Oo./compared%s_.oO[name]Oo..root"%name,repMap)
00453 resultingFile = os.path.expandvars( resultingFile )
00454 resultingFile = os.path.abspath( resultingFile )
00455 repMap["runComparisonScripts"] += "rfcp .oO[workdir]Oo./OUTPUT_comparison.root %s\n"%resultingFile
00456 self.filesToCompare[ name ] = resultingFile
00457
00458 repMap["CommandLine"]=""
00459
00460 for cfg in self.configFiles:
00461 postProcess = "rfcp .oO[workdir]Oo./*.db .oO[datadir]Oo.\n"
00462 repMap["CommandLine"]+= repMap["CommandLineTemplate"]%{"cfgFile":cfg,
00463 "postProcess":postProcess
00464 }
00465 repMap["CommandLine"]+= """# overall postprocessing
00466 cd .oO[CMSSW_BASE]Oo./src/Alignment/OfflineValidation/scripts/
00467 .oO[runComparisonScripts]Oo.
00468 cd .oO[workdir]Oo.
00469 """
00470 scripts = {scriptName: replaceByMap( configTemplates.scriptTemplate, repMap ) }
00471 return GenericValidation.createScript(self, scripts, path)
00472
00473 def createCrabCfg( self ):
00474 raise StandardError, ("Parallelization not supported for geometry "
00475 "comparison. Please choose another 'jobmode'.")
00476
00477
00478 class OfflineValidation(GenericValidation):
00479 def __init__(self, valName, alignment,config):
00480 GenericValidation.__init__(self, valName, alignment, config)
00481 defaults = {
00482 "DMRMethod":"median",
00483 "DMRMinimum":"30",
00484 "DMROptions":"",
00485 "offlineModuleLevelHistsTransient":"False",
00486 "offlineModuleLevelProfiles":"False",
00487 "OfflineTreeBaseDir":"TrackHitFilter",
00488 "SurfaceShapes":"none",
00489 "jobmode":self.jobmode,
00490 "runRange":"",
00491 "JSON":""
00492 }
00493 mandatories = [ "dataset", "maxevents", "trackcollection" ]
00494 if not config.has_section( "offline:"+self.name ):
00495 offline = config.getResultingSection( "general",
00496 defaultDict = defaults,
00497 demandPars = mandatories )
00498 else:
00499 offline = config.getResultingSection( "offline:"+self.name,
00500 defaultDict = defaults,
00501 demandPars = mandatories )
00502 self.general.update( offline )
00503 self.jobmode = self.general["jobmode"]
00504
00505 def createConfiguration(self, path,
00506 configBaseName = "TkAlOfflineValidation" ):
00507 cfgName = "%s.%s.%s_cfg.py"%( configBaseName, self.name,
00508 self.alignmentToValidate.name )
00509 repMap = self.getRepMap()
00510
00511 cfgs = {cfgName:replaceByMap( configTemplates.offlineTemplate, repMap)}
00512 self.filesToCompare[
00513 GenericValidation.defaultReferenceName ] = repMap["resultFile"]
00514 GenericValidation.createConfiguration(self, cfgs, path)
00515
00516 def createScript(self, path, scriptBaseName = "TkAlOfflineValidation"):
00517 scriptName = "%s.%s.%s.sh"%( scriptBaseName, self.name,
00518 self.alignmentToValidate.name )
00519 repMap = GenericValidation.getRepMap(self)
00520 repMap["CommandLine"]=""
00521 for cfg in self.configFiles:
00522 repMap["CommandLine"]+= repMap["CommandLineTemplate"]%{"cfgFile":cfg,
00523 "postProcess":""
00524 }
00525 scripts = {scriptName: replaceByMap( configTemplates.scriptTemplate,
00526 repMap ) }
00527 return GenericValidation.createScript(self, scripts, path)
00528
00529 def createCrabCfg( self, path,
00530 crabCfgBaseName = "TkAlOfflineValidation" ):
00531 crabCfgName = "crab.%s.%s.%s.cfg"%( crabCfgBaseName, self.name,
00532 self.alignmentToValidate.name )
00533 repMap = self.getRepMap()
00534 repMap["script"] = "dummy_script.sh"
00535 repMap["crabOutputDir"] = os.path.basename( path )
00536 repMap["crabWorkingDir"] = crabCfgName.split( '.cfg' )[0]
00537 self.crabWorkingDir = repMap["crabWorkingDir"]
00538 repMap["numberOfJobs"] = self.general["parallelJobs"]
00539 repMap["cfgFile"] = self.configFiles[0]
00540 repMap["queue"] = self.jobmode.split( ',' )[1].split( '-q' )[1]
00541 crabCfg = {crabCfgName: replaceByMap( configTemplates.crabCfgTemplate,
00542 repMap ) }
00543 return GenericValidation.createCrabCfg( self, crabCfg, path )
00544
00545 def getRepMap(self, alignment = None):
00546 repMap = GenericValidation.getRepMap(self, alignment)
00547 repMap.update({
00548 "nEvents": self.general["maxevents"],
00549 "outputFile": replaceByMap( (".oO[workdir]Oo./AlignmentValidation_"
00550 + self.name +
00551 "_.oO[name]Oo..root"), repMap ),
00552 "resultFile": replaceByMap( (".oO[datadir]Oo./AlignmentValidation_"
00553 + self.name +
00554 "_.oO[name]Oo..root"), repMap ),
00555 "TrackSelectionTemplate": configTemplates.TrackSelectionTemplate,
00556 "LorentzAngleTemplate": configTemplates.LorentzAngleTemplate,
00557 "offlineValidationMode": "Standalone",
00558 "offlineValidationFileOutput":
00559 configTemplates.offlineStandaloneFileOutputTemplate,
00560
00561 "TrackCollection": self.general["trackcollection"]
00562 })
00563 repMap["outputFile"] = os.path.expandvars( repMap["outputFile"] )
00564 repMap["outputFile"] = os.path.abspath( repMap["outputFile"] )
00565 repMap["resultFile"] = os.path.expandvars( repMap["resultFile"] )
00566 repMap["resultFile"] = os.path.abspath( repMap["resultFile"] )
00567 if self.jobmode.split( ',' )[0] == "crab":
00568 repMap["outputFile"] = os.path.basename( repMap["outputFile"] )
00569 repMap["resultFile"] = os.path.basename( repMap["resultFile"] )
00570
00571 return repMap
00572
00573 def appendToExtendedValidation( self, validationsSoFar = "" ):
00574 """
00575 if no argument or "" is passed a string with an instantiation is
00576 returned, else the validation is appended to the list
00577 """
00578 repMap = self.getRepMap()
00579 if validationsSoFar == "":
00580 validationsSoFar = ('PlotAlignmentValidation p("%(resultFile)s",'
00581 '"%(name)s", %(color)s, %(style)s);\n')%repMap
00582 else:
00583 validationsSoFar += ('p.loadFileList("%(resultFile)s", "%(name)s",'
00584 '%(color)s, %(style)s);\n')%repMap
00585 return validationsSoFar
00586
00587 def appendToMerge( self, mergesSoFar = "" ):
00588 """
00589 append all merges here
00590 """
00591 repMap = self.getRepMap()
00592 mergesSoFar += replaceByMap( configTemplates.mergeOfflineParallelResults, repMap )
00593 return mergesSoFar
00594
00595 class OfflineValidationParallel(OfflineValidation):
00596 def __init__(self, valName, alignment,config):
00597 OfflineValidation.__init__(self, valName, alignment, config)
00598 defaults = {
00599 "parallelJobs":"1",
00600 "jobmode":self.jobmode
00601 }
00602 if not config.has_section( "offline:"+self.name ):
00603 offline = config.getResultingSection( "general",
00604 defaultDict = defaults )
00605 else:
00606 offline = config.getResultingSection( "offline:"+self.name,
00607 defaultDict = defaults )
00608 self.general.update( offline )
00609 self.__NJobs = self.general["parallelJobs"]
00610
00611 def createConfiguration(self, path, configBaseName = "TkAlOfflineValidation" ):
00612
00613 numberParallelJobs = int( self.general["parallelJobs"] )
00614
00615
00616 maximumNumberJobs = 40
00617 if numberParallelJobs > maximumNumberJobs:
00618 raise StandardError, "Maximum allowed number of parallel jobs "+str(maximumNumberJobs)+" exceeded!!!"
00619
00620
00621 if int( self.general["maxevents"] ) == -1:
00622 raise StandardError, "Maximum number of events (maxevents) not specified: cannot use parallel jobs in offline validation"
00623 if numberParallelJobs > 1:
00624 if self.general["offlineModuleLevelHistsTransient"] == "True":
00625 raise StandardError, "To be able to merge results when running parallel jobs, set offlineModuleLevelHistsTransient to false."
00626 for index in range(numberParallelJobs):
00627 cfgName = "%s.%s.%s_%s_cfg.py"%( configBaseName, self.name, self.alignmentToValidate.name, str(index) )
00628 repMap = self.getRepMap()
00629
00630
00631
00632 repMap.update({"nIndex": str(index)})
00633
00634
00635 repMap.update({
00636 "outputFile": replaceByMap( ".oO[datadir]Oo./AlignmentValidation_"
00637 + self.name +
00638 "_.oO[name]Oo._.oO[nIndex]Oo..root", repMap )
00639 })
00640 repMap["outputFile"] = os.path.expandvars( repMap["outputFile"] )
00641 repMap["outputFile"] = os.path.abspath( repMap["outputFile"] )
00642
00643 cfgs = {cfgName:replaceByMap( configTemplates.offlineParallelTemplate, repMap)}
00644 self.filesToCompare[ GenericValidation.defaultReferenceName ] = repMap["resultFile"]
00645 GenericValidation.createConfiguration(self, cfgs, path)
00646
00647
00648
00649 def createScript(self, path, scriptBaseName = "TkAlOfflineValidation"):
00650
00651
00652 returnValue = []
00653 numJobs = int( self.general["parallelJobs"] )
00654 for index in range(numJobs):
00655 scriptName = "%s.%s.%s_%s.sh"%(scriptBaseName, self.name, self.alignmentToValidate.name, str(index) )
00656 repMap = GenericValidation.getRepMap(self)
00657 repMap["nIndex"]=""
00658 repMap["nIndex"]=str(index)
00659 repMap["CommandLine"]=""
00660 for cfg in self.configFiles:
00661
00662 cfgtemp = cfg.replace( str(numJobs-1)+"_cfg.py" , str(index)+"_cfg.py" )
00663 repMap["CommandLine"]+= repMap["CommandLineTemplate"]%{"cfgFile":cfgtemp,
00664 "postProcess":""
00665 }
00666 scripts = {scriptName: replaceByMap( configTemplates.parallelScriptTemplate, repMap ) }
00667 returnValue.extend( GenericValidation.createScript(self, scripts, path) )
00668 return returnValue
00669
00670 def getRepMap(self, alignment = None):
00671 repMap = OfflineValidation.getRepMap(self, alignment)
00672 repMap.update({
00673 "nJobs": self.general["parallelJobs"],
00674 "offlineValidationFileOutput":
00675 configTemplates.offlineParallelFileOutputTemplate,
00676 "nameValidation": self.name
00677 })
00678
00679
00680
00681 if str(self.general["maxevents"]) == "-1":
00682 repMap.update({ "nJobs": "1" })
00683 return repMap
00684
00685 def appendToMergeParJobs( self, validationsSoFar = "" ):
00686 """
00687 if no argument or "" is passed a string with an instantiation is returned,
00688 else the validation is appended to the list
00689 """
00690 repMap = self.getRepMap()
00691
00692 parameters = ""
00693 fileToAdd = ""
00694 for index in range(int(self.__NJobs)):
00695 fileToAdd = '%(resultFile)s'%repMap
00696 fileToAdd = fileToAdd.replace('.root','_'+str(index)+'.root')
00697 if index < int( self.general["parallelJobs"] )-1:
00698 parameters = parameters+fileToAdd+','
00699 else:
00700 parameters = parameters+fileToAdd
00701
00702 mergedoutputfile = "AlignmentValidation_" + self.name + "_" + '%(name)s'%repMap + ".root"
00703 validationsSoFar += 'hadd("'+parameters+'","'+mergedoutputfile+'");' + "\n"
00704 return validationsSoFar
00705
00706 def createCrabCfg( self ):
00707 raise StandardError, ("jobmode 'crab' not supported for "
00708 "'offlineParallel' validation. "
00709 "Please choose another 'jobmode'.")
00710
00711
00712 class OfflineValidationDQM(OfflineValidation):
00713 def __init__(self, valName, alignment, config):
00714 OfflineValidation.__init__(self, valName, alignment, config)
00715 if not config.has_section("DQM"):
00716 raise StandardError, "You need to have a DQM section in your configfile!"
00717
00718 self.__PrimaryDataset = config.get("DQM", "primaryDataset")
00719 self.__firstRun = int(config.get("DQM", "firstRun"))
00720 self.__lastRun = int(config.get("DQM", "lastRun"))
00721
00722 def createConfiguration(self, path):
00723 OfflineValidation.createConfiguration(self, path, "TkAlOfflineValidationDQM")
00724
00725 def createScript(self, path):
00726 return OfflineValidation.createScript(self, path, "TkAlOfflineValidationDQM")
00727
00728 def getRepMap(self, alignment = None):
00729 repMap = OfflineValidation.getRepMap(self, alignment)
00730 repMap.update({
00731 "workdir": os.path.expandvars(repMap["workdir"]),
00732 "offlineValidationMode": "Dqm",
00733 "offlineValidationFileOutput": configTemplates.offlineDqmFileOutputTemplate,
00734 "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),
00735 "firstRunNumber": "%i"% self.__firstRun
00736 }
00737 )
00738 if "__" in repMap["workflow"]:
00739 raise StandardError, "the DQM workflow specefication must not contain '__'. it is: %s"%repMap["workflow"]
00740 return repMap
00741
00742 class MonteCarloValidation(GenericValidation):
00743 def __init__(self, valName, alignment, config):
00744 GenericValidation.__init__(self, valName, alignment, config)
00745 defaults = {
00746 "jobmode":self.jobmode,
00747 "runRange":"",
00748 "JSON":""
00749 }
00750 mandatories = [ "relvalsample", "maxevents" ]
00751 if not config.has_section( "mcValidate:"+self.name ):
00752 mcValidate = config.getResultingSection( "general",
00753 defaultDict = defaults,
00754 demandPars = mandatories )
00755 else:
00756 mcValidate = config.getResultingSection( "mcValidate:"+self.name,
00757 defaultDict = defaults,
00758 demandPars = mandatories )
00759 self.general.update( mcValidate )
00760 self.jobmode = self.general["jobmode"]
00761
00762 def createConfiguration(self, path ):
00763 cfgName = "TkAlMcValidation.%s.%s_cfg.py"%( self.name,
00764 self.alignmentToValidate.name )
00765 repMap = self.getRepMap()
00766 repMap.update({
00767 "outputFile": replaceByMap( (".oO[workdir]Oo./McValidation_"
00768 + self.name +
00769 "_.oO[name]Oo..root"),
00770 repMap )
00771 })
00772 repMap["outputFile"] = os.path.expandvars( repMap["outputFile"] )
00773 repMap["outputFile"] = os.path.abspath( repMap["outputFile"] )
00774 cfgs = {cfgName:replaceByMap( configTemplates.mcValidateTemplate, repMap)}
00775 self.filesToCompare[ GenericValidation.defaultReferenceName ] = repMap["outputFile"]
00776 GenericValidation.createConfiguration(self, cfgs, path)
00777
00778 def createScript(self, path):
00779 scriptName = "TkAlMcValidate.%s.%s.sh"%( self.name,
00780 self.alignmentToValidate.name )
00781 repMap = self.getRepMap()
00782 repMap["CommandLine"]=""
00783 for cfg in self.configFiles:
00784 repMap["CommandLine"]+= repMap["CommandLineTemplate"]%{"cfgFile":cfg,
00785 "postProcess":""
00786 }
00787
00788 scripts = {scriptName: replaceByMap( configTemplates.scriptTemplate, repMap ) }
00789 return GenericValidation.createScript(self, scripts, path)
00790
00791 def createCrabCfg( self, path,
00792 crabCfgBaseName = "TkAlMcValidate" ):
00793 crabCfgName = "crab.%s.%s.%s.cfg"%( crabCfgBaseName, self.name,
00794 self.alignmentToValidate.name )
00795 repMap = self.getRepMap()
00796 repMap["script"] = "dummy_script.sh"
00797 repMap["crabOutputDir"] = os.path.basename( path )
00798 repMap["crabWorkingDir"] = crabCfgName.split( '.cfg' )[0]
00799 self.crabWorkingDir = repMap["crabWorkingDir"]
00800 repMap["numberOfJobs"] = self.general["parallelJobs"]
00801 repMap["cfgFile"] = self.configFiles[0]
00802 repMap["queue"] = self.jobmode.split( ',' )[1].split( '-q' )[1]
00803 crabCfg = {crabCfgName: replaceByMap( configTemplates.crabCfgTemplate,
00804 repMap ) }
00805 return GenericValidation.createCrabCfg( self, crabCfg, path )
00806
00807 def getRepMap( self, alignment = None ):
00808 repMap = GenericValidation.getRepMap(self, alignment)
00809 repMap.update({
00810 "nEvents": self.general["maxevents"],
00811
00812 "RelValSample": self.general["relvalsample"]
00813
00814 })
00815 return repMap
00816
00817
00818 class TrackSplittingValidation(GenericValidation):
00819 def __init__(self, valName, alignment, config):
00820 GenericValidation.__init__(self, valName, alignment, config)
00821 defaults = {
00822 "jobmode":self.jobmode,
00823 "runRange":"",
00824 "JSON":""
00825 }
00826 mandatories = [ "trackcollection", "maxevents" ]
00827 if not config.has_section( "split:"+self.name ):
00828 split = config.getResultingSection( "general",
00829 defaultDict = defaults,
00830 demandPars = mandatories )
00831 else:
00832 split = config.getResultingSection( "split:"+self.name,
00833 defaultDict = defaults,
00834 demandPars = mandatories )
00835 self.general.update( split )
00836 self.jobmode = self.general["jobmode"]
00837
00838
00839 def createConfiguration(self, path ):
00840 cfgName = "TkAlTrackSplitting.%s.%s_cfg.py"%( self.name,
00841 self.alignmentToValidate.name )
00842 repMap = self.getRepMap()
00843 repMap.update({
00844 "outputFile": replaceByMap( (".oO[workdir]Oo./TrackSplitting_"
00845 + self.name +
00846 "_.oO[name]Oo..root"),
00847 repMap )
00848 })
00849 repMap["outputFile"] = os.path.expandvars( repMap["outputFile"] )
00850 repMap["outputFile"] = os.path.abspath( repMap["outputFile"] )
00851 cfgs = {cfgName:replaceByMap( configTemplates.TrackSplittingTemplate, repMap)}
00852 self.filesToCompare[ GenericValidation.defaultReferenceName ] = repMap["outputFile"]
00853 GenericValidation.createConfiguration(self, cfgs, path)
00854
00855 def createScript(self, path):
00856 scriptName = "TkAlTrackSplitting.%s.%s.sh"%( self.name,
00857 self.alignmentToValidate.name )
00858 repMap = self.getRepMap()
00859 repMap["CommandLine"]=""
00860 for cfg in self.configFiles:
00861 repMap["CommandLine"]+= repMap["CommandLineTemplate"]%{"cfgFile":cfg,
00862 "postProcess":""
00863 }
00864
00865 scripts = {scriptName: replaceByMap( configTemplates.scriptTemplate, repMap ) }
00866 return GenericValidation.createScript(self, scripts, path)
00867
00868 def createCrabCfg( self, path,
00869 crabCfgBaseName = "TkAlTrackSplitting" ):
00870 crabCfgName = "crab.%s.%s.%s.cfg"%( crabCfgBaseName, self.name,
00871 self.alignmentToValidate.name )
00872 repMap = self.getRepMap()
00873 repMap["script"] = "dummy_script.sh"
00874 repMap["crabOutputDir"] = os.path.basename( path )
00875 repMap["crabWorkingDir"] = crabCfgName.split( '.cfg' )[0]
00876 self.crabWorkingDir = repMap["crabWorkingDir"]
00877 repMap["numberOfJobs"] = self.general["parallelJobs"]
00878 repMap["cfgFile"] = self.configFiles[0]
00879 repMap["queue"] = self.jobmode.split( ',' )[1].split( '-q' )[1]
00880 crabCfg = {crabCfgName: replaceByMap( configTemplates.crabCfgTemplate,
00881 repMap ) }
00882 return GenericValidation.createCrabCfg( self, crabCfg, path )
00883
00884 def getRepMap( self, alignment = None ):
00885 repMap = GenericValidation.getRepMap(self)
00886
00887 repMap.update({
00888 "nEvents": self.general["maxevents"],
00889
00890 "TrackCollection": self.general["trackcollection"]
00891 })
00892 return repMap
00893
00894
00895 class ZMuMuValidation(GenericValidation):
00896 def __init__(self, valName, alignment,config):
00897 GenericValidation.__init__(self, valName, alignment, config)
00898 defaults = {
00899 "zmumureference": ("/afs/cern.ch/cms/CAF/CMSALCA/ALCA_TRACKERALIGN2"
00900 "/TMP_EM/ZMuMu/data/MC/BiasCheck_DYToMuMu_Summer"
00901 "11_TkAlZMuMu_IDEAL.root"),
00902 "jobmode":self.jobmode,
00903 "runRange":"",
00904 "JSON":""
00905 }
00906 mandatories = [ "dataset", "maxevents", "etamax1", "etamin1", "etamax2",
00907 "etamin2" ]
00908 if not config.has_section( "zmumu:"+self.name ):
00909 zmumu = config.getResultingSection( "general",
00910 defaultDict = defaults,
00911 demandPars = mandatories )
00912 else:
00913 zmumu = config.getResultingSection( "zmumu:"+self.name,
00914 defaultDict = defaults,
00915 demandPars = mandatories )
00916 self.general.update( zmumu )
00917 self.jobmode = self.general["jobmode"]
00918
00919 def createConfiguration(self, path, configBaseName = "TkAlZMuMuValidation" ):
00920 cfgName = "%s.%s.%s_cfg.py"%( configBaseName, self.name,
00921 self.alignmentToValidate.name )
00922 repMap = self.getRepMap()
00923 cfgs = {cfgName:replaceByMap( configTemplates.ZMuMuValidationTemplate, repMap)}
00924 GenericValidation.createConfiguration(self, cfgs, path)
00925
00926 def createScript(self, path, scriptBaseName = "TkAlZMuMuValidation"):
00927 scriptName = "%s.%s.%s.sh"%(scriptBaseName, self.name,
00928 self.alignmentToValidate.name )
00929 repMap = self.getRepMap()
00930 repMap["CommandLine"]=""
00931 for cfg in self.configFiles:
00932 repMap["CommandLine"]+= repMap["CommandLineTemplate"]%{"cfgFile":cfg,
00933 "postProcess":""
00934 }
00935 scripts = {scriptName: replaceByMap( configTemplates.zMuMuScriptTemplate, repMap ) }
00936 return GenericValidation.createScript(self, scripts, path)
00937
00938 def createCrabCfg( self, path,
00939 crabCfgBaseName = "TkAlZMuMuValidation" ):
00940 crabCfgName = "crab.%s.%s.%s.cfg"%( crabCfgBaseName, self.name,
00941 self.alignmentToValidate.name )
00942 repMap = self.getRepMap()
00943 repMap["script"] = "dummy_script.sh"
00944 repMap["crabOutputDir"] = os.path.basename( path )
00945 repMap["crabWorkingDir"] = crabCfgName.split( '.cfg' )[0]
00946 self.crabWorkingDir = repMap["crabWorkingDir"]
00947 repMap["numberOfJobs"] = self.general["parallelJobs"]
00948 repMap["cfgFile"] = self.configFiles[0]
00949 repMap["queue"] = self.jobmode.split( ',' )[1].split( '-q' )[1]
00950 crabCfg = {crabCfgName: replaceByMap( configTemplates.crabCfgTemplate,
00951 repMap ) }
00952 return GenericValidation.createCrabCfg( self, crabCfg, path )
00953
00954 def getRepMap(self, alignment = None):
00955 repMap = GenericValidation.getRepMap(self, alignment)
00956 repMap.update({
00957 "nEvents": self.general["maxevents"]
00958 })
00959 return repMap
00960
00961
00962 alignRandDict = {}
00963
00964 class ValidationJob:
00965 def __init__( self, validation, config, options ):
00966 if validation[1] == "":
00967
00968 valString = validation[0].split( "->" )[0]
00969 alignments = validation[0].split( "->" )[1]
00970 else:
00971
00972 valString = validation[0]
00973 alignments = validation[1]
00974 valString = valString.split()
00975 self.__valType = valString[0]
00976 self.__valName = valString[1]
00977 self.__commandLineOptions = options
00978 self.__config = config
00979
00980 if self.__valType == "offlineParallel":
00981 section = "offline" + ":" + self.__valName
00982 else:
00983 section = self.__valType + ":" + self.__valName
00984 if not self.__config.has_section( section ):
00985 raise StandardError, ("Validation '%s' of type '%s' is requested in"
00986 " '[validation]' section, but is not defined."
00987 "\nYou have to add a '[%s]' section."
00988 %( self.__valName, self.__valType, section ))
00989 self.validation = self.__getValidation( self.__valType, self.__valName,
00990 alignments, self.__config,
00991 options )
00992
00993 def __getValidation( self, valType, name, alignments, config, options ):
00994 if valType == "compare":
00995 alignmentsList = alignments.split( "," )
00996 firstAlignList = alignmentsList[0].split()
00997 firstAlignName = firstAlignList[0].strip()
00998 if firstAlignName == "IDEAL":
00999 raise StandardError, ("'IDEAL' has to be the second (reference)"
01000 " alignment in 'compare <val_name>: "
01001 "<alignment> <reference>'.")
01002 if len( firstAlignList ) > 1:
01003 firstRun = firstAlignList[1]
01004 else:
01005 firstRun = "1"
01006 firstAlign = Alignment( firstAlignName, self.__config, firstRun )
01007 secondAlignList = alignmentsList[1].split()
01008 secondAlignName = secondAlignList[0].strip()
01009 if len( secondAlignList ) > 1:
01010 secondRun = secondAlignList[1]
01011 else:
01012 secondRun = "1"
01013 if secondAlignName == "IDEAL":
01014 secondAlign = secondAlignName
01015 else:
01016 secondAlign = Alignment( secondAlignName, self.__config,
01017 secondRun )
01018
01019 try:
01020 randomWorkdirPart = alignRandDict[firstAlignName]
01021 except KeyError:
01022 randomWorkdirPart = None
01023
01024 validation = GeometryComparison( name, firstAlign, secondAlign,
01025 self.__config,
01026 self.__commandLineOptions.getImages,
01027 randomWorkdirPart )
01028 alignRandDict[firstAlignName] = validation.randomWorkdirPart
01029 if not secondAlignName == "IDEAL":
01030 alignRandDict[secondAlignName] = validation.randomWorkdirPart
01031 elif valType == "offline":
01032 validation = OfflineValidation( name,
01033 Alignment( alignments.strip(), self.__config ), self.__config )
01034 elif valType == "offlineDQM":
01035 validation = OfflineValidationDQM( name,
01036 Alignment( alignments.strip(), self.__config ), self.__config )
01037 elif valType == "offlineParallel":
01038 validation = OfflineValidationParallel( name,
01039 Alignment( alignments.strip(), self.__config ), self.__config )
01040 elif valType == "mcValidate":
01041 validation = MonteCarloValidation( name,
01042 Alignment( alignments.strip(), self.__config ), self.__config )
01043 elif valType == "split":
01044 validation = TrackSplittingValidation( name,
01045 Alignment( alignments.strip(), self.__config ), self.__config )
01046 elif valType == "zmumu":
01047 validation = ZMuMuValidation( name,
01048 Alignment( alignments.strip(), self.__config ), self.__config )
01049 else:
01050 raise StandardError, "Unknown validation mode '%s'"%valType
01051 return validation
01052
01053 def __createJob( self, jobMode, outpath ):
01054 """This private method creates the needed files for the validation job.
01055 """
01056 self.validation.createConfiguration( outpath )
01057 self.__scripts = self.validation.createScript( outpath )
01058 if jobMode.split( ',' )[0] == "crab":
01059 self.validation.createCrabCfg( outpath )
01060 return None
01061
01062 def createJob(self):
01063 """This is the method called to create the job files."""
01064 self.__createJob( self.validation.jobmode,
01065 os.path.abspath( self.__commandLineOptions.Name) )
01066
01067 def runJob( self ):
01068 general = self.__config.getGeneral()
01069 log = ""
01070 for script in self.__scripts:
01071 name = os.path.splitext( os.path.basename( script) )[0]
01072 if self.__commandLineOptions.dryRun:
01073 print "%s would run: %s"%( name, os.path.basename( script) )
01074 continue
01075 log = "> Validating "+name
01076 print "> Validating "+name
01077 if self.validation.jobmode == "interactive":
01078 log += getCommandOutput2( script )
01079 elif self.validation.jobmode.split(",")[0] == "lxBatch":
01080 repMap = {
01081 "commands": self.validation.jobmode.split(",")[1],
01082 "logDir": general["logdir"],
01083 "jobName": name,
01084 "script": script,
01085 "bsub": "/afs/cern.ch/cms/caf/scripts/cmsbsub"
01086 }
01087 log+=getCommandOutput2("%(bsub)s %(commands)s -J %(jobName)s "
01088 "-o %(logDir)s/%(jobName)s.stdout -e "
01089 "%(logDir)s/%(jobName)s.stderr "
01090 "%(script)s"%repMap)
01091 elif self.validation.jobmode.split( "," )[0] == "crab":
01092 pass
01093 else:
01094 raise StandardError, ("Unknown 'jobmode'!\n"
01095 "Please change this parameter either in "
01096 "the [general] or in the ["
01097 + self.__valType + ":" + self.__valName
01098 + "] section to one of the following "
01099 "values:\n"
01100 "\tinteractive\n\tlxBatch, -q <queue>\n"
01101 "\tcrab, -q <queue>")
01102 return log
01103
01104 def getValidation( self ):
01105 return self.validation
01106
01107
01108 def createCrabScript( path, validations ):
01109 repMap = {"crabCommand": "",
01110 "crabBaseDir": path,
01111 "useCshell": ""
01112 }
01113 for validation in validations:
01114 if validation.jobmode.split( ',' )[0] == 'crab':
01115 valRepMap = {"crabWorkingDir": validation.crabWorkingDir,
01116 "crabCfgName": validation.crabWorkingDir + ".cfg"
01117 }
01118 repMap["crabCommand"] += replaceByMap( configTemplates.crabCommandTemplate,
01119 valRepMap )
01120 if len( repMap["crabCommand"] ) == 0:
01121 return None
01122 crabShScriptPath = os.path.join( path, 'TkAlRunCrab.sh' )
01123 crabShScript = open( crabShScriptPath, 'w' )
01124 crabShScript.write( replaceByMap( configTemplates.crabShellScriptTemplate,
01125 repMap ) )
01126 crabShScript.close()
01127 repMap["useCshell"] = "c"
01128 crabCshScriptPath = os.path.join( path, 'TkAlRunCrab.csh' )
01129 crabCshScript = open( crabCshScriptPath, 'w' )
01130 crabCshScript.write( replaceByMap( configTemplates.crabShellScriptTemplate,
01131 repMap ) )
01132 crabCshScript.close()
01133 return crabShScriptPath, crabCshScriptPath
01134
01135 def createOfflineJobsMergeScript(offlineValidationList, outFilePath):
01136 repMap = offlineValidationList[0].getRepMap()
01137 repMap[ "mergeOfflinParJobsInstantiation" ] = ""
01138
01139 for validation in offlineValidationList:
01140 repMap[ "mergeOfflinParJobsInstantiation" ] = validation.appendToMergeParJobs( repMap[ "mergeOfflinParJobsInstantiation" ] )
01141
01142
01143 theFile = open( outFilePath, "w" )
01144 theFile.write( replaceByMap( configTemplates.mergeOfflineParJobsTemplate ,repMap ) )
01145 theFile.close()
01146
01147 def createExtendedValidationScript(offlineValidationList, outFilePath):
01148 repMap = offlineValidationList[0].getRepMap()
01149 repMap[ "extendedInstantiation" ] = ""
01150
01151 for validation in offlineValidationList:
01152 repMap[ "extendedInstantiation" ] = validation.appendToExtendedValidation( repMap[ "extendedInstantiation" ] )
01153
01154 theFile = open( outFilePath, "w" )
01155 theFile.write( replaceByMap( configTemplates.extendedValidationTemplate ,repMap ) )
01156 theFile.close()
01157
01158 def createMergeScript( path, validations ):
01159 if( len(validations) == 0 ):
01160 raise StandardError, "cowardly refusing to merge nothing!"
01161
01162 repMap = validations[0].getRepMap()
01163 repMap.update({
01164 "DownloadData":"",
01165 "CompareAllignments":"",
01166 "RunExtendedOfflineValidation":""
01167 })
01168
01169 comparisonLists = {}
01170 for validation in validations:
01171 for referenceName in validation.filesToCompare:
01172 validationName = "%s.%s"%(validation.__class__.__name__, referenceName)
01173 validationName = validationName.split(".%s"%GenericValidation.defaultReferenceName )[0]
01174 if validationName in comparisonLists:
01175 comparisonLists[ validationName ].append( validation )
01176 else:
01177 comparisonLists[ validationName ] = [ validation ]
01178
01179 if "OfflineValidation" in comparisonLists:
01180 repMap["extendeValScriptPath"] = os.path.join(path, "TkAlExtendedOfflineValidation.C")
01181 createExtendedValidationScript( comparisonLists["OfflineValidation"], repMap["extendeValScriptPath"] )
01182 repMap["RunExtendedOfflineValidation"] = replaceByMap(configTemplates.extendedValidationExecution, repMap)
01183
01184 repMap["CompareAllignments"] = "#run comparisons"
01185 for validationId in comparisonLists:
01186 compareStrings = [ val.getCompareStrings(validationId) for val in comparisonLists[validationId] ]
01187
01188 repMap.update({"validationId": validationId,
01189 "compareStrings": " , ".join(compareStrings) })
01190
01191 repMap["CompareAllignments"] += replaceByMap( configTemplates.compareAlignmentsExecution, repMap )
01192
01193 filePath = os.path.join(path, "TkAlMerge.sh")
01194 theFile = open( filePath, "w" )
01195 theFile.write( replaceByMap( configTemplates.mergeTemplate, repMap ) )
01196 theFile.close()
01197 os.chmod(filePath,0755)
01198
01199 return filePath
01200
01201 def createParallelMergeScript( path, validations ):
01202 if( len(validations) == 0 ):
01203 raise StandardError, "cowardly refusing to merge nothing!"
01204
01205 repMap = validations[0].getRepMap()
01206 repMap.update({
01207 "DownloadData":"",
01208 "CompareAllignments":"",
01209 "RunExtendedOfflineValidation":""
01210 })
01211
01212 comparisonLists = {}
01213 for validation in validations:
01214 for referenceName in validation.filesToCompare:
01215 validationName = "%s.%s"%(validation.__class__.__name__, referenceName)
01216 validationName = validationName.split(".%s"%GenericValidation.defaultReferenceName )[0]
01217 if validationName in comparisonLists:
01218 comparisonLists[ validationName ].append( validation )
01219 else:
01220 comparisonLists[ validationName ] = [ validation ]
01221
01222 if "OfflineValidationParallel" in comparisonLists:
01223 repMap["extendeValScriptPath"] = os.path.join(path, "TkAlExtendedOfflineValidation.C")
01224 createExtendedValidationScript( comparisonLists["OfflineValidationParallel"], repMap["extendeValScriptPath"] )
01225 repMap["mergeOfflineParJobsScriptPath"] = os.path.join(path, "TkAlOfflineJobsMerge.C")
01226 createOfflineJobsMergeScript( comparisonLists["OfflineValidationParallel"], repMap["mergeOfflineParJobsScriptPath"] )
01227 repMap["RunExtendedOfflineValidation"] = replaceByMap(configTemplates.extendedValidationExecution, repMap)
01228
01229
01230 repMap["DownloadData"] += replaceByMap( configTemplates.mergeOfflineParallelResults, repMap )
01231
01232 repMap["CompareAllignments"] = "#run comparisons"
01233 for validationId in comparisonLists:
01234 compareStrings = [ val.getCompareStrings(validationId) for val in comparisonLists[validationId] ]
01235
01236 repMap.update({"validationId": validationId,
01237 "compareStrings": " , ".join(compareStrings) })
01238
01239 repMap["CompareAllignments"] += replaceByMap( configTemplates.compareAlignmentsExecution, repMap )
01240
01241 filePath = os.path.join(path, "TkAlMerge.sh")
01242 theFile = open( filePath, "w" )
01243 theFile.write( replaceByMap( configTemplates.mergeTemplate, repMap ) )
01244 theFile.close()
01245 os.chmod(filePath,0755)
01246
01247 return filePath
01248
01249 def loadTemplates( config ):
01250 if config.has_section("alternateTemplates"):
01251 for templateName in config.options("alternateTemplates"):
01252 newTemplateName = config.get("alternateTemplates", templateName )
01253
01254 configTemplates.alternateTemplate(templateName, newTemplateName)
01255
01256
01257 def main(argv = None):
01258 if argv == None:
01259 argv = sys.argv[1:]
01260 optParser = optparse.OptionParser()
01261 optParser.description = """ all-in-one alignment Validation
01262 This will run various validation procedures either on batch queues or interactviely.
01263
01264 If no name is given (-N parameter) a name containing time and date is created automatically
01265
01266 To merge the outcome of all validation procedures run TkAlMerge.sh in your validation's directory.
01267 """
01268 optParser.add_option("-n", "--dryRun", dest="dryRun", action="store_true", default=False,
01269 help="create all scripts and cfg File but do not start jobs (default=False)")
01270 optParser.add_option( "--getImages", dest="getImages", action="store_true", default=False,
01271 help="get all Images created during the process (default= False)")
01272 optParser.add_option("-c", "--config", dest="config",
01273 help="configuration to use (default compareConfig.ini) this can be a comma-seperated list of all .ini file you want to merge", metavar="CONFIG")
01274 optParser.add_option("-N", "--Name", dest="Name",
01275 help="Name of this validation (default: alignmentValidation_DATE_TIME)", metavar="NAME")
01276 optParser.add_option("-r", "--restrictTo", dest="restrictTo",
01277 help="restrict validations to given modes (comma seperated) (default: no restriction)", metavar="RESTRICTTO")
01278
01279 (options, args) = optParser.parse_args(argv)
01280
01281 if not options.restrictTo == None:
01282 options.restrictTo = options.restrictTo.split(",")
01283 if options.config == None:
01284 options.config = "compareConfig.ini"
01285 else:
01286 options.config = options.config.split(",")
01287 result = []
01288 for iniFile in options.config:
01289 result.append( os.path.abspath(iniFile) )
01290 options.config = result
01291 config = BetterConfigParser()
01292 config.read( options.config )
01293
01294 if options.Name == None:
01295 options.Name = "alignmentValidation_%s"%(datetime.datetime.now().strftime("%y%m%d_%H%M%S"))
01296
01297 outPath = os.path.abspath( options.Name )
01298 general = config.getGeneral()
01299 config.set("general","workdir",os.path.join(general["workdir"],options.Name) )
01300 config.set("general","datadir",os.path.join(general["datadir"],options.Name) )
01301 config.set("general","logdir",os.path.join(general["logdir"],options.Name) )
01302
01303
01304
01305 if os.path.isdir( config.getGeneral()["logdir"] ):
01306 shutil.rmtree( config.getGeneral()["logdir"] )
01307
01308 if not os.path.exists( outPath ):
01309 os.makedirs( outPath )
01310 elif not os.path.isdir( outPath ):
01311 raise StandardError,"the file %s is in the way rename the Job or move it away"%outPath
01312
01313
01314 loadTemplates( config )
01315
01316
01317 backupConfigFile = open( os.path.join( outPath, "usedConfiguration.ini" ) , "w" )
01318 config.write( backupConfigFile )
01319
01320 jobs = [ ValidationJob( validation, config, options) \
01321 for validation in config.items( "validation" ) ]
01322 map( lambda job: job.createJob(), jobs )
01323 validations = [ job.getValidation() for job in jobs ]
01324
01325 if "OfflineValidationParallel" not in [val.__class__.__name__ for val in validations]:
01326 createMergeScript( outPath, validations )
01327 else:
01328 createParallelMergeScript( outPath, validations )
01329 crabScript = createCrabScript( outPath, validations )
01330
01331 map( lambda job: job.runJob(), jobs )
01332 if crabScript != None:
01333 print
01334 print "="*80
01335 print "To start parallel validation please type:"
01336 print "source "+outPath+"/TkAlRunCrab.sh"
01337 print "\t<or>"
01338 print "source "+outPath+"/TkAlRunCrab.csh"
01339 print "="*80
01340 print
01341
01342
01343 if __name__ == "__main__":
01344
01345 main()
01346