]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWGPP/benchmark/benchmark.sh
RelVal: opt parsing fix and syntax update
[u/mrichter/AliRoot.git] / PWGPP / benchmark / benchmark.sh
index 373333da56a594035f4ca3f97b003607053c3194..52017b3a2ca96471b0d57604e9154ecc789e3778 100755 (executable)
@@ -1,6 +1,7 @@
 #!/bin/bash
 #include benchmark.config
 
+# blame: Mikolaj Krzewicki, mkrzewic@cern.ch
 # this script runs the CPass0/CPass1 train
 # produced OCDB updates are local
 
@@ -133,10 +134,9 @@ goCPass0()
     return 1  
   fi
   
-  #runpath=${PWD}/rundir_cpass0_${runNumber}_${jobindex}
   runpath=${outputDir}
-  #[[ ${reconstructInTemporaryDir} -eq 1 && -n ${TMPDIR} ]] && runpath=${TMPDIR}
   [[ ${reconstructInTemporaryDir} -eq 1 ]] && runpath=$(mktemp -d -t cpass0.XXXXXX)
+  [[ ${reconstructInTemporaryDir} -eq 2 ]] && runpath=${PWD}/rundir_cpass0_${runNumber}_${jobindex}
   mkdir -p ${runpath}
   if [[ ! -d ${runpath} ]]; then
     touch ${doneFileTmp} 
@@ -155,7 +155,11 @@ goCPass0()
 
   #runCPassX/C expects the raw chunk to be linked in the run dir
   #despite it being accessed by the full path
-  ln -s ${infile} ${runpath}/${chunkName}
+  if [[ $copyInputData == 0 ]]; then
+    ln -s ${infile} ${runpath}/${chunkName}
+  else
+    copyFileToLocal ${infile} ${runpath}/${chunkName}
+  fi
 
   #####MC
   if [[ -n ${generateMC} ]]; then
@@ -191,7 +195,7 @@ goCPass0()
   fi
   ######
   
-  if [[ ! -f ${inputList} && -z ${pretend} ]]; then
+  if [[ "${inputList}" == "${inputList%%://*}" && ! -f "${inputList}" && -z ${pretend} ]]; then
     touch ${doneFileTmp}
     echo "input file ${inputList} not found, exiting..." >> ${doneFileTmp}
     cp "$doneFileTmp" "$doneFile" || rm -f "$doneFileTmp" "$doneFile"
@@ -256,7 +260,7 @@ goCPass0()
   fi
 
   #run CPass0
-  echo "${runpath}/runCPass0.sh ${infile} ${nEvents} ${runNumber} ${ocdbPath} ${recoTriggerOptions}"
+  echo "${runpath}/runCPass0.sh /${infile} ${nEvents} ${runNumber} ${ocdbPath} ${recoTriggerOptions}"
   if [[ -n ${pretend} ]]; then
     sleep ${pretendDelay}
     touch AliESDs.root
@@ -265,8 +269,8 @@ goCPass0()
     touch rec.log
     touch calib.log
   else
-    echo ./runCPass0.sh "${infile}" "${nEvents}" "${runNumber}" "${ocdbPath}" "${recoTriggerOptions}"
-    ./runCPass0.sh "${infile}" "${nEvents}" "${runNumber}" "${ocdbPath}" "${recoTriggerOptions}"
+    #caveat: in the local case, first arg must start with a slash
+    ./runCPass0.sh "/${infile}" "${nEvents}" "${runNumber}" "${ocdbPath}" "${recoTriggerOptions}"
   fi
   
   #move stuff to final destination
@@ -277,14 +281,12 @@ goCPass0()
   # [dberzano] OK this is fine!
   echo rm -f ./${chunkName}
   rm -f ./${chunkName}
