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
27 """ Parse user input """ 29 parser = argparse.ArgumentParser(description =
"AllInOneTool for validation of the tracker alignment", formatter_class=argparse.RawTextHelpFormatter)
30 parser.add_argument(
"config", metavar=
'config', type=str, action=
"store", help=
"Global AllInOneTool config (json/yaml format)")
31 parser.add_argument(
"-d",
"--dry", action =
"store_true", help =
"Set up everything, but don't run anything")
32 parser.add_argument(
"-v",
"--verbose", action =
"store_true", help =
"Enable standard output stream")
33 parser.add_argument(
"-e",
"--example", action =
"store_true", help =
"Print example of config in JSON format")
34 parser.add_argument(
"-f",
"--force", action =
"store_true", help =
"Force creation of enviroment, possible overwritten old configuration")
35 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'")
37 return parser.parse_args()
42 """Check if GRID proxy has been initialized.""" 45 with open(os.devnull,
"w")
as dump:
46 subprocess.check_call([
"voms-proxy-info",
"--exists"],
47 stdout = dump, stderr = dump)
48 except subprocess.CalledProcessError:
55 """Forward proxy to location visible from the batch system. 57 - `rundir`: directory for storing the forwarded proxy 59 - Full path to the forwarded proxy 63 print(
"Please create proxy via 'voms-proxy-init -voms cms'.")
67 proxyName =
"{}/.user_proxy".
format(rundir)
68 localProxy = subprocess.check_output([
"voms-proxy-info",
"--path"]).
strip()
69 shutil.copyfile(localProxy, proxyName)
78 """Update a template configuration file with custom configuration 80 - configurationFile: File name for the configuration file that will be updated 81 - 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. 85 with open(configurationFile,
"r") as inputFile: fileContent = inputFile.readlines() 88 if "overwrite" in updateInstructions:
90 for instruction
in updateInstructions[
"overwrite"]:
92 decodeInstruction = instruction.split(
"|")
93 if(len(decodeInstruction) > 1):
94 lineToReplace = decodeInstruction[0]
95 newInstruction = instruction[instruction.index(
"|")+1:]
97 lineToReplace = instruction.split()[0]
98 newInstruction = instruction
100 lineOverwritten =
False 101 for iLine
in range(0,len(fileContent)):
102 if fileContent[iLine].startswith(lineToReplace):
103 fileContent[iLine] = newInstruction
104 if not fileContent[iLine].endswith(
"\n"):
105 fileContent[iLine] = fileContent[iLine] +
"\n" 106 lineOverwritten =
True 110 if not lineOverwritten:
111 fileContent.append(newInstruction)
112 if not fileContent[-1].endswith(
"\n"):
113 fileContent[-1] = fileContent[-1] +
"\n" 116 if "remove" in updateInstructions:
117 for instruction
in updateInstructions[
"remove"]:
118 for iLine
in range(0,len(fileContent)):
119 if fileContent[iLine].startswith(instruction):
120 fileContent.pop(iLine)
124 if "add" in updateInstructions:
125 for instruction
in updateInstructions[
"add"]:
126 categories = instruction.split(
".")
127 if len(categories) > 2:
128 category = categories[1]
130 category =
"nonExistent" 131 previousCategory =
"" 135 for iLine
in range(0,len(fileContent)):
136 if fileContent[iLine] ==
"\n" and previousCategory == category:
137 fileContent.insert(iLine, instruction)
138 if not fileContent[iLine].endswith(
"\n"):
139 fileContent[iLine] = fileContent[iLine] +
"\n" 142 elif fileContent[iLine] ==
"\n":
143 previousCategory =
"" 145 newCategories = fileContent[iLine].
split(
".")
146 if len(newCategories) > 2:
147 previousCategory = newCategories[1]
149 previousCategory =
"" 153 fileContent.append(instruction)
154 if not fileContent[-1].endswith(
"\n"):
155 fileContent[-1] = fileContent[-1] +
"\n" 158 if "addBefore" in updateInstructions:
159 for instruction
in updateInstructions[
"addBefore"]:
160 lineBefore = instruction.split(
"|")[0]
161 newInstruction = instruction[instruction.index(
"|")+1:]
163 for iLine
in range(0,len(fileContent)):
164 if fileContent[iLine].startswith(lineBefore):
165 fileContent.insert(iLine,newInstruction)
166 if not fileContent[iLine].endswith(
"\n"):
167 fileContent[iLine] = fileContent[iLine] +
"\n" 174 fileContent.append(newInstruction)
175 if not fileContent[-1].endswith(
"\n"):
176 fileContent[-1] = fileContent[-1] +
"\n" 179 with open(configurationFile,
"w")
as outputFile:
180 outputFile.writelines(fileContent)
189 print(
"Grid proxy is required in most use cases of the tool.")
190 print(
"Please create a proxy via 'voms-proxy-init -voms cms'.")
198 with open(
"{}/src/Alignment/OfflineValidation/bin/example.yaml".
format(os.environ[
"CMSSW_BASE"]),
"r") as exampleFile: config = yaml.load(exampleFile, Loader=yaml.Loader) 199 pprint.pprint(config, width=30) 203 with open(args.config, "r") as configFile: if args.verbose:
204 print(
"Read AllInOne config: '{}'".
format(args.config))
206 if args.config.split(
".")[-1] ==
"json":
207 config = json.load(configFile)
209 elif args.config.split(
".")[-1] ==
"yaml":
210 config = yaml.load(configFile, Loader=yaml.Loader)
213 raise Exception(
"Unknown config extension '{}'. Please use json/yaml format!".
format(args.config.split(
".")[-1]))
217 for path
in fnc.find_and_change(list(), config):
218 if args.verbose
and (
"." in str(path)
or "/" in str(path)):
222 if os.path.isdir(config[
"name"])
and not args.force:
223 raise Exception(
"Validation directory '{}' already exists! Please choose another name for your directory.".
format(config[
"name"]))
225 validationDir = os.path.abspath(config[
"name"])
226 exeDir =
"{}/executables".
format(validationDir)
227 cmsconfigDir =
"{}/cmsConfigs".
format(validationDir)
229 subprocess.call([
"mkdir",
"-p", validationDir] + (([
"-v"]
if args.verbose
else [])))
230 subprocess.call([
"mkdir",
"-p", exeDir] + ([
"-v"]
if args.verbose
else []))
231 subprocess.call([
"mkdir",
"-p", cmsconfigDir] + ([
"-v"]
if args.verbose
else []))
234 subprocess.call([
"cp",
"-f", args.config, validationDir] + ([
"-v"]
if args.verbose
else []))
237 crabTemplateFile = fnc.digest_path(
"$CMSSW_BASE/src/Alignment/OfflineValidation/python/TkAlAllInOneTool/templates/crabTemplate.py")
238 condorTemplateFile = fnc.digest_path(
"$CMSSW_BASE/src/Alignment/OfflineValidation/python/TkAlAllInOneTool/templates/condorTemplate.submit")
239 executableTempleteFile = fnc.digest_path(
"$CMSSW_BASE/src/Alignment/OfflineValidation/python/TkAlAllInOneTool/templates/executableTemplate.sh")
246 for validation
in config[
"validations"]:
247 if validation ==
"GCP":
248 jobs.extend(
GCP.GCP(config, validationDir))
250 elif validation ==
"DMR":
251 jobs.extend(
DMR.DMR(config, validationDir))
253 elif validation ==
"Zmumu":
256 elif validation ==
"PV":
257 jobs.extend(
PV.PV(config, validationDir))
259 elif validation ==
"SplitV":
262 elif validation ==
"JetHT":
264 elif validation ==
"DiMuonV":
266 elif validation ==
"MTS":
267 jobs.extend(
MTS.MTS(config, validationDir))
272 subprocess.call([
"mkdir",
"-p",
"{}/DAG/".
format(validationDir)] + ([
"-v"]
if args.verbose
else []))
274 with open(
"{}/DAG/dagFile".
format(validationDir),
"w")
as dag:
277 subprocess.call([
"mkdir",
"-p", job[
"dir"]] + ([
"-v"]
if args.verbose
else []))
278 subprocess.call([
"mkdir",
"-p", job[
"config"][
"output"]] + ([
"-v"]
if args.verbose
else []))
279 subprocess.call([
"mkdir",
"-p",
"{}/condor".
format(job[
"dir"])] + ([
"-v"]
if args.verbose
else []))
280 subprocess.call([
"ln",
"-fs", job[
"config"][
"output"],
"{}/output".
format(job[
"dir"])] + ([
"-v"]
if args.verbose
else []))
283 crabConfigurationFile =
"{}/crabConfiguration.py".
format(job[
"dir"])
284 subprocess.call([
"cp", crabTemplateFile, crabConfigurationFile] + ([
"-v"]
if args.verbose
else []))
285 condorSubmitFile =
"{}/condor.sub".
format(job[
"dir"])
286 subprocess.call([
"cp", condorTemplateFile, condorSubmitFile] + ([
"-v"]
if args.verbose
else []))
287 executableFile =
"{}/run.sh".
format(job[
"dir"])
288 subprocess.call([
"cp", executableTempleteFile, executableFile] + ([
"-v"]
if args.verbose
else []))
292 print(
"Forwarding grid proxy to directory {}".
format(job[
"dir"]))
296 subprocess.call(
"cp -f $(which {}) {}".
format(job[
"exe"], exeDir) + (
" -v" if args.verbose
else ""), shell =
True)
297 subprocess.call([
"ln",
"-fs",
"{}/{}".
format(exeDir, job[
"exe"]), job[
"dir"]] + ([
"-v"]
if args.verbose
else []))
298 if "cms-config" in job:
299 cmsConfig = job[
"cms-config"].
split(
"/")[-1]
301 subprocess.call([
"cp",
"-f", job[
"cms-config"],
"{}/{}".
format(cmsconfigDir, cmsConfig)] + ([
"-v"]
if args.verbose
else []))
302 subprocess.call([
"ln",
"-fs",
"{}/{}".
format(cmsconfigDir, cmsConfig),
"{}/validation_cfg.py".
format(job[
"dir"])] + ([
"-v"]
if args.verbose
else []))
305 with open(
"{}/validation.json".
format(job[
"dir"]),
"w")
as jsonFile:
307 print(
"Write local json config: '{}'".
format(
"{}/validation.json".
format(job[
"dir"])))
309 json.dump(job[
"config"], jsonFile, indent=4)
312 executableCustomization = {
"overwrite": [],
"addBefore": []}
314 executableCustomization[
"overwrite"].
append(
"export X509|export X509_USER_PROXY={}".
format(myProxy))
315 executableCustomization[
"overwrite"].
append(
"cd workDir|cd {}".
format(job[
"dir"]))
318 if "exeArguments" in job:
319 executableCustomization[
"overwrite"].
append(
"./cmsRun|./{} {}".
format(job[
"exe"], job[
"exeArguments"]))
321 executableCustomization[
"overwrite"].
append(
"./cmsRun|./{} {}validation.json".
format(job[
"exe"],
"validation_cfg.py config=" if "cms-config" in job
else ""))
324 if "nCondorJobs" in job:
325 executableCustomization[
"addBefore"].
append(
"./{}|JOBNUMBER=${{1:--1}}".
format(job[
"exe"]))
331 subprocess.call([
"chmod",
"a+rx", executableFile] + ([
"-v"]
if args.verbose
else []))
334 condorSubmitCustomization = {
"overwrite": [],
"addBefore": []}
337 condorSubmitCustomization[
"addBefore"].
append(
'+JobFlavour|+environment = "CMSSW_BASE={}"'.
format(fnc.digest_path(
"$CMSSW_BASE")))
340 condorSubmitCustomization[
"overwrite"].
append(
'+JobFlavour = "{}"'.
format(args.job_flavour
if not 'flavour' in job
else job[
'flavour']))
343 if "nCondorJobs" in job:
344 condorSubmitCustomization[
"addBefore"].
append(
"output|arguments = $(ProcID)")
345 condorSubmitCustomization[
"overwrite"].
append(
"output = condor/condor$(ProcID).out")
346 condorSubmitCustomization[
"overwrite"].
append(
"error = condor/condor$(ProcID).err")
347 condorSubmitCustomization[
"overwrite"].
append(
"log = condor/condor$(ProcID).log")
348 condorSubmitCustomization[
"overwrite"].
append(
"queue {}".
format(job[
"nCondorJobs"]))
354 dag.write(
"JOB {} condor.sub DIR {}\n".
format(job[
"name"], job[
"dir"]))
356 if job[
"dependencies"]:
358 dag.write(
"PARENT {} CHILD {}".
format(
" ".
join(job[
"dependencies"]), job[
"name"]))
363 if "crabCustomConfiguration" in job[
"config"]:
368 print(
"DAGman config has been written: '{}'".
format(
"{}/DAG/dagFile".
format(validationDir)))
372 print(
"Enviroment is set up. If you want to submit everything, call 'condor_submit_dag {}/DAG/dagFile'".
format(validationDir))
375 subprocess.call([
"condor_submit_dag",
"{}/DAG/dagFile".
format(validationDir)])
378 if __name__ ==
"__main__":
381
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)