3 Submits per run Primary Vertex Resoltion Alignment validation using the split vertex method, 6 submitPVResolutionJobs.py -i PVResolutionExample.ini -D /JetHT/Run2018C-TkAlMinBias-12Nov2019_UL2018-v2/ALCARECO 9 from __future__
import print_function
11 __author__ =
'Marco Musich' 12 __copyright__ =
'Copyright 2020, CERN CMS' 13 __credits__ = [
'Ernesto Migliore',
'Salvatore Di Guida']
14 __license__ =
'Unknown' 15 __maintainer__ =
'Marco Musich' 16 __email__ =
'marco.musich@cern.ch' 29 from subprocess
import Popen, PIPE
30 import multiprocessing
31 from optparse
import OptionParser
32 import os, shlex, shutil, getpass
33 import configparser
as ConfigParser
35 CopyRights =
'##################################\n' 36 CopyRights +=
'# submitPVVResolutioJobs.py #\n' 37 CopyRights +=
'# marco.musich@cern.ch #\n' 38 CopyRights +=
'# October 2020 #\n' 39 CopyRights +=
'##################################\n' 44 p = subprocess.Popen(*args, **kwargs)
45 stdout, stderr = p.communicate()
46 return p.returncode, stdout, stderr
51 """Check if GRID proxy has been initialized.""" 54 with open(os.devnull,
"w")
as dump:
55 subprocess.check_call([
"voms-proxy-info",
"--exists"],
56 stdout = dump, stderr = dump)
57 except subprocess.CalledProcessError:
64 """Forward proxy to location visible from the batch system. 66 - `rundir`: directory for storing the forwarded proxy 70 print(
"Please create proxy via 'voms-proxy-init -voms cms -rfc'.")
73 local_proxy = subprocess.check_output([
"voms-proxy-info",
"--path"]).
strip()
74 shutil.copyfile(local_proxy, os.path.join(rundir,
".user_proxy"))
80 returns the list of list files associated with a given dataset for a certain run 82 cmd2 =
' dasgoclient -limit=0 -query \'file run='+blob[0]+
' dataset='+blob[1]+
'\'' 83 q = Popen(cmd2 , shell=
True, stdout=PIPE, stderr=PIPE)
84 out, err = q.communicate()
85 outputList = out.decode().
split(
'\n')
92 """Writes 'job.submit' file in `path`. 94 - `path`: job directory 95 - `script`: script to be executed 96 - `proxy_path`: path to proxy (only used in case of requested proxy forward) 99 job_submit_template=
"""\ 101 executable = {script:s} 102 output = {jobm:s}/{out:s}.out 103 error = {jobm:s}/{out:s}.err 104 log = {jobm:s}/{out:s}.log 105 transfer_output_files = "" 106 +JobFlavour = "{flavour:s}" 109 if proxy_path
is not None:
110 job_submit_template +=
"""\ 111 +x509userproxy = "{proxy:s}" 114 job_submit_file = os.path.join(path,
"job_"+name+
".submit")
115 with open(job_submit_file,
"w")
as f:
116 f.write(job_submit_template.format(script = os.path.join(path,name+
"_$(ProcId).sh"),
117 out = name+
"_$(ProcId)",
118 jobm = os.path.abspath(path),
119 flavour =
"tomorrow",
123 return job_submit_file
128 """Expects something like 129 +-------+------+--------+--------+-------------------+------------------+ 130 | nfill | nrun | nls | ncms | totdelivered(/fb) | totrecorded(/fb) | 131 +-------+------+--------+--------+-------------------+------------------+ 132 | 73 | 327 | 142418 | 138935 | 19.562 | 18.036 | 133 +-------+------+--------+--------+-------------------+------------------+ 134 And extracts the total recorded luminosity (/b). 145 output = subprocess.check_output([homedir+
"/.local/bin/brilcalc",
"lumi",
"-b",
"STABLE BEAMS",
"-u",
"/pb",
"--begin",
str(minRun),
"--end",
str(maxRun),
"--output-style",
"csv"])
147 warnings.warn(
'ATTENTION! Impossible to query the BRIL DB!')
151 print(
"INSIDE GET LUMINOSITY")
154 for line
in output.decode().
split(
"\n"):
155 if (
"#" not in line):
156 runToCache = line.split(
",")[0].
split(
":")[0]
157 lumiToCache = line.split(
",")[-1].
replace(
"\r",
"")
160 myCachedLumi[runToCache] = lumiToCache
170 with open(jsonfile,
'r') as myJSON: jsonDATA = json.load(myJSON) 171 return (run
in jsonDATA)
173 warnings.warn(
'ATTENTION! Impossible to find lumi mask! All runs will be used.')
180 for section
in config.sections():
181 dictionary[section] = {}
182 for option
in config.options(section):
183 dictionary[section][option] = config.get(section, option)
188 def batchScriptCERN(theCMSSW_BASE, cfgdir, runindex, eosdir, lumiToRun, key, config, tkCollection, isUnitTest=False):
190 '''prepare the batch script, to run on HTCondor''' 191 script =
"""#!/bin/bash 192 #source /afs/cern.ch/cms/caf/setup.sh 193 CMSSW_DIR={CMSSW_BASE_DIR}/src/Alignment/OfflineValidation/test 194 echo "the mother directory is $CMSSW_DIR" 195 export X509_USER_PROXY=$CMSSW_DIR/.user_proxy 196 #OUT_DIR=$CMSSW_DIR/harvest ## for local storage 198 LOG_DIR=$CMSSW_DIR/out 201 eval `scram runtime -sh` 203 cp -pr {CFGDIR}/PrimaryVertexResolution_{KEY}_{runindex}_cfg.py . 204 cmsRun PrimaryVertexResolution_{KEY}_{runindex}_cfg.py TrackCollection={TRKS} GlobalTag={GT} lumi={LUMITORUN} {REC} {EXT} >& log_{KEY}_run{runindex}.out 206 """.
format(CMSSW_BASE_DIR=theCMSSW_BASE,
213 GT=config[
'globaltag'],
214 EXT=
"external="+config[
'external']
if 'external' in config.keys()
else "",
215 REC=
"records="+config[
'records']
if 'records' in config.keys()
else "")
218 script +=
"""for payloadOutput in $(ls *root ); do xrdcp -f $payloadOutput root://eoscms/$OUT_DIR/pvresolution_{KEY}_{runindex}.root ; done 219 tar czf log_{KEY}_run{runindex}.tgz log_{KEY}_run{runindex}.out 220 for logOutput in $(ls *tgz ); do cp $logOutput $LOG_DIR/ ; done 221 """.
format(KEY=key, runindex=runindex)
231 for dir
in out_path.split(
'/'):
232 newpath=os.path.join(newpath,dir)
234 if newpath.find(
'test_out') > 0:
235 command=
"eos mkdir "+newpath
236 p = subprocess.Popen(command,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
237 (out, err) = p.communicate()
242 command2=
"eos ls "+out_path
243 p = subprocess.Popen(command2,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
244 (out, err) = p.communicate()
253 desc=
"""This is a description of %prog.""" 254 parser = OptionParser(description=desc,version=
'%prog version 0.1')
255 parser.add_option(
'-s',
'--submit', help=
'job submitted', dest=
'submit', action=
'store_true', default=
False)
256 parser.add_option(
'-j',
'--jobname', help=
'task name', dest=
'taskname', action=
'store', default=
'myTask')
257 parser.add_option(
'-i',
'--init', help=
'ini file', dest=
'iniPathName', action=
'store', default=
"default.ini")
258 parser.add_option(
'-b',
'--begin', help=
'starting point', dest=
'start', action=
'store', default=
'1')
259 parser.add_option(
'-e',
'--end', help=
'ending point', dest=
'end', action=
'store', default=
'999999')
260 parser.add_option(
'-D',
'--Dataset', help=
'dataset to run upon', dest=
'DATASET', action=
'store', default=
'/StreamExpressAlignment/Run2017F-TkAlMinBias-Express-v1/ALCARECO')
261 parser.add_option(
'-v',
'--verbose', help=
'verbose output', dest=
'verbose', action=
'store_true', default=
False)
262 parser.add_option(
'-u',
'--unitTest',help=
'unit tests?', dest=
'isUnitTest', action=
'store_true', default=
False)
263 (opts, args) = parser.parse_args()
266 print(
'\n'+CopyRights)
268 input_CMSSW_BASE = os.environ.get(
'CMSSW_BASE')
272 USER = os.environ.get(
'USER')
273 HOME = os.environ.get(
'HOME')
274 eosdir=os.path.join(
"/store/group/alca_trackeralign",USER,
"test_out",opts.taskname)
278 print(
"Not going to create EOS folder. -s option has not been chosen")
283 config = ConfigParser.ConfigParser()
284 config.read(opts.iniPathName)
285 except ConfigParser.MissingSectionHeaderError
as e:
286 raise WrongIniFormatError(e)
288 print(
"Parsed the following configuration \n\n")
290 pprint.pprint(inputDict)
293 raise SystemExit(
"\n\n ERROR! Could not parse any input file, perhaps you are submitting this from the wrong folder? \n\n")
299 runs =
get_status_output(
"dasgoclient -query='run dataset="+opts.DATASET+
"'",shell=
True, stdout=PIPE, stderr=PIPE)[1].
decode().
split(
"\n")
302 print(
"\n\n Will run on the following runs: \n",runs)
304 if(
not os.path.exists(
"cfg")):
305 os.system(
"mkdir cfg")
306 os.system(
"mkdir BASH")
307 os.system(
"mkdir harvest")
308 os.system(
"mkdir out")
311 bashdir = os.path.join(cwd,
"BASH")
312 cfgdir = os.path.join(cwd,
"cfg")
321 print(
"|| WARNING: won't run on any run, probably DAS returned an empty query,\n|| but that's fine because this is a unit test!")
326 raise Exception(
'Will not run on any run.... please check again the configuration')
329 myLumiDB =
getLuminosity(HOME,runs[0],runs[-1],
True,opts.verbose)
332 pprint.pprint(myLumiDB)
334 lumimask = inputDict[
"Input"][
"lumimask"]
335 print(
"\n\n Using JSON file:",lumimask)
337 tkCollection = inputDict[
"Input"][
"trackcollection"]
338 print(
"\n\n Using trackCollection:", tkCollection)
341 print(
"\n\n First run:",opts.start,
"last run:",opts.end)
344 if (
int(run)<
int(opts.start)
or int(run)>
int(opts.end)):
345 print(
"excluding run",run)
352 print(
"'======> taking run",run)
353 mytuple.append((run,opts.DATASET))
357 pool = multiprocessing.Pool(processes=20)
358 count = pool.map(getFilesForRun,mytuple)
361 print(
"printing count")
365 file_info = dict(
zip([run
for run, _
in mytuple], count))
368 print(
"printing file_info")
369 pprint.pprint(file_info)
377 if (
int(run)<
int(opts.start)
or int(run)>
int(opts.end)):
378 print(
"excluding",run)
382 print(
"=====> excluding run:",run)
386 files = file_info[run]
391 listOfFiles=listOfFiles+
"\""+
str(ffile)+
"\"," 397 if (run)
in myLumiDB:
398 theLumi = myLumiDB[run]
399 print(
"run",run,
" int. lumi:",theLumi,
"/pb")
401 print(
"=====> COULD NOT FIND LUMI, setting default = 1/pb")
403 print(
"run",run,
" int. lumi:",theLumi,
"/pb")
406 for key, value
in inputDict.items():
411 key = key.split(
":", 1)[1]
412 print(
"dealing with",key)
414 os.system(
"cp "+input_CMSSW_BASE+
"/src/Alignment/OfflineValidation/test/PrimaryVertexResolution_templ_cfg.py ./cfg/PrimaryVertexResolution_"+key+
"_"+run+
"_cfg.py")
415 os.system(
"sed -i 's|XXX_FILES_XXX|"+listOfFiles+
"|g' "+cwd+
"/cfg/PrimaryVertexResolution_"+key+
"_"+run+
"_cfg.py")
416 os.system(
"sed -i 's|XXX_RUN_XXX|"+run+
"|g' "+cwd+
"/cfg/PrimaryVertexResolution_"+key+
"_"+run+
"_cfg.py")
417 os.system(
"sed -i 's|YYY_KEY_YYY|"+key+
"|g' "+cwd+
"/cfg/PrimaryVertexResolution_"+key+
"_"+run+
"_cfg.py")
419 scriptFileName = os.path.join(bashdir,
"batchHarvester_"+key+
"_"+
str(count-1)+
".sh")
420 scriptFile = open(scriptFileName,
'w')
421 scriptFile.write(
batchScriptCERN(input_CMSSW_BASE,cfgdir,run,eosdir,theLumi,key,value,tkCollection,opts.isUnitTest))
426 for key, value
in inputDict.items():
430 key = key.split(
":", 1)[1]
433 os.system(
"chmod u+x "+bashdir+
"/*.sh")
436 submissionCommand =
"condor_submit "+job_submit_file
438 os.system(submissionCommand)
441 if __name__ ==
"__main__":
443 def isInJSON(run, jsonfile)
def get_status_output(args, kwargs)
def getLuminosity(homedir, minRun, maxRun, isRunBased, verbose)
ALPAKA_FN_HOST_ACC ALPAKA_FN_INLINE constexpr float zip(ConstView const &tracks, int32_t i)
def replace(string, replacements)
def mkdir_eos(out_path)
method to create recursively directories on EOS
def forward_proxy(rundir)
def batchScriptCERN(theCMSSW_BASE, cfgdir, runindex, eosdir, lumiToRun, key, config, tkCollection, isUnitTest=False)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
def split(sequence, size)
bool decode(bool &, std::string_view)
if(threadIdxLocalY==0 &&threadIdxLocalX==0)
def write_HTCondor_submit_file(path, name, nruns, proxy_path=None)