-  echo "cp -R ${runpath}/* ${outputDir}"
-  cp -p -R ${runpath}/* ${outputDir}
+  echo "paranoidCp ${runpath}/* ${outputDir}"
+  paranoidCp ${runpath}/* ${outputDir}
   echo
   
   #validate CPass0
   cd ${outputDir}
-  touch ${doneFileTmp}
-  echo "dir ${outputDir}" >> ${doneFileTmp}
   if summarizeLogs >> ${doneFileTmp}; then
     [[ -f ${outputDirMC}/galice.root ]] && echo "sim ${outputDirMC}/galice.root" >> ${doneFileTmp}
     [[ -f AliESDfriends_v1.root ]] && echo "calibfile ${outputDir}/AliESDfriends_v1.root" >> ${doneFileTmp}
@@ -349,7 +351,7 @@ goCPass1()
   #Packages= ;OutputDir= ;LPMPass= ;TriggerAlias= ;LPMRunNumber= ;LPMProductionType= ;LPMInteractionType= ;LPMProductionTag= ;LPMAnchorRun= ;LPMAnchorProduction= ;LPMAnchorYear= 
   export PRODUCTION_METADATA="OutputDir=cpass1"
 
-  if [[ ! -f ${inputList} && -z ${pretend} ]]; then
+  if [[ "${inputList}" == "${inputList%%://*}" && ! -f "${inputList}" && -z ${pretend} ]]; then
     touch ${doneFileTmp}
     echo "input file ${inputList} not found, exiting..." >> ${doneFileTmp}
     cp "$doneFileTmp" "$doneFile" || rm -f "$doneFileTmp" "$doneFile"
@@ -373,10 +375,9 @@ goCPass1()
     return 1
   fi
   
-  #runpath=${PWD}/rundir_cpass1_${runNumber}_${jobindex}
   runpath=${outputDir}
-  #[[ ${reconstructInTemporaryDir} -eq 1 && -n ${TMPDIR} ]] && runpath=${TMPDIR}
   [[ ${reconstructInTemporaryDir} -eq 1 ]] && runpath=$(mktemp -d -t cpass1.XXXXXX)
+  [[ ${reconstructInTemporaryDir} -eq 2 ]] && runpath=${PWD}/rundir_cpass1_${runNumber}_${jobindex}
 
   #MC
   if [[ "${infile}" =~ galice\.root ]]; then
@@ -402,7 +403,11 @@ goCPass1()
   fi
 
   #this is needed for runCPass1.sh
-  ln -s ${infile} ${runpath}/${chunkName}
+  if [[ $copyInputData == 0 ]]; then
+    ln -s ${infile} ${runpath}/${chunkName}
+  else
+    copyFileToLocal ${infile} ${runpath}/${chunkName}
+  fi
 
   logOutputDir=${runpath}
   [[ -n ${logToFinalDestination} ]] && logOutputDir=${outputDir}
@@ -506,7 +511,7 @@ goCPass1()
 
   #run CPass1
   chmod u+x runCPass1.sh
-  echo "${runpath}/runCPass1.sh ${infile} ${nEvents} ${runNumber} ${ocdbPath} ${recoTriggerOptions}"
+  echo "${runpath}/runCPass1.sh /${infile} ${nEvents} ${runNumber} ${ocdbPath} ${recoTriggerOptions}"
   if [[ -n ${pretend} ]]; then
     sleep ${pretendDelay}
     touch AliESDs_Barrel.root
@@ -524,7 +529,8 @@ goCPass1()
     touch qa.log
     touch filtering.log FilterEvents_Trees.root
   else
-    ./runCPass1.sh "${infile}" "${nEvents}" "${runNumber}" "${ocdbPath}" "${recoTriggerOptions}"
+    #caveat: in the local case, first arg must start with a slash
+    ./runCPass1.sh "/${infile}" "${nEvents}" "${runNumber}" "${ocdbPath}" "${recoTriggerOptions}"
     
     [[ ! -f AliESDs_Barrel.root && -f Barrel/AliESDs.root ]] && mv Barrel/AliESDs.root AliESDs_Barrel.root
     [[ ! -f AliESDfriends_Barrel.root && -f Barrel/AliESDfriends.root ]] && mv Barrel/AliESDfriends.root AliESDfriends_Barrel.root
@@ -572,14 +578,12 @@ goCPass1()
   /bin/ls
   echo rm -f ./${chunkName}
   rm -f ./${chunkName}
-  echo "cp -R ${runpath}/* ${outputDir}"
-  cp -pf -R ${runpath}/* ${outputDir}
+  echo "paranoidCp ${runpath}/* ${outputDir}"
+  paranoidCp ${runpath}/* ${outputDir}
   echo
 
   #validate CPass1
   cd ${outputDir}
-  touch ${doneFileTmp}
-  echo "dir ${outputDir}" >> ${doneFileTmp}
   if summarizeLogs >> ${doneFileTmp}; then
     [[ -f AliESDs_Barrel.root ]] && echo "esd ${outputDir}/AliESDs_Barrel.root" >> ${doneFileTmp}
     [[ -f AliESDfriends_v1.root ]] && echo "calibfile ${outputDir}/AliESDfriends_v1.root" >> ${doneFileTmp}
@@ -641,10 +645,9 @@ goMergeCPass0()
 
   [[ -f ${alirootSource} && -z ${ALICE_ROOT} ]] && source ${alirootSource}
 
-  #runpath=${PWD}/rundir_cpass0_Merge_${runNumber}
   runpath=${outputDir}
-  #[[ ${reconstructInTemporaryDir} -eq 1 && -n ${TMPDIR} ]] && runpath=${TMPDIR}
   [[ ${reconstructInTemporaryDir} -eq 1 ]] && runpath=$(mktemp -d -t mergeCPass0.XXXXXX)
+  [[ ${reconstructInTemporaryDir} -eq 2 ]] && runpath=${PWD}/rundir_mergeCPass0_${runNumber}
 
   mkdir -p ${runpath}
   if [[ ! -d ${runpath} ]]; then
@@ -713,7 +716,7 @@ goMergeCPass0()
     /bin/ls -1 ${outputDir}/*/AliESDfriends_v1.root 2>/dev/null > ${calibrationFilesToMerge}
   fi
   
