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=[]):
27 "jobmode": self.
general[
"jobmode"],
28 "cmssw": os.environ[
'CMSSW_BASE'],
32 defaults.update(addDefaults)
34 mandatories += addMandatories
35 needpackages = [
"Alignment/OfflineValidation"]
36 needpackages += addneedpackages
37 theUpdate = config.getResultingSection(valType+
":"+self.
name,
38 defaultDict = defaults,
39 demandPars = mandatories)
40 self.general.update(theUpdate)
46 maximumNumberJobs = 40
47 if self.
NJobs > maximumNumberJobs:
48 msg = (
"Maximum allowed number of parallel jobs "
49 +str(maximumNumberJobs)+
" exceeded!!!")
56 if "is not found" in output:
raise RuntimeError
62 for character
in badcharacters:
63 if character
in self.
cmssw:
64 raise AllInOneError(
"The bad characters " + badcharacters +
" are not allowed in the cmssw\n"
65 "path name. If you really have it in such a ridiculously named location,\n"
66 "try making a symbolic link somewhere with a decent name.")
68 os.listdir(self.
cmssw)
72 if self.
cmssw == os.environ[
"CMSSW_BASE"]:
76 command = (
"cd '" + self.
cmssw +
"' && eval `scramv1 ru -sh 2> /dev/null`"
77 ' && echo "$CMSSW_BASE\n$SCRAM_ARCH\n$CMSSW_RELEASE_BASE"')
79 self.
cmssw = commandoutput[0]
84 for package
in needpackages:
86 pkgpath = os.path.join(placetolook,
"src", package)
87 if os.path.exists(pkgpath):
94 if config.has_option(
"alternateTemplates",
"AutoAlternates"):
96 self.
AutoAlternates = json.loads(config.get(
"alternateTemplates",
"AutoAlternates").lower())
98 raise AllInOneError(
"AutoAlternates needs to be true or false, not %s" % config.get(
"alternateTemplates",
"AutoAlternates"))
100 knownOpts = defaults.keys()+mandatories
102 config.checkInput(valType+
":"+self.
name,
103 knownSimpleOptions = knownOpts,
104 ignoreOptions = ignoreOpts)
107 if alignment ==
None:
113 result.update(alignment.getRepMap())
116 "workdir": os.path.join(self.
general[
"workdir"],
118 "datadir": self.
general[
"datadir"],
119 "logdir": self.
general[
"logdir"],
120 "CommandLineTemplate": (
"#run configfile and post-proccess it\n"
121 "cmsRun %(cfgFile)s\n"
123 "CMSSW_BASE": self.
cmssw,
126 "alignmentName": alignment.name,
127 "condLoad": alignment.getConditions(),
128 "condLoad": alignment.getConditions(),
135 repMap = self.alignmentToValidate.getRepMap()
138 if repMap[
"file"].startswith(
"/castor/" ):
139 repMap[
"file"] =
"rfio:%(file)s"%repMap
140 elif repMap[
"file"].startswith(
"/store/" ):
141 repMap[
"file"] =
"root://eoscms.cern.ch//eos/cms%(file)s"%repMap
143 result[validationId]=repMap[
"file"]
145 result[validationId]=
"%(file)s=%(title)s|%(color)s|%(style)s"%repMap
146 if requestId ==
None:
149 if not "." in requestId:
150 requestId +=
".%s"%GenericValidation.defaultReferenceName
151 if not requestId.split(
".")[-1]
in result:
152 msg = (
"could not find %s in reference Objects!"
153 %requestId.split(
".")[-1])
155 return result[ requestId.split(
".")[-1] ]
157 def createFiles(self, fileContents, path, repMap = None, repMaps = None):
158 """repMap: single map for all files
159 repMaps: a dict, with the filenames as the keys"""
160 if repMap
is not None and repMaps
is not None:
161 raise AllInOneError(
"createFiles can only take repMap or repMaps (or neither), not both")
163 for fileName
in fileContents:
164 filePath = os.path.join(path, fileName)
165 result.append(filePath)
167 for (i, filePathi)
in enumerate(
addIndex(filePath, self.
NJobs)):
168 theFile = open( filePathi,
"w" )
169 fileContentsi = fileContents[ fileName ]
170 if repMaps
is not None:
171 repMap = repMaps[fileName]
172 if repMap
is not None:
173 repMap.update({
"nIndex": str(i)})
175 theFile.write( fileContentsi )
181 self.
configFiles = GenericValidation.createFiles(self, fileContents,
182 path, repMap = repMap, repMaps = repMaps)
183 if not schedule ==
None:
184 schedule = [os.path.join( path, cfgName)
for cfgName
in schedule]
185 for cfgName
in schedule:
187 msg = (
"scheduled %s missing in generated configfiles: %s"
191 if not cfgName
in schedule:
192 msg = (
"generated configuration %s not scheduled: %s"
193 %(cfgName, schedule))
198 def createScript(self, fileContents, path, downloadFiles=[], repMap = None, repMaps = None):
199 self.
scriptFiles = GenericValidation.createFiles(self, fileContents,
200 path, repMap = repMap, repMaps = repMaps)
203 os.chmod(scriptwithindex,0o755)
208 msg = (
"jobmode 'crab' not supported for parallel validation."
209 " Please set parallelJobs = 1.")
218 Subclass of `GenericValidation` which is the base for validations using
222 def __init__(self, valName, alignment, config, valType,
223 addDefaults = {}, addMandatories=[], addneedpackages=[]):
225 This method adds additional items to the `self.general` dictionary
226 which are only needed for validations using datasets.
229 - `valName`: String which identifies individual validation instances
230 - `alignment`: `Alignment` instance to validate
231 - `config`: `BetterConfigParser` instance which includes the
232 configuration of the validations
233 - `valType`: String which specifies the type of validation
234 - `addDefaults`: Dictionary which contains default values for individual
235 validations in addition to the general default values
236 - `addMandatories`: List which contains mandatory parameters for
237 individual validations in addition to the general
241 defaults = {
"runRange":
"",
248 defaults.update(addDefaults)
249 mandatories = [
"dataset",
"maxevents" ]
250 mandatories += addMandatories
251 needpackages = addneedpackages
252 GenericValidation.__init__(self, valName, alignment, config, valType, defaults, mandatories, needpackages)
256 if int( self.
general[
"maxevents"] ) == -1
and self.
NJobs > 1:
257 msg = (
"Maximum number of events (maxevents) not specified: "
258 "cannot use parallel jobs.")
261 tryPredefinedFirst = (
not self.jobmode.split(
',' )[0] ==
"crab" and self.
general[
"JSON"] ==
""
262 and self.
general[
"firstRun"] ==
"" and self.
general[
"lastRun"] ==
""
265 if self.
general[
"dataset"]
not in globalDictionaries.usedDatasets:
266 globalDictionaries.usedDatasets[self.
general[
"dataset"]] = {}
268 if self.
cmssw not in globalDictionaries.usedDatasets[self.
general[
"dataset"]]:
269 if globalDictionaries.usedDatasets[self.
general[
"dataset"]] != {}:
270 print (
"Warning: you use the same dataset '%s' in multiple cmssw releases.\n"
271 "This is allowed, but make sure it's not a mistake") % self.
general[
"dataset"]
272 globalDictionaries.usedDatasets[self.
general[
"dataset"]][self.
cmssw] = {
False:
None,
True:
None}
274 if globalDictionaries.usedDatasets[self.
general[
"dataset"]][self.
cmssw][tryPredefinedFirst]
is None:
276 self.
general[
"dataset"], tryPredefinedFirst = tryPredefinedFirst,
278 globalDictionaries.usedDatasets[self.
general[
"dataset"]][self.
cmssw][tryPredefinedFirst] = dataset
279 if tryPredefinedFirst
and not dataset.predefined():
280 globalDictionaries.usedDatasets[self.
general[
"dataset"]][self.
cmssw][
False] = dataset
283 self.
general[
"magneticField"] = self.dataset.magneticField()
284 self.
general[
"defaultMagneticField"] =
"MagneticField"
285 if self.
general[
"magneticField"] ==
"unknown":
286 print "Could not get the magnetic field for this dataset."
287 print "Using the default: ", self.
general[
"defaultMagneticField"]
288 self.
general[
"magneticField"] =
'.oO[defaultMagneticField]Oo.'
290 if not self.jobmode.split(
',' )[0] ==
"crab":
292 self.
general[
"datasetDefinition"] = self.dataset.datasetSnippet(
293 jsonPath = self.
general[
"JSON"],
294 firstRun = self.
general[
"firstRun"],
295 lastRun = self.
general[
"lastRun"],
298 parent = self.needParentFiles )
299 except AllInOneError
as e:
300 msg =
"In section [%s:%s]: "%(valType, self.
name)
304 if self.dataset.predefined():
305 msg = (
"For jobmode 'crab' you cannot use predefined datasets "
306 "(in your case: '%s')."%( self.dataset.name() ))
309 theUpdate = config.getResultingSection(valType+
":"+self.
name,
310 demandPars = [
"parallelJobs"])
311 except AllInOneError
as e:
312 msg = str(e)[:-1]+
" when using 'jobmode: crab'."
314 self.general.update(theUpdate)
319 self.
general[
"lastRun"] ) = self.dataset.convertTimeToRun(
320 firstRun = self.
general[
"firstRun"],
321 lastRun = self.
general[
"lastRun"],
325 if self.
general[
"begin"] ==
None:
327 if self.
general[
"end"] ==
None:
331 if (
not self.
general[
"firstRun"] )
and \
333 self.
general[
"firstRun"] = str(
334 self.dataset.runList()[0][
"run_number"])
335 if (
not self.
general[
"lastRun"] )
and \
338 self.dataset.runList()[-1][
"run_number"])
341 msg = (
"The lower time/runrange limit ('begin'/'firstRun') "
342 "chosen is greater than the upper time/runrange limit "
343 "('end'/'lastRun').")
346 +
'-' + self.
general[
"lastRun"])
348 self.
general[
"datasetDefinition"] = self.dataset.datasetSnippet(
349 jsonPath = self.
general[
"JSON"],
350 firstRun = self.
general[
"firstRun"],
351 lastRun = self.
general[
"lastRun"],
355 except AllInOneError
as e:
356 msg =
"In section [%s:%s]: "%(valType, self.
name)
361 result = GenericValidation.getRepMap(self, alignment)
363 "%s_%s_.oO[name]Oo..root" % (self.outputBaseName, self.
name)
365 resultfile = os.path.expandvars(
replaceByMap((
"/store/caf/user/$USER/.oO[eosdir]Oo./" +
366 "%s_%s_.oO[name]Oo..root" % (self.resultBaseName, self.
name))
369 "resultFile":
".oO[resultFiles[.oO[nIndex]Oo.]]Oo.",
371 "finalResultFile": resultfile,
372 "outputFile":
".oO[outputFiles[.oO[nIndex]Oo.]]Oo.",
374 "finalOutputFile": outputfile
378 def createScript(self, path, template = configTemplates.scriptTemplate, downloadFiles=[], repMap = None, repMaps = None):
379 scriptName =
"%s.%s.%s.sh"%(self.scriptBaseName, self.
name,
380 self.alignmentToValidate.name )
381 if repMap
is None and repMaps
is None:
383 repMap[
"CommandLine"]=
""
385 repMap[
"CommandLine"]+= repMap[
"CommandLineTemplate"]%{
"cfgFile":
addIndex(cfg, self.
NJobs,
".oO[nIndex]Oo."),
388 scripts = {scriptName: template}
389 return GenericValidation.createScript(self, scripts, path, downloadFiles = downloadFiles,
390 repMap = repMap, repMaps = repMaps)
394 Method which creates a `crab.cfg` for a validation on datasets.
397 - `path`: Path at which the file will be stored.
398 - `crabCfgBaseName`: String which depends on the actual type of
399 validation calling this method.
401 crabCfgName =
"crab.%s.%s.%s.cfg"%( crabCfgBaseName, self.
name,
402 self.alignmentToValidate.name )
404 repMap[
"script"] =
"dummy_script.sh"
406 repMap[
"crabWorkingDir"] = crabCfgName.split(
'.cfg' )[0]
408 repMap[
"numberOfJobs"] = self.
general[
"parallelJobs"]
410 repMap[
"queue"] = self.jobmode.split(
',' )[1].
split(
'-q' )[1]
411 if self.dataset.dataType() ==
"mc":
412 repMap[
"McOrData"] =
"events = .oO[nEvents]Oo."
413 elif self.dataset.dataType() ==
"data":
414 repMap[
"McOrData"] =
"lumis = -1"
415 if self.jobmode.split(
',' )[0] ==
"crab":
416 print (
"For jobmode 'crab' the parameter 'maxevents' will be "
417 "ignored and all events will be processed.")
419 raise AllInOneError(
"Unknown data type! Can't run in crab mode")
420 crabCfg = {crabCfgName:
replaceByMap( configTemplates.crabCfgTemplate,
422 return GenericValidation.createCrabCfg( self, crabCfg, path )
def replaceByMap
— Helpers —############################