3 from __future__
import print_function
4 from future.utils
import lmap
13 import Alignment.OfflineValidation.TkAlAllInOneTool.findAndChange
as fnc
15 import Alignment.OfflineValidation.TkAlAllInOneTool.GCP
as GCP
16 import Alignment.OfflineValidation.TkAlAllInOneTool.DMR
as DMR
17 import Alignment.OfflineValidation.TkAlAllInOneTool.Zmumu
as Zmumu
18 import Alignment.OfflineValidation.TkAlAllInOneTool.PV
as PV
19 import Alignment.OfflineValidation.TkAlAllInOneTool.SplitV
as SplitV
20 import Alignment.OfflineValidation.TkAlAllInOneTool.JetHT
as JetHT
21 import Alignment.OfflineValidation.TkAlAllInOneTool.DiMuonV
as DiMuonV
22 import Alignment.OfflineValidation.TkAlAllInOneTool.MTS
as MTS
23 import Alignment.OfflineValidation.TkAlAllInOneTool.PixBary
as PixBary
28 """ Parse user input """ 30 parser = argparse.ArgumentParser(description =
"AllInOneTool for validation of the tracker alignment", formatter_class=argparse.RawTextHelpFormatter)
31 parser.add_argument(
"config", metavar=
'config', type=str, action=
"store", help=
"Global AllInOneTool config (json/yaml format)")
32 parser.add_argument(
"-d",
"--dry", action =
"store_true", help =
"Set up everything, but don't run anything")
33 parser.add_argument(
"-v",
"--verbose", action =
"store_true", help =
"Enable standard output stream")
34 parser.add_argument(
"-e",
"--example", action =
"store_true", help =
"Print example of config in JSON format")
35 parser.add_argument(
"-f",
"--force", action =
"store_true", help =
"Force creation of enviroment, possible overwritten old configuration")
36 parser.add_argument(
"-j",
"--job-flavour", action =
"store", default =
"workday", choices = [
"espresso",
"microcentury",
"longlunch",
"workday",
"tomorrow",
"testmatch",
"nextweek"], help =
"Job flavours for HTCondor at CERN, default is 'workday'")
38 return parser.parse_args()
43 """Check if GRID proxy has been initialized.""" 46 with open(os.devnull,
"w")
as dump:
47 subprocess.check_call([
"voms-proxy-info",
"--exists"],
48 stdout = dump, stderr = dump)
49 except subprocess.CalledProcessError:
56 """Forward proxy to location visible from the batch system. 58 - `rundir`: directory for storing the forwarded proxy 60 - Full path to the forwarded proxy 64 print(
"Please create proxy via 'voms-proxy-init -voms cms'.")
68 proxyName =
"{}/.user_proxy".
format(rundir)
69 localProxy = subprocess.check_output([
"voms-proxy-info",
"--path"]).
strip()
70 shutil.copyfile(localProxy, proxyName)
79 """Update a template configuration file with custom configuration 81 - configurationFile: File name for the configuration file that will be updated 82 - updateInstructions: A dictionary defining the updated configuration with keys "overwrite", "remove", "add" and "addBefore" each containing a list with the instructions on what should be replaced, removed or added. 86 with open(configurationFile,
"r") as inputFile: fileContent = inputFile.readlines() 89 if "overwrite" in updateInstructions:
91 for instruction
in updateInstructions[
"overwrite"]:
93 decodeInstruction = instruction.split(
"|")
94 if(len(decodeInstruction) > 1):
95 lineToReplace = decodeInstruction[0]
96 newInstruction = instruction[instruction.index(
"|")+1:]
98 lineToReplace = instruction.split()[0]
99 newInstruction = instruction
101 lineOverwritten =
False 102 for iLine
in range(0,len(fileContent)):
103 if fileContent[iLine].startswith(lineToReplace):
104 fileContent[iLine] = newInstruction
105 if not fileContent[iLine].endswith(
"\n"):
106 fileContent[iLine] = fileContent[iLine] +
"\n" 107 lineOverwritten =
True 111 if not lineOverwritten:
112 fileContent.append(newInstruction)
113 if not fileContent[-1].endswith(
"\n"):
114 fileContent[-1] = fileContent[-1] +
"\n" 117 if "remove" in updateInstructions:
118 for instruction
in updateInstructions[
"remove"]:
119 for iLine
in range(0,len(fileContent)):
120 if fileContent[iLine].startswith(instruction):
121 fileContent.pop(iLine)
125 if "add" in updateInstructions:
126 for instruction
in updateInstructions[
"add"]:
127 categories = instruction.split(
".")
128 if len(categories) > 2:
129 category = categories[1]
131 category =
"nonExistent" 132 previousCategory =
"" 136 for iLine
in range(0,len(fileContent)):
137 if fileContent[iLine] ==
"\n" and previousCategory == category:
138 fileContent.insert(iLine, instruction)
139 if not fileContent[iLine].endswith(
"\n"):
140 fileContent[iLine] = fileContent[iLine] +
"\n" 143 elif fileContent[iLine] ==
"\n":
144 previousCategory =
"" 146 newCategories = fileContent[iLine].
split(
".")
147 if len(newCategories) > 2:
148 previousCategory = newCategories[1]
150 previousCategory =
"" 154 fileContent.append(instruction)
155 if not fileContent[-1].endswith(
"\n"):
156 fileContent[-1] = fileContent[-1] +
"\n" 159 if "addBefore" in updateInstructions:
160 for instruction
in updateInstructions[
"addBefore"]:
161 lineBefore = instruction.split(
"|")[0]
162 newInstruction = instruction[instruction.index(
"|")+1:]
164 for iLine
in range(0,len(fileContent)):
165 if fileContent[iLine].startswith(lineBefore):
166 fileContent.insert(iLine,newInstruction)
167 if not fileContent[iLine].endswith(
"\n"):
168 fileContent[iLine] = fileContent[iLine] +
"\n" 175 fileContent.append(newInstruction)
176 if not fileContent[-1].endswith(
"\n"):
177 fileContent[-1] = fileContent[-1] +
"\n" 180 with open(configurationFile,
"w")
as outputFile:
181 outputFile.writelines(fileContent)
190 print(
"Grid proxy is required in most use cases of the tool.")
191 print(
"Please create a proxy via 'voms-proxy-init -voms cms'.")
199 with open(
"{}/src/Alignment/OfflineValidation/bin/example.yaml".
format(os.environ[
"CMSSW_BASE"]),
"r") as exampleFile: config = yaml.load(exampleFile, Loader=yaml.Loader) 200 pprint.pprint(config, width=30) 204 with open(args.config, "r") as configFile: if args.verbose:
205 print(
"Read AllInOne config: '{}'".
format(args.config))
207 if args.config.split(
".")[-1] ==
"json":
208 config = json.load(configFile)
210 elif args.config.split(
".")[-1] ==
"yaml":
211 config = yaml.load(configFile, Loader=yaml.Loader)
214 raise Exception(
"Unknown config extension '{}'. Please use json/yaml format!".
format(args.config.split(
".")[-1]))
218 for path
in fnc.find_and_change(list(), config):
219 if args.verbose
and (
"." in str(path)
or "/" in str(path)):
223 if os.path.isdir(config[
"name"])
and not args.force:
224 raise Exception(
"Validation directory '{}' already exists! Please choose another name for your directory.".
format(config[
"name"]))
226 validationDir = os.path.abspath(config[
"name"])
227 exeDir =
"{}/executables".
format(validationDir)
228 cmsconfigDir =
"{}/cmsConfigs".
format(validationDir)
230 subprocess.call([
"mkdir",
"-p", validationDir] + (([
"-v"]
if args.verbose
else [])))
231 subprocess.call([
"mkdir",
"-p", exeDir] + ([
"-v"]
if args.verbose
else []))
232 subprocess.call([
"mkdir",
"-p", cmsconfigDir] + ([
"-v"]
if args.verbose
else []))
235 subprocess.call([
"cp",
"-f", args.config, validationDir] + ([
"-v"]
if args.verbose
else []))
238 crabTemplateFile = fnc.digest_path(
"$CMSSW_BASE/src/Alignment/OfflineValidation/python/TkAlAllInOneTool/templates/crabTemplate.py")
239 condorTemplateFile = fnc.digest_path(
"$CMSSW_BASE/src/Alignment/OfflineValidation/python/TkAlAllInOneTool/templates/condorTemplate.submit")
240 executableTempleteFile = fnc.digest_path(
"$CMSSW_BASE/src/Alignment/OfflineValidation/python/TkAlAllInOneTool/templates/executableTemplate.sh")
247 for validation
in config[
"validations"]:
248 if validation ==
"GCP":
249 jobs.extend(
GCP.GCP(config, validationDir))
251 elif validation ==
"DMR":
252 jobs.extend(
DMR.DMR(config, validationDir))
254 elif validation ==
"Zmumu":
257 elif validation ==
"PV":
258 jobs.extend(
PV.PV(config, validationDir))
260 elif validation ==
"SplitV":
263 elif validation ==
"JetHT":
265 elif validation ==
"DiMuonV":
267 elif validation ==
"MTS":
268 jobs.extend(
MTS.MTS(config, validationDir))
269 elif validation ==
"PixBary":
275 subprocess.call([
"mkdir",
"-p",
"{}/DAG/".
format(validationDir)] + ([
"-v"]
if args.verbose
else []))
277 with open(
"{}/DAG/dagFile".
format(validationDir),
"w")
as dag:
280 subprocess.call([
"mkdir",
"-p", job[
"dir"]] + ([
"-v"]
if args.verbose
else []))
281 subprocess.call([
"mkdir",
"-p", job[
"config"][
"output"]] + ([
"-v"]
if args.verbose
else []))
282 subprocess.call([
"mkdir",
"-p",
"{}/condor".
format(job[
"dir"])] + ([
"-v"]
if args.verbose
else []))
283 subprocess.call([
"ln",
"-fs", job[
"config"][
"output"],
"{}/output".
format(job[
"dir"])] + ([
"-v"]
if args.verbose
else []))
286 crabConfigurationFile =
"{}/crabConfiguration.py".
format(job[
"dir"])
287 subprocess.call([
"cp", crabTemplateFile, crabConfigurationFile] + ([
"-v"]
if args.verbose
else []))
288 condorSubmitFile =
"{}/condor.sub".
format(job[
"dir"])
289 subprocess.call([
"cp", condorTemplateFile, condorSubmitFile] + ([
"-v"]
if args.verbose
else []))
290 executableFile =
"{}/run.sh".
format(job[
"dir"])
291 subprocess.call([
"cp", executableTempleteFile, executableFile] + ([
"-v"]
if args.verbose
else []))
295 print(
"Forwarding grid proxy to directory {}".
format(job[
"dir"]))
299 subprocess.call(
"cp -f $(which {}) {}".
format(job[
"exe"], exeDir) + (
" -v" if args.verbose
else ""), shell =
True)
300 subprocess.call([
"ln",
"-fs",
"{}/{}".
format(exeDir, job[
"exe"]), job[
"dir"]] + ([
"-v"]
if args.verbose
else []))
301 if "cms-config" in job:
302 cmsConfig = job[
"cms-config"].
split(
"/")[-1]
304 subprocess.call([
"cp",
"-f", job[
"cms-config"],
"{}/{}".
format(cmsconfigDir, cmsConfig)] + ([
"-v"]
if args.verbose
else []))
305 subprocess.call([
"ln",
"-fs",
"{}/{}".
format(cmsconfigDir, cmsConfig),
"{}/validation_cfg.py".
format(job[
"dir"])] + ([
"-v"]
if args.verbose
else []))
308 with open(
"{}/validation.json".
format(job[
"dir"]),
"w")
as jsonFile:
310 print(
"Write local json config: '{}'".
format(
"{}/validation.json".
format(job[
"dir"])))
312 json.dump(job[
"config"], jsonFile, indent=4)
315 executableCustomization = {
"overwrite": [],
"addBefore": []}
317 executableCustomization[
"overwrite"].
append(
"export X509|export X509_USER_PROXY={}".
format(myProxy))
318 executableCustomization[
"overwrite"].
append(
"cd workDir|cd {}".
format(job[
"dir"]))
321 if "exeArguments" in job:
322 executableCustomization[
"overwrite"].
append(
"./cmsRun|./{} {}".
format(job[
"exe"], job[
"exeArguments"]))
324 executableCustomization[
"overwrite"].
append(
"./cmsRun|./{} {}validation.json".
format(job[
"exe"],
"validation_cfg.py config=" if "cms-config" in job
else ""))
327 if "nCondorJobs" in job:
328 executableCustomization[
"addBefore"].
append(
"./{}|JOBNUMBER=${{1:--1}}".
format(job[
"exe"]))
334 subprocess.call([
"chmod",
"a+rx", executableFile] + ([
"-v"]
if args.verbose
else []))
337 condorSubmitCustomization = {
"overwrite": [],
"addBefore": []}
340 condorSubmitCustomization[
"addBefore"].
append(
'+JobFlavour|+environment = "CMSSW_BASE={}"'.
format(fnc.digest_path(
"$CMSSW_BASE")))
343 condorSubmitCustomization[
"overwrite"].
append(
'+JobFlavour = "{}"'.
format(args.job_flavour
if not 'flavour' in job
else job[
'flavour']))
346 if "nCondorJobs" in job:
347 condorSubmitCustomization[
"addBefore"].
append(
"output|arguments = $(ProcID)")
348 condorSubmitCustomization[
"overwrite"].
append(
"output = condor/condor$(ProcID).out")
349 condorSubmitCustomization[
"overwrite"].
append(
"error = condor/condor$(ProcID).err")
350 condorSubmitCustomization[
"overwrite"].
append(
"log = condor/condor$(ProcID).log")
351 condorSubmitCustomization[
"overwrite"].
append(
"queue {}".
format(job[
"nCondorJobs"]))
357 dag.write(
"JOB {} condor.sub DIR {}\n".
format(job[
"name"], job[
"dir"]))
359 if job[
"dependencies"]:
361 dag.write(
"PARENT {} CHILD {}".
format(
" ".
join(job[
"dependencies"]), job[
"name"]))
366 if "crabCustomConfiguration" in job[
"config"]:
371 print(
"DAGman config has been written: '{}'".
format(
"{}/DAG/dagFile".
format(validationDir)))
375 print(
"Enviroment is set up. If you want to submit everything, call 'condor_submit_dag {}/DAG/dagFile'".
format(validationDir))
378 subprocess.call([
"condor_submit_dag",
"{}/DAG/dagFile".
format(validationDir)])
381 if __name__ ==
"__main__":
384 def PixBary(config, validationDir, verbose=False)
def DiMuonV(config, validationDir)
def SplitV(config, validationDir)
def Zmumu(config, validationDir)
def updateConfigurationFile(configurationFile, updateInstructions)
def MTS(config, validationDir)
def forward_proxy(rundir)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
def DMR(config, validationDir)
def split(sequence, size)
static std::string join(char **cmd)
def PV(config, validationDir)
def GCP(config, validationDir)
if(threadIdxLocalY==0 &&threadIdxLocalX==0)
def JetHT(config, validationDir)