-  echo "${mergingScript} ${calibrationFilesToMerge} ${runNumber} local://./OCDB ${ocdbStorage}"
+  echo "${mergingScript} ${calibrationFilesToMerge} ${runNumber} local://./OCDB defaultOCDB=${ocdbStorage} fileAccessMethod=nocopy"
   if [[ -n ${pretend} ]]; then
     sleep ${pretendDelay}
     touch CalibObjects.root
@@ -725,7 +728,7 @@ goMergeCPass0()
     echo "some calibration" >> ./OCDB/TPC/Calib/TimeGain/someCalibObject_0-999999_cpass0.root
     echo "some calibration" >> ./OCDB/TPC/Calib/TimeDrift/otherCalibObject_0-999999_cpass0.root
   else
-    ./${mergingScript} ${calibrationFilesToMerge} ${runNumber} "local://./OCDB" ${ocdbStorage} >> "mergeMakeOCDB.log"
+    ./${mergingScript} ${calibrationFilesToMerge} ${runNumber} "local://./OCDB" defaultOCDB=${ocdbStorage} fileAccessMethod=nocopy >> "mergeMakeOCDB.log"
 
     #produce the calib trees for expert QA (dcsTime.root)
     goMakeLocalOCDBaccessConfig ./OCDB
@@ -747,7 +750,8 @@ goMergeCPass0()
   /bin/ls
 
   #copy all to output dir
