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=[]):
26 defaults = {
"jobmode": self.
general[
"jobmode"],
27 "cmssw": os.environ[
'CMSSW_BASE'],
30 defaults.update(addDefaults)
32 mandatories += addMandatories
33 needpackages = [
"Alignment/OfflineValidation"]
34 needpackages += addneedpackages
35 theUpdate = config.getResultingSection(valType+
":"+self.
name,
36 defaultDict = defaults,
37 demandPars = mandatories)
38 self.general.update(theUpdate)
44 maximumNumberJobs = 40
45 if self.
NJobs > maximumNumberJobs:
46 msg = (
"Maximum allowed number of parallel jobs "
47 +str(maximumNumberJobs)+
" exceeded!!!")
52 for character
in badcharacters:
53 if character
in self.
cmssw:
54 raise AllInOneError(
"The bad characters " + badcharacters +
" are not allowed in the cmssw\n"
55 "path name. If you really have it in such a ridiculously named location,\n"
56 "try making a symbolic link somewhere with a decent name.")
58 os.listdir(self.
cmssw)
62 if self.
cmssw == os.environ[
"CMSSW_BASE"]:
66 command = (
"cd '" + self.
cmssw +
"' && eval `scramv1 ru -sh 2> /dev/null`"
67 ' && echo "$CMSSW_BASE\n$SCRAM_ARCH\n$CMSSW_RELEASE_BASE"')
69 self.
cmssw = commandoutput[0]
74 for package
in needpackages:
76 pkgpath = os.path.join(placetolook,
"src", package)
77 if os.path.exists(pkgpath):
84 if config.has_option(
"alternateTemplates",
"AutoAlternates"):
86 self.
AutoAlternates = json.loads(config.get(
"alternateTemplates",
"AutoAlternates").lower())
88 raise AllInOneError(
"AutoAlternates needs to be true or false, not %s" % config.get(
"alternateTemplates",
"AutoAlternates"))
90 knownOpts = defaults.keys()+mandatories
92 config.checkInput(valType+
":"+self.
name,
93 knownSimpleOptions = knownOpts,
94 ignoreOptions = ignoreOpts)
103 result.update(alignment.getRepMap())
106 "workdir": os.path.join(self.
general[
"workdir"],
108 "datadir": self.
general[
"datadir"],
109 "logdir": self.
general[
"logdir"],
110 "CommandLineTemplate": (
"#run configfile and post-proccess it\n"
111 "cmsRun %(cfgFile)s\n"
113 "CMSSW_BASE": self.
cmssw,
116 "alignmentName": alignment.name,
117 "condLoad": alignment.getConditions(),
118 "condLoad": alignment.getConditions(),
125 repMap = self.alignmentToValidate.getRepMap()
128 if repMap[
"file"].startswith(
"/castor/" ):
129 repMap[
"file"] =
"rfio:%(file)s"%repMap
130 elif repMap[
"file"].startswith(
"/store/" ):
131 repMap[
"file"] =
"root://eoscms.cern.ch//eos/cms%(file)s"%repMap
133 result[validationId]=repMap[
"file"]
135 result[validationId]=
"%(file)s=%(title)s|%(color)s|%(style)s"%repMap
136 if requestId ==
None:
139 if not "." in requestId:
140 requestId +=
".%s"%GenericValidation.defaultReferenceName
141 if not requestId.split(
".")[-1]
in result:
142 msg = (
"could not find %s in reference Objects!"
143 %requestId.split(
".")[-1])
145 return result[ requestId.split(
".")[-1] ]
147 def createFiles(self, fileContents, path, repMap = None, repMaps = None):
148 """repMap: single map for all files
149 repMaps: a dict, with the filenames as the keys"""
150 if repMap
is not None and repMaps
is not None:
151 raise AllInOneError(
"createFiles can only take repMap or repMaps (or neither), not both")
153 for fileName
in fileContents:
154 filePath = os.path.join(path, fileName)
155 result.append(filePath)
157 for (i, filePathi)
in enumerate(
addIndex(filePath, self.
NJobs)):
158 theFile = open( filePathi,
"w" )
159 fileContentsi = fileContents[ fileName ]
160 if repMaps
is not None:
161 repMap = repMaps[fileName]
162 if repMap
is not None:
163 repMap.update({
"nIndex": str(i)})
165 theFile.write( fileContentsi )
171 self.
configFiles = GenericValidation.createFiles(self, fileContents,
172 path, repMap = repMap, repMaps = repMaps)
173 if not schedule ==
None:
174 schedule = [os.path.join( path, cfgName)
for cfgName
in schedule]
175 for cfgName
in schedule:
177 msg = (
"scheduled %s missing in generated configfiles: %s"
181 if not cfgName
in schedule:
182 msg = (
"generated configuration %s not scheduled: %s"
183 %(cfgName, schedule))
188 def createScript(self, fileContents, path, downloadFiles=[], repMap = None, repMaps = None):
189 self.
scriptFiles = GenericValidation.createFiles(self, fileContents,
190 path, repMap = repMap, repMaps = repMaps)
193 os.chmod(scriptwithindex,0o755)
198 msg = (
"jobmode 'crab' not supported for parallel validation."
199 " Please set parallelJobs = 1.")
208 Subclass of `GenericValidation` which is the base for validations using
212 def __init__(self, valName, alignment, config, valType,
213 addDefaults = {}, addMandatories=[], addneedpackages=[]):
215 This method adds additional items to the `self.general` dictionary
216 which are only needed for validations using datasets.
219 - `valName`: String which identifies individual validation instances
220 - `alignment`: `Alignment` instance to validate
221 - `config`: `BetterConfigParser` instance which includes the
222 configuration of the validations
223 - `valType`: String which specifies the type of validation
224 - `addDefaults`: Dictionary which contains default values for individual
225 validations in addition to the general default values
226 - `addMandatories`: List which contains mandatory parameters for
227 individual validations in addition to the general
231 defaults = {
"runRange":
"",
238 defaults.update(addDefaults)
239 mandatories = [
"dataset",
"maxevents" ]
240 mandatories += addMandatories
241 needpackages = addneedpackages
242 GenericValidation.__init__(self, valName, alignment, config, valType, defaults, mandatories, needpackages)
246 if int( self.
general[
"maxevents"] ) == -1
and self.
NJobs > 1:
247 msg = (
"Maximum number of events (maxevents) not specified: "
248 "cannot use parallel jobs.")
251 tryPredefinedFirst = (
not self.jobmode.split(
',' )[0] ==
"crab" and self.
general[
"JSON"] ==
""
252 and self.
general[
"firstRun"] ==
"" and self.
general[
"lastRun"] ==
""
255 if self.
general[
"dataset"]
not in globalDictionaries.usedDatasets:
256 globalDictionaries.usedDatasets[self.
general[
"dataset"]] = {}
258 if self.
cmssw not in globalDictionaries.usedDatasets[self.
general[
"dataset"]]:
259 if globalDictionaries.usedDatasets[self.
general[
"dataset"]] != {}:
260 print (
"Warning: you use the same dataset '%s' in multiple cmssw releases.\n"
261 "This is allowed, but make sure it's not a mistake") % self.
general[
"dataset"]
262 globalDictionaries.usedDatasets[self.
general[
"dataset"]][self.
cmssw] = {
False:
None,
True:
None}
264 if globalDictionaries.usedDatasets[self.
general[
"dataset"]][self.
cmssw][tryPredefinedFirst]
is None:
266 self.
general[
"dataset"], tryPredefinedFirst = tryPredefinedFirst,
268 globalDictionaries.usedDatasets[self.
general[
"dataset"]][self.
cmssw][tryPredefinedFirst] = dataset
269 if tryPredefinedFirst
and not dataset.predefined():
270 globalDictionaries.usedDatasets[self.
general[
"dataset"]][self.
cmssw][
False] = dataset
273 self.
general[
"magneticField"] = self.dataset.magneticField()
274 self.
general[
"defaultMagneticField"] =
"MagneticField"
275 if self.
general[
"magneticField"] ==
"unknown":
276 print "Could not get the magnetic field for this dataset."
277 print "Using the default: ", self.
general[
"defaultMagneticField"]
278 self.
general[
"magneticField"] =
'.oO[defaultMagneticField]Oo.'
280 if not self.jobmode.split(
',' )[0] ==
"crab":
282 self.
general[
"datasetDefinition"] = self.dataset.datasetSnippet(
283 jsonPath = self.
general[
"JSON"],
284 firstRun = self.
general[
"firstRun"],
285 lastRun = self.
general[
"lastRun"],
288 parent = self.needParentFiles )
289 except AllInOneError
as e:
290 msg =
"In section [%s:%s]: "%(valType, self.
name)
294 if self.dataset.predefined():
295 msg = (
"For jobmode 'crab' you cannot use predefined datasets "
296 "(in your case: '%s')."%( self.dataset.name() ))
299 theUpdate = config.getResultingSection(valType+
":"+self.
name,
300 demandPars = [
"parallelJobs"])
301 except AllInOneError
as e:
302 msg = str(e)[:-1]+
" when using 'jobmode: crab'."
304 self.general.update(theUpdate)
309 self.
general[
"lastRun"] ) = self.dataset.convertTimeToRun(
310 firstRun = self.
general[
"firstRun"],
311 lastRun = self.
general[
"lastRun"],
315 if self.
general[
"begin"] ==
None:
317 if self.
general[
"end"] ==
None:
321 if (
not self.
general[
"firstRun"] )
and \
323 self.
general[
"firstRun"] = str(
324 self.dataset.runList()[0][
"run_number"])
325 if (
not self.
general[
"lastRun"] )
and \
328 self.dataset.runList()[-1][
"run_number"])
331 msg = (
"The lower time/runrange limit ('begin'/'firstRun') "
332 "chosen is greater than the upper time/runrange limit "
333 "('end'/'lastRun').")
336 +
'-' + self.
general[
"lastRun"])
338 self.
general[
"datasetDefinition"] = self.dataset.datasetSnippet(
339 jsonPath = self.
general[
"JSON"],
340 firstRun = self.
general[
"firstRun"],
341 lastRun = self.
general[
"lastRun"],
345 except AllInOneError
as e:
346 msg =
"In section [%s:%s]: "%(valType, self.
name)
351 result = GenericValidation.getRepMap(self, alignment)
353 "%s_%s_.oO[name]Oo..root" % (self.outputBaseName, self.
name)
355 resultfile = os.path.expandvars(
replaceByMap((
"/store/caf/user/$USER/.oO[eosdir]Oo./" +
356 "%s_%s_.oO[name]Oo..root" % (self.resultBaseName, self.
name))
359 "resultFile":
".oO[resultFiles[.oO[nIndex]Oo.]]Oo.",
361 "finalResultFile": resultfile,
362 "outputFile":
".oO[outputFiles[.oO[nIndex]Oo.]]Oo.",
364 "finalOutputFile": outputfile
368 def createScript(self, path, template = configTemplates.scriptTemplate, downloadFiles=[], repMap = None, repMaps = None):
369 scriptName =
"%s.%s.%s.sh"%(self.scriptBaseName, self.
name,
370 self.alignmentToValidate.name )
371 if repMap
is None and repMaps
is None:
373 repMap[
"CommandLine"]=
""
375 repMap[
"CommandLine"]+= repMap[
"CommandLineTemplate"]%{
"cfgFile":
addIndex(cfg, self.
NJobs,
".oO[nIndex]Oo."),
378 scripts = {scriptName: template}
379 return GenericValidation.createScript(self, scripts, path, downloadFiles = downloadFiles,
380 repMap = repMap, repMaps = repMaps)
384 Method which creates a `crab.cfg` for a validation on datasets.
387 - `path`: Path at which the file will be stored.
388 - `crabCfgBaseName`: String which depends on the actual type of
389 validation calling this method.
391 crabCfgName =
"crab.%s.%s.%s.cfg"%( crabCfgBaseName, self.
name,
392 self.alignmentToValidate.name )
394 repMap[
"script"] =
"dummy_script.sh"
396 repMap[
"crabWorkingDir"] = crabCfgName.split(
'.cfg' )[0]
398 repMap[
"numberOfJobs"] = self.
general[
"parallelJobs"]
400 repMap[
"queue"] = self.jobmode.split(
',' )[1].
split(
'-q' )[1]
401 if self.dataset.dataType() ==
"mc":
402 repMap[
"McOrData"] =
"events = .oO[nEvents]Oo."
403 elif self.dataset.dataType() ==
"data":
404 repMap[
"McOrData"] =
"lumis = -1"
405 if self.jobmode.split(
',' )[0] ==
"crab":
406 print (
"For jobmode 'crab' the parameter 'maxevents' will be "
407 "ignored and all events will be processed.")
409 raise AllInOneError(
"Unknown data type! Can't run in crab mode")
410 crabCfg = {crabCfgName:
replaceByMap( configTemplates.crabCfgTemplate,
412 return GenericValidation.createCrabCfg( self, crabCfg, path )
def replaceByMap
— Helpers —############################