4 import globalDictionaries
6 from dataset
import Dataset
7 from helperFunctions
import replaceByMap, addIndex, getCommandOutput2
8 from plottingOptions
import PlottingOptions
9 from TkAlExceptions
import AllInOneError
13 defaultReferenceName =
"DEFAULT"
14 def __init__(self, valName, alignment, config, valType,
15 addDefaults = {}, addMandatories=[], addneedpackages=[]):
28 "jobmode": self.
general[
"jobmode"],
29 "cmssw": os.environ[
'CMSSW_BASE'],
33 defaults.update(addDefaults)
35 mandatories += addMandatories
36 needpackages = [
"Alignment/OfflineValidation"]
37 needpackages += addneedpackages
38 theUpdate = config.getResultingSection(valType+
":"+self.
name,
39 defaultDict = defaults,
40 demandPars = mandatories)
41 self.general.update(theUpdate)
47 maximumNumberJobs = 40
48 if self.
NJobs > maximumNumberJobs:
49 msg = (
"Maximum allowed number of parallel jobs "
50 +str(maximumNumberJobs)+
" exceeded!!!")
57 if "is not found" in output:
raise RuntimeError
63 for character
in badcharacters:
64 if character
in self.
cmssw:
65 raise AllInOneError(
"The bad characters " + badcharacters +
" are not allowed in the cmssw\n"
66 "path name. If you really have it in such a ridiculously named location,\n"
67 "try making a symbolic link somewhere with a decent name.")
69 os.listdir(self.
cmssw)
73 if self.
cmssw == os.environ[
"CMSSW_BASE"]:
77 command = (
"cd '" + self.
cmssw +
"' && eval `scramv1 ru -sh 2> /dev/null`"
78 ' && echo "$CMSSW_BASE\n$SCRAM_ARCH\n$CMSSW_RELEASE_BASE"')
80 self.
cmssw = commandoutput[0]
85 for package
in needpackages:
87 pkgpath = os.path.join(placetolook,
"src", package)
88 if os.path.exists(pkgpath):
95 if config.has_option(
"alternateTemplates",
"AutoAlternates"):
97 self.
AutoAlternates = json.loads(config.get(
"alternateTemplates",
"AutoAlternates").lower())
99 raise AllInOneError(
"AutoAlternates needs to be true or false, not %s" % config.get(
"alternateTemplates",
"AutoAlternates"))
101 knownOpts = defaults.keys()+mandatories
103 config.checkInput(valType+
":"+self.
name,
104 knownSimpleOptions = knownOpts,
105 ignoreOptions = ignoreOpts)
108 if alignment ==
None:
114 result.update(alignment.getRepMap())
117 "workdir": os.path.join(self.
general[
"workdir"],
119 "datadir": self.
general[
"datadir"],
120 "logdir": self.
general[
"logdir"],
121 "CommandLineTemplate": (
"#run configfile and post-proccess it\n"
122 "cmsRun %(cfgFile)s\n"
124 "CMSSW_BASE": self.
cmssw,
127 "alignmentName": alignment.name,
128 "condLoad": alignment.getConditions(),
129 "LoadGlobalTagTemplate": configTemplates.loadGlobalTagTemplate,
136 repMap = self.alignmentToValidate.getRepMap()
139 if repMap[
"file"].startswith(
"/castor/" ):
140 repMap[
"file"] =
"rfio:%(file)s"%repMap
141 elif repMap[
"file"].startswith(
"/store/" ):
142 repMap[
"file"] =
"root://eoscms.cern.ch//eos/cms%(file)s"%repMap
144 result[validationId]=repMap[
"file"]
146 result[validationId]=
"%(file)s=%(title)s|%(color)s|%(style)s"%repMap
147 if requestId ==
None:
150 if not "." in requestId:
151 requestId +=
".%s"%GenericValidation.defaultReferenceName
152 if not requestId.split(
".")[-1]
in result:
153 msg = (
"could not find %s in reference Objects!"
154 %requestId.split(
".")[-1])
156 return result[ requestId.split(
".")[-1] ]
158 def createFiles(self, fileContents, path, repMap = None, repMaps = None):
159 """repMap: single map for all files
160 repMaps: a dict, with the filenames as the keys"""
161 if repMap
is not None and repMaps
is not None:
162 raise AllInOneError(
"createFiles can only take repMap or repMaps (or neither), not both")
164 for fileName
in fileContents:
165 filePath = os.path.join(path, fileName)
166 result.append(filePath)
168 for (i, filePathi)
in enumerate(
addIndex(filePath, self.
NJobs)):
169 theFile = open( filePathi,
"w" )
170 fileContentsi = fileContents[ fileName ]
171 if repMaps
is not None:
172 repMap = repMaps[fileName]
173 if repMap
is not None:
174 repMap.update({
"nIndex": str(i)})
176 theFile.write( fileContentsi )
182 self.
configFiles = GenericValidation.createFiles(self, fileContents,
183 path, repMap = repMap, repMaps = repMaps)
184 if not schedule ==
None:
185 schedule = [os.path.join( path, cfgName)
for cfgName
in schedule]
186 for cfgName
in schedule:
188 msg = (
"scheduled %s missing in generated configfiles: %s"
192 if not cfgName
in schedule:
193 msg = (
"generated configuration %s not scheduled: %s"
194 %(cfgName, schedule))
199 def createScript(self, fileContents, path, downloadFiles=[], repMap = None, repMaps = None):
200 self.
scriptFiles = GenericValidation.createFiles(self, fileContents,
201 path, repMap = repMap, repMaps = repMaps)
204 os.chmod(scriptwithindex,0o755)
209 msg = (
"jobmode 'crab' not supported for parallel validation."
210 " Please set parallelJobs = 1.")
219 Subclass of `GenericValidation` which is the base for validations using
223 def __init__(self, valName, alignment, config, valType,
224 addDefaults = {}, addMandatories=[], addneedpackages=[]):
226 This method adds additional items to the `self.general` dictionary
227 which are only needed for validations using datasets.
230 - `valName`: String which identifies individual validation instances
231 - `alignment`: `Alignment` instance to validate
232 - `config`: `BetterConfigParser` instance which includes the
233 configuration of the validations
234 - `valType`: String which specifies the type of validation
235 - `addDefaults`: Dictionary which contains default values for individual
236 validations in addition to the general default values
237 - `addMandatories`: List which contains mandatory parameters for
238 individual validations in addition to the general
242 defaults = {
"runRange":
"",
249 defaults.update(addDefaults)
250 mandatories = [
"dataset",
"maxevents" ]
251 mandatories += addMandatories
252 needpackages = addneedpackages
253 GenericValidation.__init__(self, valName, alignment, config, valType, defaults, mandatories, needpackages)
257 if int( self.
general[
"maxevents"] ) == -1
and self.
NJobs > 1:
258 msg = (
"Maximum number of events (maxevents) not specified: "
259 "cannot use parallel jobs.")
262 tryPredefinedFirst = (
not self.jobmode.split(
',' )[0] ==
"crab" and self.
general[
"JSON"] ==
""
263 and self.
general[
"firstRun"] ==
"" and self.
general[
"lastRun"] ==
""
266 if self.
general[
"dataset"]
not in globalDictionaries.usedDatasets:
267 globalDictionaries.usedDatasets[self.
general[
"dataset"]] = {}
269 if self.
cmssw not in globalDictionaries.usedDatasets[self.
general[
"dataset"]]:
270 if globalDictionaries.usedDatasets[self.
general[
"dataset"]] != {}:
271 print (
"Warning: you use the same dataset '%s' in multiple cmssw releases.\n"
272 "This is allowed, but make sure it's not a mistake") % self.
general[
"dataset"]
273 globalDictionaries.usedDatasets[self.
general[
"dataset"]][self.
cmssw] = {
False:
None,
True:
None}
275 if globalDictionaries.usedDatasets[self.
general[
"dataset"]][self.
cmssw][tryPredefinedFirst]
is None:
277 self.
general[
"dataset"], tryPredefinedFirst = tryPredefinedFirst,
279 globalDictionaries.usedDatasets[self.
general[
"dataset"]][self.
cmssw][tryPredefinedFirst] = dataset
280 if tryPredefinedFirst
and not dataset.predefined():
281 globalDictionaries.usedDatasets[self.
general[
"dataset"]][self.
cmssw][
False] = dataset
284 self.
general[
"magneticField"] = self.dataset.magneticField()
285 self.
general[
"defaultMagneticField"] =
"MagneticField"
286 if self.
general[
"magneticField"] ==
"unknown":
287 print "Could not get the magnetic field for this dataset."
288 print "Using the default: ", self.
general[
"defaultMagneticField"]
289 self.
general[
"magneticField"] =
'.oO[defaultMagneticField]Oo.'
291 if not self.jobmode.split(
',' )[0] ==
"crab":
293 self.
general[
"datasetDefinition"] = self.dataset.datasetSnippet(
294 jsonPath = self.
general[
"JSON"],
295 firstRun = self.
general[
"firstRun"],
296 lastRun = self.
general[
"lastRun"],
299 parent = self.needParentFiles )
300 except AllInOneError
as e:
301 msg =
"In section [%s:%s]: "%(valType, self.
name)
305 if self.dataset.predefined():
306 msg = (
"For jobmode 'crab' you cannot use predefined datasets "
307 "(in your case: '%s')."%( self.dataset.name() ))
310 theUpdate = config.getResultingSection(valType+
":"+self.
name,
311 demandPars = [
"parallelJobs"])
312 except AllInOneError
as e:
313 msg = str(e)[:-1]+
" when using 'jobmode: crab'."
315 self.general.update(theUpdate)
320 self.
general[
"lastRun"] ) = self.dataset.convertTimeToRun(
321 firstRun = self.
general[
"firstRun"],
322 lastRun = self.
general[
"lastRun"],
326 if self.
general[
"begin"] ==
None:
328 if self.
general[
"end"] ==
None:
332 if (
not self.
general[
"firstRun"] )
and \
334 self.
general[
"firstRun"] = str(
335 self.dataset.runList()[0][
"run_number"])
336 if (
not self.
general[
"lastRun"] )
and \
339 self.dataset.runList()[-1][
"run_number"])
342 msg = (
"The lower time/runrange limit ('begin'/'firstRun') "
343 "chosen is greater than the upper time/runrange limit "
344 "('end'/'lastRun').")
347 +
'-' + self.
general[
"lastRun"])
349 self.
general[
"datasetDefinition"] = self.dataset.datasetSnippet(
350 jsonPath = self.
general[
"JSON"],
351 firstRun = self.
general[
"firstRun"],
352 lastRun = self.
general[
"lastRun"],
356 except AllInOneError
as e:
357 msg =
"In section [%s:%s]: "%(valType, self.
name)
362 result = GenericValidation.getRepMap(self, alignment)
364 "%s_%s_.oO[name]Oo..root" % (self.outputBaseName, self.
name)
366 resultfile = os.path.expandvars(
replaceByMap((
"/store/caf/user/$USER/.oO[eosdir]Oo./" +
367 "%s_%s_.oO[name]Oo..root" % (self.resultBaseName, self.
name))
370 "resultFile":
".oO[resultFiles[.oO[nIndex]Oo.]]Oo.",
372 "finalResultFile": resultfile,
373 "outputFile":
".oO[outputFiles[.oO[nIndex]Oo.]]Oo.",
375 "finalOutputFile": outputfile
379 def createScript(self, path, template = configTemplates.scriptTemplate, downloadFiles=[], repMap = None, repMaps = None):
380 scriptName =
"%s.%s.%s.sh"%(self.scriptBaseName, self.
name,
381 self.alignmentToValidate.name )
382 if repMap
is None and repMaps
is None:
384 repMap[
"CommandLine"]=
""
386 repMap[
"CommandLine"]+= repMap[
"CommandLineTemplate"]%{
"cfgFile":
addIndex(cfg, self.
NJobs,
".oO[nIndex]Oo."),
389 scripts = {scriptName: template}
390 return GenericValidation.createScript(self, scripts, path, downloadFiles = downloadFiles,
391 repMap = repMap, repMaps = repMaps)
395 Method which creates a `crab.cfg` for a validation on datasets.
398 - `path`: Path at which the file will be stored.
399 - `crabCfgBaseName`: String which depends on the actual type of
400 validation calling this method.
402 crabCfgName =
"crab.%s.%s.%s.cfg"%( crabCfgBaseName, self.
name,
403 self.alignmentToValidate.name )
405 repMap[
"script"] =
"dummy_script.sh"
407 repMap[
"crabWorkingDir"] = crabCfgName.split(
'.cfg' )[0]
409 repMap[
"numberOfJobs"] = self.
general[
"parallelJobs"]
411 repMap[
"queue"] = self.jobmode.split(
',' )[1].
split(
'-q' )[1]
412 if self.dataset.dataType() ==
"mc":
413 repMap[
"McOrData"] =
"events = .oO[nEvents]Oo."
414 elif self.dataset.dataType() ==
"data":
415 repMap[
"McOrData"] =
"lumis = -1"
416 if self.jobmode.split(
',' )[0] ==
"crab":
417 print (
"For jobmode 'crab' the parameter 'maxevents' will be "
418 "ignored and all events will be processed.")
420 raise AllInOneError(
"Unknown data type! Can't run in crab mode")
421 crabCfg = {crabCfgName:
replaceByMap( configTemplates.crabCfgTemplate,
423 return GenericValidation.createCrabCfg( self, crabCfg, path )
def replaceByMap
— Helpers —############################