-  cp -pf -R ${runpath}/* ${outputDir}
+  echo "paranoidCp ${runpath}/* ${outputDir}"
+  paranoidCp ${runpath}/* ${outputDir}
 
   if [[ -n ${generateMC} ]]; then
     goPrintValues sim ${commonOutputPath}/meta/sim.run${runNumber}.list ${commonOutputPath}/meta/cpass0.job*.run${runNumber}.done
@@ -755,8 +759,6 @@ goMergeCPass0()
 
   #validate merging cpass0
   cd ${outputDir}
-  touch ${doneFileTmp}
-  echo "dir ${outputDir}" >> ${doneFileTmp}
   if summarizeLogs >> ${doneFileTmp}; then
     [[ -f CalibObjects.root ]] && echo "calibfile ${outputDir}/CalibObjects.root" >> ${doneFileTmp}
     [[ -f dcsTime.root ]] && echo "dcsTree ${outputDir}/dcsTime.root" >> ${doneFileTmp}
@@ -807,10 +809,9 @@ goMergeCPass1()
 
   [[ -f ${alirootSource} && -z ${ALICE_ROOT} ]] && source ${alirootSource}
 
-  #runpath=${PWD}/rundir_cpass1_Merge_${runNumber}
   runpath=${outputDir}
-  #[[ ${reconstructInTemporaryDir} -eq 1 && -n ${TMPDIR} ]] && runpath=${TMPDIR}
   [[ ${reconstructInTemporaryDir} -eq 1 ]] && runpath=$(mktemp -d -t mergeCPass1.XXXXXX)
+  [[ ${reconstructInTemporaryDir} -eq 2 ]] && runpath=${PWD}/rundir_mergeCPass1_${runNumber}
 
   mkdir -p ${runpath}
   if [[ ! -d ${runpath} ]]; then
@@ -903,8 +904,8 @@ goMergeCPass1()
     echo "/bin/ls -1 ${outputDir}/*/QAresults*.root | while read x; do echo ${x%/*}; done | sort | uniq > ${qaFilesToMerge}"
     /bin/ls -1 ${outputDir}/*/QAresults*.root | while read x; do echo ${x%/*}; done | sort | uniq > ${qaFilesToMerge}
   fi
-  
-  echo "${mergingScript} ${calibrationFilesToMerge} ${runNumber} local://./OCDB ${ocdbStorage}"
+
+  echo "${mergingScript} ${calibrationFilesToMerge} ${runNumber} local://./OCDB defaultOCDB=${ocdbStorage} fileAccessMethod=nocopy"
   if [[ -n ${pretend} ]]; then
     sleep ${pretendDelay}
     touch ocdb.log
@@ -918,7 +919,7 @@ goMergeCPass1()
     touch ${qaMergedOutputFileName}
     mkdir -p OCDB
   else
-    ./${mergingScript} ${calibrationFilesToMerge} ${runNumber} "local://./OCDB" ${ocdbStorage}
+    ./${mergingScript} ${calibrationFilesToMerge} ${runNumber} "local://./OCDB" defaultOCDB=${ocdbStorage} fileAccessMethod=nocopy
 
     #merge QA (and filtered trees)
     [[ -n ${AliAnalysisTaskFilteredTree_fLowPtTrackDownscaligF} ]] && export AliAnalysisTaskFilteredTree_fLowPtTrackDownscaligF
@@ -950,12 +951,11 @@ goMergeCPass1()
   /bin/ls
 
   #copy all to output dir
-  cp -pf -R ${runpath}/* ${outputDir}
+  echo "paranoidCp ${runpath}/* ${outputDir}"
+  paranoidCp ${runpath}/* ${outputDir}
   
   #validate merge cpass1
   cd ${outputDir}
-  touch ${doneFileTmp}
-  echo "dir ${outputDir}" >> ${doneFileTmp}
   if summarizeLogs >>  ${doneFileTmp}; then
     [[ -f CalibObjects.root ]] && echo "calibfile ${outputDir}/CalibObjects.root" >> ${doneFileTmp}
     [[ -f ${qaMergedOutputFileName} ]] && echo "qafile ${outputDir}/${qaMergedOutputFileName}" >> ${doneFileTmp}
@@ -1034,9 +1034,9 @@ goSubmitMakeflow()
   #if which greadlink; then self=$(greadlink -f "${0}"); fi
   
   #for reference copy the setup to the output dir
-  cp ${self} ${commonOutputPath}
-  cp ${configFile} ${commonOutputPath}
-  cp ${inputFileList} ${commonOutputPath}
+  paranoidCp ${self} ${commonOutputPath}
+  paranoidCp ${configFile} ${commonOutputPath}
+  paranoidCp ${inputFileList} ${commonOutputPath}
 
   #submit - use makeflow if available, fall back to old stuff when makeflow not there
   if which makeflow; then
@@ -1046,6 +1046,15 @@ goSubmitMakeflow()
   else 
     echo "no makeflow!"
   fi
+  
+  #summarize the run based on the makeflow log
+  #and add it to the end of summary log
+  awk '/STARTED/   {startTime=$3} 
+       /COMPLETED/ {endTime=$3} 
+       END         {print "makeflow running time: "(endTime-startTime)/1000000/3600" hours"}' \
+      benchmark.makeflow.makeflowlog | tee -a summary.log
+  paranoidCp summary.log ${commonOutputPath}
+
   return 0
 }
 
@@ -1437,6 +1446,9 @@ summarizeLogs()
             "stderr"
   )
 
+  #put dir information in the output
+  echo "dir $PWD"
+
   #check logs
   local logstatus=0
   for log in ${logFiles[*]}; do
@@ -1593,7 +1605,6 @@ EOF
   fi
   pwd
   /bin/ls
-  touch ${doneFile}
   summarizeLogs >>  ${doneFile}
   
   #echo mv -f * ${outputDir}
@@ -2065,7 +2076,8 @@ goSubmitBatch()
   echo "submit make a summary"
   echo
 
-  submit "${JOBID6}" 1 1 "${LASTJOB}" "${alirootEnv} ${self}" MakeSummary ${configFile}
+  [[ -z ${alirootEnvQA} ]] && alirootEnvQA=$(encSpaces "${alirootEnv}")
+  submit "${JOBID6}" 1 1 "${LASTJOB}" "${alirootEnvQA} ${self}" MakeSummary ${configFile} "commonOutputPath=${commonOutputPath}"
   LASTJOB=${JOBID6}
   #################################################################################
   
@@ -2197,14 +2209,20 @@ EOF
 
 stackTraceTree()
 (
-  # make stacktrace processing  in case of standard root crash log
-  # input is a (list of) text files with the stack trace (either gdb aoutput
-  # produced with e.g. gdb --batch --quiet -ex "bt" -ex "quit" aliroot core, or the root crash log), output is a TTree formatted table.
-# example usage:
-# benchmark.sh stackTraceTree /foo/*/rec.log
+  if [[ $# -lt 1 ]]; then
+    echo 'make stacktrace processing  in case of standard root crash log'
+    echo 'input is a (list of) text files with the stack trace (either gdb aoutput'
+    echo 'produced with e.g. gdb --batch --quiet -ex "bt" -ex "quit" aliroot core,'
+    echo 'or the root crash log), output is a TTree formatted table.'
+    echo 'example usage:'
+    echo 'benchmark.sh stackTraceTree /foo/*/rec.log'
+    echo 'benchmark.sh stackTraceTree $(cat file.list)'
+    echo 'benchmark.sh stackTraceTree `cat file.list`'
+    return 0
+  fi
   gawk '
        BEGIN { 
-               print "frame/I:method/C:line/C:cpass/I:aliroot/I";
+               print "frame/I:method/C:line/C:cpass/I:aliroot/I:file/C";
                RS="#[0-9]*";
                aliroot=0;
                read=1;
@@ -2214,7 +2232,7 @@ stackTraceTree()
       read==1 { 
                if ($3 ~ /Ali*/) aliroot=1; else aliroot=0;
                gsub("#","",RT); 
-               if ($NF!="" && RT!="" && $3!="") print RT" "$3" "$NF" "0" "aliroot
+               if ($NF!="" && RT!="" && $3!="") print RT" "$3" "$NF" "0" "aliroot" "FILENAME
              }
       ' "$@" 2>/dev/null
 )
@@ -2318,7 +2336,7 @@ goMakeSummary()
   echo per run stats:
   /bin/ls -1 ${commonOutputPath}/meta/merge.cpass0.run*.done | while read x 
 do
-  dir=$(goPrintValues calibfile - ${x})
+  dir=$(goPrintValues dir - ${x})
   runNumber=$(guessRunNumber ${dir})
   [[ -z ${runNumber} ]] && continue
 
@@ -2393,10 +2411,12 @@ done
   cp "$logTmp" "$logDest" || rm -f "$logTmp" "$logDest"
   
   #copy output files
-  cp -r QAplots ${commonOutputPath}
-  cp *.list ${commonOutputPath}
-  cp *.root ${commonOutputPath}
-  cp *.log ${commonOutputPath}
+  exec &> >(tee fileCopy.log)
+  paranoidCp QAplots ${commonOutputPath}
+  paranoidCp *.list ${commonOutputPath}
+  paranoidCp *.root ${commonOutputPath}
+  paranoidCp *.log ${commonOutputPath}
+  paranoidCp fileCopy.log ${commonOutputPath}
 
   return 0
 )
@@ -2545,6 +2565,7 @@ parseConfig()
   logToFinalDestination=1
   ALIROOT_FORCE_COREDUMP=1
   pretendDelay=0
+  copyInputData=0
 
   #first, source the config file
   if [ -f ${configFile} ]; then
@@ -2601,6 +2622,74 @@ aliroot()
   return 0
 }
 
+copyFileToLocal()
+(
+  #copies a file from either a remote or local location to a local destination
+  src="$1"
+  dst="$2"
+
+  proto="${src%%://*}"
+  if [[ "$proto" == "$src" ]]; then
+    cp "$src" "$dst"
+  else
+    case "$proto" in
+      root)
+        xrdcp -f "$src" "$dst"
+      ;;
+      http)
+        curl -L "$src" -O "$dst"
+      ;;
+      *)
+        echo "protocol not supported: $proto"
+        return 1
+      ;;
+    esac
+  fi
+)
+
+paranoidCp()
+(
+  #recursively copy files and directories
+  #to avoid using find and the like as they kill
+  #the performance on some cluster file systems
+  #does not copy links to avoid problems
+  sourceFiles=("${@}")
+  destination="${sourceFiles[@]:(-1)}" #last element
+  unset sourceFiles[${#sourceFiles[@]}-1] #remove last element (dst)
+  for src in "${sourceFiles[@]}"; do
+    if [[ -f "${src}" && ! -h  "${src}" ]]; then
+      paranoidCopyFile "${src}" "${destination}"
+    elif [[ -d "${src}" && ! -h "${src}" ]]; then
+      src="${src%/}"
+      dst="${destination}/${src##*/}"
+      mkdir -p "${dst}"
+      paranoidCp "${src}"/* "${dst}"
+    fi
+  done
+)
+
+paranoidCopyFile()
+(
+  #copy a single file to a target in an existing dir
+  #repeat a few times if copy fails
+  src="${1}"
+  dst="${2}"
+  [[ -d "${dst}" ]] && dst="${dst}/${src##*/}"
+  [[ -z "${maxCopyTries}" ]] && maxCopyTries=5
+  #echo "maxCopyTries=${maxCopyTries}"
+  echo "cp ${src} ${dst}"
+  cp "${src}" "${dst}"
+  i=0
+  until cmp -s "${src}" "${dst}"; do
+    echo "try: ${i}"
+    [[ -f "${dst}" ]] && rm "${dst}"
+    cp "${src}" "${dst}"
+    [[ ${i} -gt ${maxCopyTries} ]] && ret=1 && return 1
+    (( i++ ))
+  done
+  return 0
+)
+
 guessRunData()
 {
   #guess the period from the path, pick the rightmost one