4 from __future__
import print_function
29 responsiblePerson =
"youzhou@email.arizona.edu"
30 maillist = responsiblePerson
32 CoolMergeByDefault =
False
38 print (
'updating file list')
40 outFile =
open(oldListPath,
'w')
41 outFile.write(newList)
47 def runCalib(calType, runNumber,workDir,castorCopyCmd):
50 scriptDir =
'${HOME}/CSC/run/'
51 if calType ==
'pulser':
52 calibScript = scriptDir +
'CscCalcSlopeMon.py'
53 dbScript = scriptDir +
'cscWritePSlopeCool.py'
54 webDir =
'${HOME}/www/csc/pulser'
55 runListFile =
"pulserRunList.pickle"
57 elif( calType ==
'ped'):
58 calibScript = scriptDir +
'CscCalcPedMon.py'
59 dbScript = scriptDir +
'cscWritePedRefCool.py'
60 onlDbFile = scriptDir +
'online.cal'
61 webDir =
'${HOME}/www/csc/ped'
62 webPageUrl =
'https://atlas-csc-calib.web.cern.ch/atlas-csc-calib/ped/pedRun_' +runNumber
63 runListFile =
"pedRunList.pickle"
66 outputDir = workDir +
"/CalibResults"
67 bsDir = workDir +
"/Bytestream"
69 print (
'outputDir = ' + outputDir)
73 emailMessage =
'Finished ' + calType +
' calibration on run number ' + runNumber
74 emailMessage +=
'. Output in ' + outputDir +
'.'
75 emailMessage +=
'\\nAnd website at:\\n'
76 emailMessage += webPageUrl
79 goodEmailSubject =
'[CSC CALIB PROC]: SUCCESS with ' + calType +
'calib run' + runNumber
80 badEmailSubject =
'[CSC CALIB PROC]: PROBLEMS with ' + calType +
'calib run' + runNumber
83 bashFilePath = workDir+
'/CscCalib_' + calType +
'_' + runNumber +
'.sh'
85 bsubCmd =
'cd ' + outputDir +
';bsub -q 2nd -R "type==SLC5_64&&mem>420" ' + bashFilePath
87 bashFileContents =
"#!/bin/bash\n"
88 bashFileContents +=
"#To resubmit this job, submit it to the atlasmuonqueu like so:\n#"
89 bashFileContents += bsubCmd +
"\n"
90 bashFileContents +=
"source ~/CSC/CscSetup.sh\n"
91 bashFileContents +=
"\n"
92 bashFileContents +=
"resultDir=\"" + outputDir +
"\"\n"
93 bashFileContents +=
'bytestreamDir="' + bsDir +
'"\n'
94 bashFileContents +=
'maillist="' + maillist +
'"\n'
95 bashFileContents +=
'webSiteDir="' + webDir +
'"\n'
97 calFilePrefix=
"${resultDir}/" + runNumber
98 inputPattern =
"${bytestreamDir}/*.data"
100 calibCommand =
'echo "Running calibration"\n' \
101 +
'mkdir ${resultDir}\n' \
102 +
'athena.py -c "outputPre=\'' + calFilePrefix \
103 +
'\';inputOnlCalibFile=\'' +onlDbFile \
104 +
'\';inputPat=\'' + inputPattern \
105 +
'\';reportPrefix=\'' + emailMessage \
110 goodEmailCommand =
' mail -s "' + goodEmailSubject +
'" $maillist < ' + calFilePrefix +
"CalibReport.txt"
111 badEmailCommand =
' mail -s "' + badEmailSubject +
'" $maillist < ' + calFilePrefix +
"CalibReport.txt"
115 infile =
open(runListFile,
"rb")
116 runList = pickle.load(infile)
123 if(runNumber
in runList):
124 print (
"Mailing message")
125 message =[
"mail",
"-s",\
126 '"New castor run directory found for previously processed run ' +
str(runNumber) +
'"',\
129 "runAlreadyProcessed.mail"]
131 subprocess.call(message)
135 highestRun = runList[-1]
137 isRunNumberConflict =
False
140 if(highestRun > runNumber):
144 subprocess.call([
"mail",
"-s",\
145 "[CSC CALIB PROC] Wrong run number ordering on run " +
str(runNumber) \
146 +
"! Human intervension required!",\
149 "runNumberConflict.mail"]\
151 isRunNumberConflict =
True
154 runList += [runNumber]
155 outfile =
open(runListFile,
"wb")
156 pickle.dump(runList,outfile)
161 subprocess.call([
'touch',
'/afs/cern.ch/user/m/muoncali/CSC/run/runningCalibration' + runNumber])
164 DbCommand =
'athena.py -c "input=\'' + calFilePrefix+
'.cal\';output=\'' \
165 + calFilePrefix +
'.db\';IOVRunStart=int(\'' + highestRun +
'\')" ' + dbScript
181 UploadCommand +=
'/afs/cern.ch/user/a/atlcond/utils/AtlCoolMerge.py ' \
183 if(
not CoolMergeByDefault
or isRunNumberConflict):
184 UploadCommand +=
" --noexec "
186 UploadCommand +=
"--comment=\'Automated reference update from " + calType \
187 +
' run ' + runNumber +
' to IOV starting at ' + highestRun +
"' " \
188 + calFilePrefix +
'.db' \
189 +
' COMP200 ATLAS_COOLWRITE ATLAS_COOLOFL_CSC_W WCOOLOFL4CSC17 '
191 WebSiteCommand =
'\nfs sa ${resultDir} webserver:afs read\n'
192 WebSiteCommand +=
'cd $resultDir\n'
193 WebSiteCommand +=
'ln -s ${resultDir} ${webSiteDir}/pedRun_' + runNumber +
'\n'
194 WebSiteCommand +=
'MakeCscPedSite.exe ' + runNumber +
'.root ' + runNumber +
'.cal_online\n'
199 bashFileContents +=
'\ncd ' + workDir +
'\n' \
200 +
"#Copying files from castor#\n" \
203 +
"#Running calibration (and calib monitoring)\n"\
204 +
"#, resulting in .cal file and status report\n"\
205 + calibCommand +
'\n' \
207 +
"#Athena job to transform *.cal file to *.db file.\n"\
209 +
"#Python utility to upload *.db file to database. When entering by\n"\
210 +
"#hand, I recomend removing '--batch' flag so you can check puposed\n"\
211 +
"#operations before submision to database\n"\
212 + UploadCommand +
'\n' \
213 +
'#Check if AllCalibMonGood file was created, which means that\n'\
214 +
'#this run passed acceptable criteria in the calibration monitoring\n'\
215 +
'if [ -a AllCalibMonGood ]; then\n' \
216 + t1 +
"#Email list that the calibration looks good\n"\
217 + t1 + goodEmailCommand +
'\n' \
218 + t1 +
"################################################################\n"\
219 + t1 +
"#Execute next two commands if you want to submit database entry#\n"\
220 + t1 +
"#Useful if these steps were skipped due to suspicious behaviour#\n"\
221 + t1 +
"#during calibration. #\n"\
222 + t1 +
"###############################################################\n"\
226 + t1 +
"#Suspicious behaviour in calibration. Notify mail list of this fact\n"\
227 + t1 + badEmailCommand +
'\n' \
230 +
'#Always create website'\
231 + WebSiteCommand +
'\n' \
232 +
'rm -rf $bytestreamDir\n' \
233 +
'rm -rf ' + scriptDir +
"runningCalibration" + runNumber +
'\n'
236 print (
"Printing bash file to: " +bashFilePath)
237 bashFile =
open(bashFilePath,
'w')
238 bashFile.write(bashFileContents)
242 os.system(
'chmod +x ' + bashFilePath)
243 bsubsMessage = os.popen(bsubCmd).
read()
246 emailMessage =
'Starting ' + calType +
' calibration on run number ' + runNumber
247 emailSubject =
'[CSC CALIB PROC]: ' + emailMessage
248 emailMessage +=
'\nbsubs output:\n' + bsubsMessage
249 os.system(
'echo "' + emailMessage +
'" | mail -s "' + emailSubject +
'" ' + maillist)
257 calType = sys.argv[1]
258 if calType ==
'pulser':
259 calibFileDir =
'/castor/cern.ch/user/l/lampen/CalibRunTest/slope/'
260 oldListFilePath =
'/afs/cern.ch/user/m/muoncali/CSC/run/pulserList.txt'
261 outputDir =
'/afs/cern.ch/user/m/muoncali/w0/CSC/runs/pulser/pulser'
262 elif calType ==
'ped':
263 calibFileDir =
'/castor/cern.ch/grid/atlas/DAQ/muon/csc/'
264 oldListFilePath =
'/afs/cern.ch/user/m/muoncali/CSC/run/pedDirList.txt'
265 outputDir =
'/afs/cern.ch/user/m/muoncali/w0/CSC/runs/ped/ped'
266 calibRe = re.compile(
'data1.*_calib.*calibration_pedCSC\\.daq\\.RAW.*\\.data')
268 print (
'Need to specify pulser or ped')
274 testFile = glob.glob(
"/afs/cern.ch/user/m/muoncali/CSC/run/runningCalibration*")
276 print (
'already running: ' +
str(testFile))
281 print (
'rfdir ' + calibFileDir)
282 currentLs = os.popen(
'rfdir ' + calibFileDir).
read()
284 os.popen(
'touch testing')
287 inFile =
open(oldListFilePath,
'r')
288 oldLs = inFile.read()
292 print (
'checking for changes')
295 now = datetime.datetime.now()
299 if(oldLs != currentLs):
300 print (
'There has been a change')
301 currentDirList = currentLs.split(
'\n')
302 oldDirList = oldLs.split(
'\n')
307 for Dir
in currentDirList:
309 if Dir
not in oldDirList:
310 print (
"**********************************************************")
311 splitDir = Dir.split()
313 DirName =splitDir[-1]
316 timediff = today - day
317 if(timediff > 7
or timediff < -23):
320 print (
"Found old dir " + DirName +
", but its over at least a week old, so we're skipping it")
326 print (
"day is " +
str(day))
329 cmd =
'rfdir ' + calibFileDir + DirName
332 nFiles = len(fileList) -1
333 print (
"found " +
str(nFiles) +
" files")
338 outputDirFull = outputDir +
'Run_' + runNumber
339 print (
'outputDirFull is ' + outputDirFull)
346 castorCopyCmd =
"mkdir ${bytestreamDir}"
347 for file
in fileList:
348 fileName = (file.split(
' '))[-1]
350 print (
"fileName: " +fileName)
351 ThisCalibDir = re.match(calibRe,fileName)
352 if(nFiles < numFilesToRun):
353 print (
"only " +
str(nFiles) +
" files. Breaking.")
355 print (
"There is a calib dir, but it only has " +
str(nFiles)
356 +
" file. Will not process.")
357 updateRunList =
False
360 fullPath = calibFileDir + DirName +
'/' + fileName
361 castorCopyCmd +=
"\nxrdcp root://castoratlas/" + fullPath +
" ${bytestreamDir}"
366 print (
"found " +
str(nFiles) +
" files")
369 if(nFiles >= numFilesToRun):
372 updateRunList =
False
373 print (
"Found new calibration directory to run on (" +DirName +
"), but already running on " + runningDir)
375 print (
'running on ' + DirName)
377 if(nFiles > numFilesToRun):
378 print (
'WARNING! Found ' +
str(nFiles) +
' calib files, when only ' +
str(numFilesToRun) +
' were expected!')
381 if( os.path.exists(outputDirFull)):
382 print (
"There is already a directory for run number " + runNumber)
383 print (
"Will not run on this pedestal run")
388 print (castorCopyCmd)
391 os.makedirs(outputDirFull+
"/CalibResults")
393 runCalib(calType, runNumber, outputDirFull, castorCopyCmd)
395 print(
'Launched job, but will continue to check if we have more runs to run on later')
397 updateRunList =
False
404 print (
"No unprocessed or currently being processed calibration runs. Will update run list.")
407 print (
"NOT updating run list")
410 print (
'No changes between old and new runs')