]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGPP/QA/scripts/runQA.sh
add a protection and a warning against running with bash version < 4
[u/mrichter/AliRoot.git] / PWGPP / QA / scripts / runQA.sh
CommitLineData
f7707400 1#!/bin/bash
34af53b5 2if [ ${BASH_VERSINFO} -lt 4 ]; then
3 echo "bash version >= 4 needed, you have ${BASH_VERSION}, exiting..."
4 exit 1
5fi
6
f7707400 7main()
8{
0c9bef99 9 if [[ -z $1 ]]; then
0adcf494 10 echo "Usage: "
11 echo " ${0##*/} option=value [option=value]"
161409c5 12 echo " at least inputList should be specified, or configFile containing it:"
13 echo " ${0##*/} inputList=file.list"
0adcf494 14 echo " options override config file (if any), e.g.:"
15 echo " ${0##*/} configFile=runQA.config inputList=file.list outputDirectory=%det"
2c46f154 16 return 1
93e1d132 17 fi
34af53b5 18
c8973bf8 19 if ! parseConfig "$@"; then
0adcf494 20 ${0}
21 return 1
22 fi
0c9bef99 23
2c46f154 24 [[ -z $ALICE_ROOT ]] && echo "ALICE_ROOT not defined" && return 1
93e1d132 25
26 ocdbregex='raw://'
2c46f154 27 if [[ ${ocdbStorage} =~ ${ocdbregex} ]]; then
823d0979 28 alien-token-init ${alienUserName}
5ed6085c 29 #this is a hack! alien-token init seems not enough
30 #but the gclient_env script messes up the LD_LIBRARY_PATH
31 while read x; do
32 eval ${x};
33 done < <(grep -v "LD_LIBRARY_PATH" /tmp/gclient_env_${UID})
2c46f154 34 fi
0c9bef99 35
c8973bf8 36 updateQA "$@"
f7707400 37}
38
0c9bef99 39updateQA()
f7707400 40{
41 umask 0002
c8973bf8 42 parseConfig "$@"
0adcf494 43
44 #be paranoid and make some full paths
0adcf494 45 [[ ! -f ${inputList} ]] && echo "no input list: ${inputList}" && return 1
7f49f812 46 inputList=$(get_realpath ${inputList})
0adcf494 47 mkdir -p ${workingDirectory}
7f49f812 48 workingDirectory=$(workingDirectory=${workingDirectory%/}; cd ${workingDirectory%/*}; echo "${PWD}/${workingDirectory##*/}")
0adcf494 49 if [[ ! -d ${workingDirectory} ]]; then
50 echo "working dir $workingDirectory does not exist and cannot be created"
51 return 1
52 fi
53 cd ${workingDirectory}
54
55 echo JOB config:
56 echo inputList=$inputList
57 echo outputDirectory=$outputDirectory
58 echo
f7707400 59
142113c1 60 dateString=$(date +%Y-%m-%d-%H-%M-%S-%N)
93e1d132 61 echo "Start time QA process: $dateString"
62
9cc5d265 63 #logging
64 mkdir -p $logDirectory
2c46f154 65 [[ ! -d $logDirectory ]] && echo "no log dir $logDirectory" && return 1
93e1d132 66 logFile="$logDirectory/${0##*/}.${dateString}.log"
9cc5d265 67 touch ${logFile}
2c46f154 68 [[ ! -f ${logFile} ]] && echo "cannot write logfile $logfile" && return 1
93e1d132 69 echo "logFile = $logFile"
9cc5d265 70
71 #check lock
a360b7b2 72 lockFile=${workingDirectory}/runQA.lock
bf4e7ceb 73 [[ -f ${lockFile} ]] && echo "lock ${lockFile} exists!" | tee ${logFile} && return 1
9cc5d265 74 touch ${lockFile}
bf4e7ceb 75 [[ ! -f ${lockFile} ]] && echo "cannot lock $lockFile" | tee ${logFile} && return 1
9cc5d265 76
bf4e7ceb 77 exec &>${logFile}
78
0c9bef99 79 ################################################################
80 #ze detector loop
f7707400 81 for detectorScript in $ALICE_ROOT/PWGPP/QA/detectorQAscripts/*; do
3db1b975 82 echo
83 echo "##############################################"
244ec455 84 echo $(date)
bf4e7ceb 85 unset planB
86 [[ ! ${detectorScript} =~ .*\.sh$ ]] && continue
f7707400 87 detector=${detectorScript%.sh}
88 detector=${detector##*/}
2c46f154 89
90 #skip if excluded
c1386fec 91 if [[ "${excludeDetectors}" =~ ${detector} ]]; then
92 echo "${detector} is excluded in config, skipping..."
93 continue
94 fi
2c46f154 95
161409c5 96 #if includeDetectors set, only process thoe detectors specified there
97 if [[ -n ${includeDetectors} && ! "${includeDetectors}" =~ ${detector} ]]; then
98 echo "${detector} not included in includeDetectors, skipping..."
99 continue
100 fi
101
2c46f154 102 logSummary=${logDirectory}/summary-${detector}-${dateString}.log
69b2d32e 103 hostInfo >> ${logSummary}
f7707400 104 outputDir=$(substituteDetectorName ${detector} ${outputDirectory})
bf4e7ceb 105 tmpDetectorRunDir=${workingDirectory}/tmpQAtmpRunDir${detector}-${dateString}
8e7a87c1 106 if ! mkdir -p ${tmpDetectorRunDir}; then
107 echo "cannot create the temp dir $tmpDetectorRunDir"
9cc5d265 108 continue
109 fi
8e7a87c1 110 cd ${tmpDetectorRunDir}
9cc5d265 111
8e7a87c1 112 tmpPrefix=${tmpDetectorRunDir}/${outputDir}
93e1d132 113 echo "running QA for ${detector}"
114 echo " outputDir=$outputDir"
115 echo " tmpPrefix=$tmpPrefix"
f7707400 116
61fa85ce 117 #unset the detector functions from previous iterations (detectors)
f7707400 118 unset -f runLevelQA
119 unset -f periodLevelQA
645f513c 120 unset -f runLevelHighPtTreeQA
121 unset -f periodLevelHighPtTreeQA
f7707400 122 source ${detectorScript}
123
124 #################################################################
125 #produce the QA and trending tree for each file (run)
2a6472ef 126 unset arrOfTouchedProductions
127 declare -A arrOfTouchedProductions
f7707400 128 while read qaFile; do
2c46f154 129 echo
244ec455 130 echo $(date)
3db1b975 131
132 #first check if input file exists
133 [[ ! -f ${qaFile%\#*} ]] && echo "file ${qaFile%\#*} not accessible" && continue
2c46f154 134
0adcf494 135 if ! guessRunData ${qaFile}; then
136 echo "could not guess run data from ${qaFile}"
137 continue
138 fi
17b0cdcd 139 echo "anchorYear for ${originalPeriod} is: ${anchorYear}"
f7707400 140
2a6472ef 141 tmpProductionDir=${tmpPrefix}/${dataType}/${year}/${period}/${pass}
2a6472ef 142 tmpRunDir=${tmpProductionDir}/000${runNumber}
143 mkdir -p ${tmpRunDir}
144 cd ${tmpRunDir}
f7707400 145
645f513c 146 #by default we expect to have everything in the same archive
147 highPtTree=${qaFile}
148
149 #maybe the input is not an archive, but a file
3db1b975 150 [[ "${qaFile}" =~ QAresults.root$ ]] && highPtTree=""
151 [[ "${qaFile}" =~ FilterEvents_Trees.root$ ]] && qaFile=""
f7707400 152
645f513c 153 #it is possible we get the highPt trees from somewhere else
154 #search the list of high pt trees for the proper run number
155 if [[ -n ${inputListHighPtTrees} ]]; then
645f513c 156 highPtTree=$(egrep -m1 ${runNumber} ${inputListHighPtTrees})
f8619ac0 157 echo "loaded the highPtTree ${highPtTree} from external file ${inputListHighPtTrees}"
645f513c 158 fi
159
160 echo qaFile=$qaFile
161 echo highPtTree=$highPtTree
c8973bf8 162 echo ocdbStorage=${ocdbStorage}
163 echo
645f513c 164
165 #what if we have a zip archive?
166 if [[ "$qaFile" =~ .*.zip$ ]]; then
167 if unzip -l ${qaFile} | egrep "QAresults.root" &>/dev/null; then
168 qaFile="${qaFile}#QAresults.root"
39488911 169 elif unzip -l ${qaFile} | egrep "QAresults_barrel.root" &>/dev/null; then
170 qaFile="${qaFile}#QAresults_barrel.root"
645f513c 171 else
172 qaFile=""
173 fi
174 fi
175 if [[ "$highPtTree" =~ .*.zip$ ]]; then
176 if unzip -l ${highPtTree} | egrep "FilterEvents_Trees.root" &>/dev/null; then
177 highPtTree="${highPtTree}#FilterEvents_Trees.root"
178 else
179 highPtTree=""
180 fi
de540baf 181 fi
645f513c 182
183 if [[ -n ${qaFile} && $(type -t runLevelQA) =~ "function" ]]; then
184 echo running ${detector} runLevelQA for run ${runNumber} from ${qaFile}
185 runLevelQA "${qaFile}" &> runLevelQA.log
186 #perform some default actions:
187 #if trending.root not created, create a default one
188 if [[ ! -f trending.root ]]; then
3db1b975 189 aliroot -b -q -l "$ALICE_ROOT/PWGPP/macros/simpleTrending.C(\"${qaFile}\",${runNumber},\"${detector}\",\"trending.root\",\"trending\",\"recreate\")" 2>&1 | tee -a runLevelQA.log
190 fi
191 if [[ -f trending.root ]]; then
762f2238 192 #cache the touched production + an example file to guarantee consistent run data parsing
193 arrOfTouchedProductions[${tmpProductionDir}]="${qaFile%\#*}"
3db1b975 194 else
195 echo "trending.root not created"
645f513c 196 fi
645f513c 197 fi
198 #expert QA based on high pt trees
199 if [[ -n ${highPtTree} && $(type -t runLevelHighPtTreeQA) =~ "function" ]]; then
200 echo running ${detector} runLevelHighPtTreeQA for run ${runNumber} from ${highPtTree}
201 runLevelHighPtTreeQA "${highPtTree}" &> runLevelHighPtTreeQA.log
202 arrOfTouchedProductions[${tmpProductionDir}]=1
203 fi
204
8e7a87c1 205 cd ${tmpDetectorRunDir}
f7707400 206
207 done < ${inputList}
208
209 #################################################################
210 #cache which productions were (re)done
93e1d132 211 echo "list of processed productions:"
2a6472ef 212 echo " ${!arrOfTouchedProductions[@]}"
93e1d132 213 echo
2a6472ef 214
f7707400 215 #################################################################
bf4e7ceb 216 #(re)do the merging/trending
2a6472ef 217 for tmpProductionDir in ${!arrOfTouchedProductions[@]}; do
bf4e7ceb 218 cd ${tmpProductionDir}
2c46f154 219 echo
220 echo "running period level stuff in ${tmpProductionDir}"
244ec455 221 echo $(date)
f7707400 222
f7707400 223 productionDir=${outputDir}/${tmpProductionDir#${tmpPrefix}}
bf4e7ceb 224 echo productionDir=${outputDir}/${tmpProductionDir#${tmpPrefix}}
2c46f154 225
f7707400 226 mkdir -p ${productionDir}
9cc5d265 227 if [[ ! -d ${productionDir} ]]; then
93e1d132 228 echo "cannot make productionDir $productionDir" && continue
9cc5d265 229 fi
f7707400 230
bf4e7ceb 231 #move runs to final destination
232 for dir in ${tmpProductionDir}/000*; do
233 echo
93e1d132 234 oldRunDir=${outputDir}/${dir#${tmpPrefix}}
762f2238 235 if ! guessRunData "${arrOfTouchedProductions[${tmpProductionDir}]}"; then
0adcf494 236 echo "could not guess run data from ${dir}"
237 continue
238 fi
2c46f154 239
240 #before moving - VALIDATE!!!
bf4e7ceb 241 if ! validate ${dir}; then
242 continue
243 fi
2c46f154 244
1aa30209 245 #moving a dir is an atomic operation, no locking necessary
93e1d132 246 if [[ -d ${oldRunDir} ]]; then
50864a2d 247 echo "removing old ${oldRunDir}"
93e1d132 248 rm -rf ${oldRunDir}
249 fi
2c46f154 250 echo "moving new ${runNumber} to ${productionDir}"
93e1d132 251 mv -f ${dir} ${productionDir}
252 done
033dacdc 253
3db1b975 254 #go to a temp dir to do the period level stuff in a completely clean dir
bf4e7ceb 255 tmpPeriodLevelQAdir="${tmpProductionDir}/periodLevelQA"
256 echo
257 echo tmpPeriodLevelQAdir="${tmpProductionDir}/periodLevelQA"
258 if ! mkdir -p ${tmpPeriodLevelQAdir}; then continue; fi
259 cd ${tmpPeriodLevelQAdir}
260
261 #link the final list of per-run dirs here, just the dirs
262 #to have a clean working directory
263 unset linkedStuff
264 declare -a linkedStuff
265 for x in ${productionDir}/000*; do [[ -d $x ]] && ln -s $x && linkedStuff+=(${x##*/}); done
bf4e7ceb 266
8e7a87c1 267 #merge trending files if any
268 if /bin/ls 000*/trending.root &>/dev/null; then
269 hadd trending.root 000*/trending.root &> periodLevelQA.log
645f513c 270 fi
271
bf4e7ceb 272 #run the period level trending/QA
645f513c 273 if [[ -f "trending.root" && $(type -t periodLevelQA) =~ "function" ]]; then
274 echo running ${detector} periodLevelQA for production ${period}/${pass}
8e7a87c1 275 periodLevelQA trending.root &>> periodLevelQA.log
645f513c 276 else
277 echo "WARNING: not running ${detector} periodLevelQA for production ${period}/${pass}, no trending.root"
8e7a87c1 278 fi
279
2c46f154 280 if ! validate ${PWD}; then continue; fi
2c46f154 281
bf4e7ceb 282 #here we are validated so move the produced QA to the final place
283 #clean up linked stuff first
284 [[ -n ${linkedStuff[@]} ]] && rm ${linkedStuff[@]}
1aa30209 285 periodLevelLock=${productionDir}/runQA.lock
286 if [[ ! -f ${periodLevelLock} ]]; then
287 #some of the output could be a directory, so handle that
288 #TODO: maybe use rsync?
289 #lock to avoid conflicts:
290 echo "${HOSTNAME} ${dateString}" > ${periodLevelLock}
291 for x in ${tmpPeriodLevelQAdir}/*; do
292 if [[ -d ${x} ]]; then
293 echo "removing ${productionDir}/${x##*/}"
294 rm -rf ${productionDir}/${x##*/}
295 echo "moving ${x} to ${productionDir}"
296 mv ${x} ${productionDir}
297 fi
298 if [[ -f ${x} ]]; then
299 echo "moving ${x} to ${productionDir}"
300 mv -f ${x} ${productionDir}
301 fi
302 done
303 rm -f ${periodLevelLock}
304 #remove the temp dir
305 rm -rf ${tmpPeriodLevelQAdir}
306 else
56af0297 307 echo "ERROR: cannot move to destination" >> ${logSummary}
308 echo "production dir ${productionDir} locked!" >> ${logSummary}
309 echo "check and maybe manually do:" >> ${logSummary}
310 echo " rm ${periodLevelLock}" >> ${logSummary}
311 echo " rsync -av ${tmpPeriodLevelQAdir}/ ${productionDir}/" >> ${logSummary}
c38409ba 312 planB=1
1aa30209 313 fi
bf4e7ceb 314
f7707400 315 done
316
9cc5d265 317 cd ${workingDirectory}
2c46f154 318
319 if [[ -z ${planB} ]]; then
9a5f8a19 320 echo
8e7a87c1 321 echo removing ${tmpDetectorRunDir}
322 rm -rf ${tmpDetectorRunDir}
2c46f154 323 else
324 executePlanB
325 fi
3db1b975 326 done #end of detector loop
f7707400 327
9cc5d265 328 #remove lock
329 rm -f ${lockFile}
f7707400 330}
331
2c46f154 332executePlanB()
333{
334 #in case of emergency
335 if [[ -n ${MAILTO} ]]; then
336 echo
337 echo "trouble detected, sending email to ${MAILTO}"
69b2d32e 338 cat ${logSummary} | mail -s "qa in need of assistance" ${MAILTO}
2c46f154 339 fi
340}
341
342validate()
343{
344 summarizeLogs ${1} >> ${logSummary}
345 logStatus=$?
346 if [[ ${logStatus} -ne 0 ]]; then
347 echo "WARNING not validated: ${1}"
348 planB=1
349 return 1
350 fi
351 return 0
352}
353
354summarizeLogs()
355{
356 local dir=$1
2a6472ef 357 [[ ! -d ${dir} ]] && dir=${PWD}
2c46f154 358
359 #print a summary of logs
360 logFiles=(
361 "*.log"
362 "stdout"
363 "stderr"
364 )
365
366 #check logs
367 local logstatus=0
368 for log in ${dir}/${logFiles[*]}; do
2c46f154 369 [[ ! -f ${log} ]] && continue
370 errorSummary=$(validateLog ${log})
371 validationStatus=$?
372 [[ validationStatus -ne 0 ]] && logstatus=1
373 if [[ ${validationStatus} -eq 0 ]]; then
374 #in pretend mode randomly report an error in rec.log some cases
375 if [[ -n ${pretend} && "${log}" == "rec.log" ]]; then
69b2d32e 376 [[ $(( ${RANDOM}%2 )) -ge 1 ]] && echo "${log} BAD random error" || echo "${log} OK"
2c46f154 377 else
69b2d32e 378 echo "${log} OK"
2c46f154 379 fi
380 elif [[ ${validationStatus} -eq 1 ]]; then
69b2d32e 381 echo "${log} BAD ${errorSummary}"
2c46f154 382 elif [[ ${validationStatus} -eq 2 ]]; then
69b2d32e 383 echo "${log} OK MWAH ${errorSummary}"
2c46f154 384 fi
385 done
386
387 #report core files
388 while read x; do
389 echo ${x}
390 chmod 644 ${x}
391 gdb --batch --quiet -ex "bt" -ex "quit" aliroot ${x} > stacktrace_${x//\//_}.log
392 done < <(/bin/ls ${PWD}/*/core 2>/dev/null; /bin/ls ${PWD}/core 2>/dev/null)
393
394 return ${logstatus}
395}
396
397validateLog()
398{
399 log=${1}
400 errorConditions=(
401 'There was a crash'
402 'floating'
403 'error while loading shared libraries'
404 'std::bad_alloc'
405 's_err_syswatch_'
406 'Thread [0-9]* (Thread'
407 'AliFatal'
408 'core dumped'
409 '\.C.*error:.*\.h: No such file'
410 'segmentation'
645f513c 411 'Interpreter error recovered'
2c46f154 412 )
413
414 warningConditions=(
415 'This is serious'
416 )
417
418 local logstatus=0
419 local errorSummary=""
420 local warningSummary=""
421
422 for ((i=0; i<${#errorConditions[@]};i++)); do
423 local tmp=$(grep -m1 -e "${errorConditions[${i}]}" ${log})
424 [[ -n ${tmp} ]] && tmp+=" : "
425 errorSummary+=${tmp}
426 done
427
428 for ((i=0; i<${#warningConditions[@]};i++)); do
429 local tmp=$(grep -m1 -e "${warningConditions[${i}]}" ${log})
430 [[ -n ${tmp} ]] && tmp+=" : "
431 warningSummary+=${tmp}
432 done
433
434 if [[ -n ${errorSummary} ]]; then
435 echo "${errorSummary}"
436 return 1
437 fi
438
439 if [[ -n ${warningSummary} ]]; then
440 echo "${warningSummary}"
441 return 2
442 fi
443
444 return 0
445}
446
f7707400 447parseConfig()
448{
d56eeaab 449 args=("$@")
450
0adcf494 451 #config file
452 configFile=""
453 #where to search for qa files
454 inputList=file.list
455 #working directory
456 workingDirectory="${PWD}"
457 #where to place the final qa plots
458 #outputDirectory="/afs/cern.ch/work/a/aliqa%det/www/"
459 outputDirectory="${workingDirectory}/%DET"
460 #filter out detector option
461 excludeDetectors="EXAMPLE"
462 #logs
463 logDirectory=${workingDirectory}/logs
0adcf494 464 #OCDB storage
b001e589 465 ocdbStorage="raw://"
0adcf494 466 #email to
467 #MAILTO="fbellini@cern.ch"
468
469 #first, check if the config file is configured
470 #is yes - source it so that other options can override it
471 #if any
d56eeaab 472 for opt in "${args[@]}"; do
0adcf494 473 if [[ ${opt} =~ configFile=.* ]]; then
474 eval "${opt}"
7f49f812 475 [[ ! -f ${configFile} ]] && echo "configFile ${configFile} not found, exiting..." && return 1
d56eeaab 476 echo "using config file: ${configFile}"
0adcf494 477 source "${configFile}"
478 break
479 fi
480 done
f7707400 481
482 #then, parse the options as they override the options from file
d56eeaab 483 for opt in "${args[@]}"; do
484 if [[ ! "${opt}" =~ .*=.* ]]; then
0adcf494 485 echo "badly formatted option ${var}, should be: option=value, stopping..."
486 return 1
487 fi
d56eeaab 488 local var="${opt%%=*}"
489 local value="${opt#*=}"
c8973bf8 490 echo "${var}=${value}"
d56eeaab 491 export ${var}="${value}"
f7707400 492 done
493}
494
495guessRunData()
496{
497 #guess the period from the path, pick the rightmost one
498 period=""
499 runNumber=""
500 year=""
501 pass=""
502 legoTrainRunNumber=""
503 dataType=""
911c7ce3 504 originalPass=""
505 originalPeriod=""
7d4afda6 506 anchorYear=""
f7707400 507
17b0cdcd 508 shortRunNumber=""
c8973bf8 509 oldIFS=${IFS}
f7707400 510 local IFS="/"
511 declare -a path=( $1 )
c8973bf8 512 IFS="${oldIFS}"
f7707400 513 local dirDepth=$(( ${#path[*]}-1 ))
514 i=0
515 for ((x=${dirDepth};x>=0;x--)); do
516
517 [[ $((x-1)) -ge 0 ]] && local fieldPrev=${path[$((x-1))]}
518 local field=${path[${x}]}
519 local fieldNext=${path[$((x+1))]}
520
521 [[ ${field} =~ ^[0-9]*$ && ${fieldNext} =~ (.*\.zip$|.*\.root$) ]] && legoTrainRunNumber=${field}
522 [[ -n ${legoTrainRunNumber} && -z ${pass} ]] && pass=${fieldPrev}
911c7ce3 523 [[ ${field} =~ ^LHC[0-9][0-9][a-z].*$ ]] && period=${field%_*} && originalPeriod=${field}
f7707400 524 [[ ${field} =~ ^000[0-9][0-9][0-9][0-9][0-9][0-9]$ ]] && runNumber=${field#000}
525 [[ ${field} =~ ^[0-9][0-9][0-9][0-9][0-9][0-9]$ ]] && shortRunNumber=${field}
526 [[ ${field} =~ ^20[0-9][0-9]$ ]] && year=${field}
527 [[ ${field} =~ ^(^sim$|^data$) ]] && dataType=${field}
528 (( i++ ))
529 done
911c7ce3 530 originalPass=${pass}
17b0cdcd 531 [[ -n ${shortRunNumber} && "${legoTrainRunNumber}" =~ ${shortRunNumber} ]] && legoTrainRunNumber=""
f7707400 532 [[ -z ${legoTrainRunNumber} ]] && pass=${path[$((dirDepth-1))]}
17b0cdcd 533 [[ "${dataType}" =~ ^sim$ ]] && pass="passMC" && runNumber=${shortRunNumber} && originalPass="" #for MC not from lego, the runnumber is identified as lego train number, thus needs to be nulled
84ed81b2 534 [[ -n ${legoTrainRunNumber} ]] && pass+="_lego${legoTrainRunNumber}"
0c9bef99 535
c8973bf8 536 #modify the OCDB: set the year
17b0cdcd 537 if [[ ${dataType} =~ sim ]]; then
538 anchorYear=$(for x in $mcProductionMap ; do [[ "${x}" =~ ${originalPeriod} ]] && echo ${x} && break; done)
539 anchorYear=${anchorYear#*=}
7d4afda6 540 ocdbStorage=$(setYear ${anchorYear} ${ocdbStorage})
541 else
542 ocdbStorage=$(setYear ${year} ${ocdbStorage})
543 fi
c8973bf8 544
2a6472ef 545 #if [[ -z ${dataType} || -z ${year} || -z ${period} || -z ${runNumber}} || -z ${pass} ]];
c8973bf8 546 if [[ -z ${runNumber}} ]]
0c9bef99 547 then
548 #error condition
549 return 1
550 else
551 #ALL OK
552 return 0
553 fi
f7707400 554}
555
556substituteDetectorName()
557{
558 local det=$1
559 local dir=$2
560 [[ ${dir} =~ \%det ]] && det=${det,,} && echo ${dir/\%det/${det}}
561 [[ ${dir} =~ \%DET ]] && det=${det} && echo ${dir/\%DET/${det}}
562}
563
7f49f812 564get_realpath()
565{
566 if [[ -f "$1" ]]
567 then
568 # file *must* exist
569 if cd "$(echo "${1%/*}")" &>/dev/null
570 then
571 # file *may* not be local
572 # exception is ./file.ext
573 # try 'cd .; cd -;' *works!*
574 local tmppwd="$PWD"
575 cd - &>/dev/null
576 else
577 # file *must* be local
578 local tmppwd="$PWD"
579 fi
580 else
581 # file *cannot* exist
582 return 1 # failure
583 fi
584 # reassemble realpath
585 echo "$tmppwd"/"${1##*/}"
586 return 0 # success
587}
588
c8973bf8 589setYear()
590{
591 #set the year
592 # ${1} - year to be set
593 # ${2} - where to set the year
594 local year1=$(guessYear ${1})
595 local year2=$(guessYear ${2})
596 local path=${2}
597 [[ ${year1} -ne ${year2} && -n ${year2} && -n ${year1} ]] && path=${2/\/${year2}\//\/${year1}\/}
598 echo ${path}
599 return 0
600}
601
602guessYear()
603{
604 #guess the year from the path, pick the rightmost one
605 local IFS="/"
606 declare -a pathArray=( ${1} )
607 local field
608 local year
609 for field in ${pathArray[@]}; do
610 [[ ${field} =~ ^20[0-9][0-9]$ ]] && year=${field}
611 done
612 echo ${year}
613 return 0
614}
615
69b2d32e 616hostInfo(){
617#
618# Hallo world - Print AliRoot/Root/Alien system info
619#
620
621#
622# HOST info
623#
624 echo --------------------------------------
625 echo
626 echo HOSTINFO
627 echo
628 echo HOSTINFO HOSTNAME" "$HOSTNAME
629 echo HOSTINFO DATE" "`date`
630 echo HOSTINFO gccpath" "`which gcc`
631 echo HOSTINFO gcc version" "`gcc --version | grep gcc`
632 echo --------------------------------------
633
634#
635# ROOT info
636#
637 echo --------------------------------------
638 echo
639 echo ROOTINFO
640 echo
641 echo ROOTINFO ROOT" "`which root`
642 echo ROOTINFO VERSION" "`root-config --version`
643 echo
644 echo --------------------------------------
645
646
647#
648# ALIROOT info
649#
650 echo --------------------------------------
651 echo
652 echo ALIROOTINFO
653 echo
654 echo ALIROOTINFO ALIROOT" "`which aliroot`
655 echo ALIROOTINFO VERSION" "`echo $ALICE_LEVEL`
656 echo ALIROOTINFO TARGET" "`echo $ALICE_TARGET`
657 echo
658 echo --------------------------------------
659
660#
661# Alien info
662#
663#echo --------------------------------------
664#echo
665#echo ALIENINFO
666#for a in `alien --printenv`; do echo ALIENINFO $a; done
667#echo
668#echo --------------------------------------
669
670#
671# Local Info
672#
673 echo PWD `pwd`
674 echo Dir
675 ls -al
676 echo
677 echo
678 echo
679}
680
c8973bf8 681main "$@"