28 responsiblePerson =
"youzhou@email.arizona.edu"
29 maillist = responsiblePerson
31 CoolMergeByDefault =
False
37 print (
'updating file list')
39 outFile =
open(oldListPath,
'w')
40 outFile.write(newList)
46 def runCalib(calType, runNumber,workDir,castorCopyCmd):
49 scriptDir =
'${HOME}/CSC/run/'
50 if calType ==
'pulser':
51 calibScript = scriptDir +
'CscCalcSlopeMon.py'
52 dbScript = scriptDir +
'cscWritePSlopeCool.py'
53 webDir =
'${HOME}/www/csc/pulser'
54 runListFile =
"pulserRunList.pickle"
56 elif( calType ==
'ped'):
57 calibScript = scriptDir +
'CscCalcPedMon.py'
58 dbScript = scriptDir +
'cscWritePedRefCool.py'
59 onlDbFile = scriptDir +
'online.cal'
60 webDir =
'${HOME}/www/csc/ped'
61 webPageUrl =
'https://atlas-csc-calib.web.cern.ch/atlas-csc-calib/ped/pedRun_' +runNumber
62 runListFile =
"pedRunList.pickle"
65 outputDir = workDir +
"/CalibResults"
66 bsDir = workDir +
"/Bytestream"
68 print (
'outputDir = ' + outputDir)
72 emailMessage =
'Finished ' + calType +
' calibration on run number ' + runNumber
73 emailMessage +=
'. Output in ' + outputDir +
'.'
74 emailMessage +=
'\\nAnd website at:\\n'
75 emailMessage += webPageUrl
78 goodEmailSubject =
'[CSC CALIB PROC]: SUCCESS with ' + calType +
'calib run' + runNumber
79 badEmailSubject =
'[CSC CALIB PROC]: PROBLEMS with ' + calType +
'calib run' + runNumber
82 bashFilePath = workDir+
'/CscCalib_' + calType +
'_' + runNumber +
'.sh'
84 bsubCmd =
'cd ' + outputDir +
';bsub -q 2nd -R "type==SLC5_64&&mem>420" ' + bashFilePath
86 bashFileContents =
"#!/bin/bash\n"
87 bashFileContents +=
"#To resubmit this job, submit it to the atlasmuonqueu like so:\n#"
88 bashFileContents += bsubCmd +
"\n"
89 bashFileContents +=
"source ~/CSC/CscSetup.sh\n"
90 bashFileContents +=
"\n"
91 bashFileContents +=
"resultDir=\"" + outputDir +
"\"\n"
92 bashFileContents +=
'bytestreamDir="' + bsDir +
'"\n'
93 bashFileContents +=
'maillist="' + maillist +
'"\n'
94 bashFileContents +=
'webSiteDir="' + webDir +
'"\n'
96 calFilePrefix=
"${resultDir}/" + runNumber
97 inputPattern =
"${bytestreamDir}/*.data"
99 calibCommand =
'echo "Running calibration"\n' \
100 +
'mkdir ${resultDir}\n' \
101 +
'athena.py -c "outputPre=\'' + calFilePrefix \
102 +
'\';inputOnlCalibFile=\'' +onlDbFile \
103 +
'\';inputPat=\'' + inputPattern \
104 +
'\';reportPrefix=\'' + emailMessage \
109 goodEmailCommand =
' mail -s "' + goodEmailSubject +
'" $maillist < ' + calFilePrefix +
"CalibReport.txt"
110 badEmailCommand =
' mail -s "' + badEmailSubject +
'" $maillist < ' + calFilePrefix +
"CalibReport.txt"
114 infile =
open(runListFile,
"rb")
115 runList = pickle.load(infile)
122 if(runNumber
in runList):
123 print (
"Mailing message")
124 message =[
"mail",
"-s",\
125 '"New castor run directory found for previously processed run ' +
str(runNumber) +
'"',\
128 "runAlreadyProcessed.mail"]
130 subprocess.call(message)
134 highestRun = runList[-1]
136 isRunNumberConflict =
False
139 if(highestRun > runNumber):
143 subprocess.call([
"mail",
"-s",\
144 "[CSC CALIB PROC] Wrong run number ordering on run " +
str(runNumber) \
145 +
"! Human intervension required!",\
148 "runNumberConflict.mail"]\
150 isRunNumberConflict =
True
153 runList += [runNumber]
154 outfile =
open(runListFile,
"wb")
155 pickle.dump(runList,outfile)
160 subprocess.call([
'touch',
'/afs/cern.ch/user/m/muoncali/CSC/run/runningCalibration' + runNumber])
163 DbCommand =
'athena.py -c "input=\'' + calFilePrefix+
'.cal\';output=\'' \
164 + calFilePrefix +
'.db\';IOVRunStart=int(\'' + highestRun +
'\')" ' + dbScript
180 UploadCommand +=
'/afs/cern.ch/user/a/atlcond/utils/AtlCoolMerge.py ' \
182 if(
not CoolMergeByDefault
or isRunNumberConflict):
183 UploadCommand +=
" --noexec "
185 UploadCommand +=
"--comment=\'Automated reference update from " + calType \
186 +
' run ' + runNumber +
' to IOV starting at ' + highestRun +
"' " \
187 + calFilePrefix +
'.db' \
188 +
' COMP200 ATLAS_COOLWRITE ATLAS_COOLOFL_CSC_W WCOOLOFL4CSC17 '
190 WebSiteCommand =
'\nfs sa ${resultDir} webserver:afs read\n'
191 WebSiteCommand +=
'cd $resultDir\n'
192 WebSiteCommand +=
'ln -s ${resultDir} ${webSiteDir}/pedRun_' + runNumber +
'\n'
193 WebSiteCommand +=
'MakeCscPedSite.exe ' + runNumber +
'.root ' + runNumber +
'.cal_online\n'
198 bashFileContents +=
'\ncd ' + workDir +
'\n' \
199 +
"#Copying files from castor#\n" \
202 +
"#Running calibration (and calib monitoring)\n"\
203 +
"#, resulting in .cal file and status report\n"\
204 + calibCommand +
'\n' \
206 +
"#Athena job to transform *.cal file to *.db file.\n"\
208 +
"#Python utility to upload *.db file to database. When entering by\n"\
209 +
"#hand, I recomend removing '--batch' flag so you can check puposed\n"\
210 +
"#operations before submision to database\n"\
211 + UploadCommand +
'\n' \
212 +
'#Check if AllCalibMonGood file was created, which means that\n'\
213 +
'#this run passed acceptable criteria in the calibration monitoring\n'\
214 +
'if [ -a AllCalibMonGood ]; then\n' \
215 + t1 +
"#Email list that the calibration looks good\n"\
216 + t1 + goodEmailCommand +
'\n' \
217 + t1 +
"################################################################\n"\
218 + t1 +
"#Execute next two commands if you want to submit database entry#\n"\
219 + t1 +
"#Useful if these steps were skipped due to suspicious behaviour#\n"\
220 + t1 +
"#during calibration. #\n"\
221 + t1 +
"###############################################################\n"\
225 + t1 +
"#Suspicious behaviour in calibration. Notify mail list of this fact\n"\
226 + t1 + badEmailCommand +
'\n' \
229 +
'#Always create website'\
230 + WebSiteCommand +
'\n' \
231 +
'rm -rf $bytestreamDir\n' \
232 +
'rm -rf ' + scriptDir +
"runningCalibration" + runNumber +
'\n'
235 print (
"Printing bash file to: " +bashFilePath)
236 bashFile =
open(bashFilePath,
'w')
237 bashFile.write(bashFileContents)
241 os.system(
'chmod +x ' + bashFilePath)
242 bsubsMessage = os.popen(bsubCmd).
read()
245 emailMessage =
'Starting ' + calType +
' calibration on run number ' + runNumber
246 emailSubject =
'[CSC CALIB PROC]: ' + emailMessage
247 emailMessage +=
'\nbsubs output:\n' + bsubsMessage
248 os.system(
'echo "' + emailMessage +
'" | mail -s "' + emailSubject +
'" ' + maillist)
256 calType = sys.argv[1]
257 if calType ==
'pulser':
258 calibFileDir =
'/castor/cern.ch/user/l/lampen/CalibRunTest/slope/'
259 oldListFilePath =
'/afs/cern.ch/user/m/muoncali/CSC/run/pulserList.txt'
260 outputDir =
'/afs/cern.ch/user/m/muoncali/w0/CSC/runs/pulser/pulser'
261 elif calType ==
'ped':
262 calibFileDir =
'/castor/cern.ch/grid/atlas/DAQ/muon/csc/'
263 oldListFilePath =
'/afs/cern.ch/user/m/muoncali/CSC/run/pedDirList.txt'
264 outputDir =
'/afs/cern.ch/user/m/muoncali/w0/CSC/runs/ped/ped'
265 calibRe = re.compile(
'data1.*_calib.*calibration_pedCSC\\.daq\\.RAW.*\\.data')
267 print (
'Need to specify pulser or ped')
273 testFile = glob.glob(
"/afs/cern.ch/user/m/muoncali/CSC/run/runningCalibration*")
275 print (
'already running: ' +
str(testFile))
280 print (
'rfdir ' + calibFileDir)
281 currentLs = os.popen(
'rfdir ' + calibFileDir).
read()
283 os.popen(
'touch testing')
286 inFile =
open(oldListFilePath,
'r')
287 oldLs = inFile.read()
291 print (
'checking for changes')
294 now = datetime.datetime.now()
298 if(oldLs != currentLs):
299 print (
'There has been a change')
300 currentDirList = currentLs.split(
'\n')
301 oldDirList = oldLs.split(
'\n')
306 for Dir
in currentDirList:
308 if Dir
not in oldDirList:
309 print (
"**********************************************************")
310 splitDir = Dir.split()
312 DirName =splitDir[-1]
315 timediff = today - day
316 if(timediff > 7
or timediff < -23):
319 print (
"Found old dir " + DirName +
", but its over at least a week old, so we're skipping it")
325 print (
"day is " +
str(day))
328 cmd =
'rfdir ' + calibFileDir + DirName
331 nFiles = len(fileList) -1
332 print (
"found " +
str(nFiles) +
" files")
337 outputDirFull = outputDir +
'Run_' + runNumber
338 print (
'outputDirFull is ' + outputDirFull)
345 castorCopyCmd =
"mkdir ${bytestreamDir}"
346 for file
in fileList:
347 fileName = (file.split(
' '))[-1]
349 print (
"fileName: " +fileName)
350 ThisCalibDir = re.match(calibRe,fileName)
351 if(nFiles < numFilesToRun):
352 print (
"only " +
str(nFiles) +
" files. Breaking.")
354 print (
"There is a calib dir, but it only has " +
str(nFiles)
355 +
" file. Will not process.")
356 updateRunList =
False
359 fullPath = calibFileDir + DirName +
'/' + fileName
360 castorCopyCmd +=
"\nxrdcp root://castoratlas/" + fullPath +
" ${bytestreamDir}"
365 print (
"found " +
str(nFiles) +
" files")
368 if(nFiles >= numFilesToRun):
371 updateRunList =
False
372 print (
"Found new calibration directory to run on (" +DirName +
"), but already running on " + runningDir)
374 print (
'running on ' + DirName)
376 if(nFiles > numFilesToRun):
377 print (
'WARNING! Found ' +
str(nFiles) +
' calib files, when only ' +
str(numFilesToRun) +
' were expected!')
380 if( os.path.exists(outputDirFull)):
381 print (
"There is already a directory for run number " + runNumber)
382 print (
"Will not run on this pedestal run")
387 print (castorCopyCmd)
390 os.makedirs(outputDirFull+
"/CalibResults")
392 runCalib(calType, runNumber, outputDirFull, castorCopyCmd)
394 print(
'Launched job, but will continue to check if we have more runs to run on later')
396 updateRunList =
False
403 print (
"No unprocessed or currently being processed calibration runs. Will update run list.")
406 print (
"NOT updating run list")
409 print (
'No changes between old and new runs')