]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/FORWARD/analysis2/qa/RunQAMT.sh
Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / qa / RunQAMT.sh
1 #!/bin/bash
2 #
3 # This script runs the Forward QA for the specified production number
4 #
5 # The scripts downloads and runs the single run QA in parallel 
6 #
7
8 # --- Some aux files -------------------------------------------------
9 if test "X$QA_FWD" = "X" ; then 
10     QA_FWD=$ALICE_ROOT/PWGLF/FORWARD/analysis2/qa
11 fi 
12 style=${QA_FWD}/style.css 
13 favicon=${QA_FWD}/fmd_favicon.png
14 logo=${QA_FWD}/fmd_logo.png
15 script=${QA_FWD}/script.js
16 topmk=${QA_FWD}/makeIndex.sh
17
18 # --- Check AliEn token ----------------------------------------------
19 check_token()
20 {
21     uid=`id -u`
22     genv_file=/tmp/gclient_env_${uid}
23     
24     if test ! -f ${genv_file} ; then 
25         echo "No such file: ${genv_file}, please do alien-token-init" \
26             >/dev/stderr
27         exit 1
28     fi
29     . ${genv_file}
30     alien-token-info | grep -q "Token is still valid"
31     if test $? -ne 0 ; then 
32         echo "Token not valid, please re-new" > /dev/stderr 
33         exit 1
34     fi
35 }
36
37 # --- Diagnostics output ---------------------------------------------
38 verb=0
39 print() { 
40     local col=$1 ; shift 
41     local lvl=$1 ; shift 
42     local opt=
43     if test $lvl -gt $verb; then return ; fi 
44     case $1 in 
45         -*) opt=$1 ; shift ;; 
46     esac
47     echo -e ${opt} "\e[${col}m$*\e[0m"
48     # echo -e ${opt} "\e[${col}m$*\e[0m"
49 }
50 mess()
51 {
52     print 95 $@ 
53 }
54
55 err() 
56 {
57     echo -e "\e[1mError: \e[91m$*\e[0m" > /dev/stderr 
58 }
59 warn()
60 {
61     echo -e "\e[1mWarning: \e[93m$*\e[0m" > /dev/stderr 
62 }
63 info() 
64 {
65     print 96 0 $@ 
66 }
67 ok() 
68 {
69     print 92 0 "OK"
70 }
71
72 # --- Handling of exit -----------------------------------------------
73 lock=
74 handle_exit()
75 {
76     if test "x$lock" = "x" ; then return ; fi 
77     if test "x$store" != "x" && test "x${top}" != "x" ; then 
78         chmod -R g+rwX ${top}/${proddir} >> ${redir} 2>&1
79         chmod -R g+rwX ${top}/$store >> ${redir} 2>&1
80     fi
81     rm -rf $lock 
82 }
83 trap handle_exit EXIT
84
85 # --- Handling of errors ---------------------------------------------
86 last=
87 handle_err()
88 {
89     err "$last"
90     exit 1
91 }
92 enable_trap()
93 {
94     trap handle_err ERR
95 }
96 disable_trap()
97 {
98     trap - ERR
99 }
100
101 # --- Check the lock -------------------------------------------------
102 check_lock()
103 {
104     local loc=$1 
105     lock=$loc/.lock
106
107     if test -f $lock ; then 
108         err "Another QA process is already running:"
109         err "Content of ${lock}:"
110         cat $lock > /dev/stderr 
111         trap - EXIT
112         exit 1
113     fi 
114     local now=`date` 
115     cat <<-EOF > $lock
116         Process: $$
117         User:    $USER
118         Start:   $now
119         EOF
120 }
121
122 # --- Parse production information -----------------------------------
123 parse_prod()
124 {
125     prodyear=`echo $prodfull | sed 's/LHC\(..\).*/\1/'` 
126     prodletter=`echo $prodfull | sed "s/LHC${prodyear}\(.\).*/\1/"` 
127     prodpost=`echo $prodfull | sed "s/LHC${prodyear}${prodletter}//"` 
128 }
129
130 parse_pass()
131 {
132     passno=`echo $passfull | sed 's/.*pass\([0-9]*\).*/\1/'`  
133     passpost=`echo $passfull | sed -n "s/.*pass${passno}_//p"` 
134     passpre=`echo $passfull | sed -n "s/pass.*//p"` 
135 }
136
137 # --- Extract parts from the found path ------------------------------
138 force=0
139 year=0
140 passfull=
141 passno=0
142 passpost=
143 passpre=
144 prodfull=
145 prodyear=0
146 prodletter=
147 prodpost=
148 remainder=
149 qanumber=0
150 barrel=0
151
152 # --- Append path element --------------------------------------------
153 append_to_path()
154 {
155     local tmp=$1 ; shift 
156     local add=$1
157     if test "x$tmp" != "x" ; then tmp="${tmp}/" ; fi 
158     echo ${tmp}${add}
159 }
160
161 # --- Get a list of files to get -------------------------------------
162 file=trending.root
163 other=QAresults.root
164 files=
165 path=
166 numf=0
167 from_local=0
168 type=data
169 passid=
170 mc=0
171 get_filelist()
172 {
173     mess 3 "Getting file list" 
174
175     local datd=data
176     local esdd=ESDs/
177     if test ${barrel} -gt 0 ; then
178         esdd=
179     fi
180     if test ${barrel} -gt 1 ; then      
181         file=trending_barrel.root
182         other=QAresults_barrel.root
183     fi
184     if test $mc -gt 0 ; then 
185         datd=sim 
186         type=sim
187         esdd= 
188     fi 
189
190     local post=${passpost}
191     case x$post in 
192         x_*) ;; 
193         x) ;; 
194         *) post="_${post}" ;; 
195     esac
196
197     local paid=
198     if test "x${passpre}pass${passno}${post}" != "x$passfull" ; then 
199         passpre=
200         paid=${passfull}
201         post=
202     elif echo "$passno" | grep -q -E '^[0-9]*[.]?[0-9]*$' ; then 
203         if test "x$passfull" != "x" && test $passno -gt 0 ; then 
204             paid=pass${passno}
205         fi
206     else
207         paid=${passfull}
208         passpre=
209         post=
210     fi
211     passid=${paid}
212     if test $mc -gt 0 ; then passid="passMC" ; fi 
213
214     local search=
215     if test "x$path" = "x" ; then 
216         # Assume official productions 
217         path=/alice/${datd}/${year}/${prodfull}/
218         search="${esdd}${passpre}${paid}${post}"
219     else
220         search="*"
221     fi
222
223     if test $qanumber -gt 0 ; then 
224         qapost=`printf "QA%02d" $qanumber` 
225         search=`append_to_path "$search" $qapost` 
226     fi
227     
228     search=`append_to_path "$search" $file` 
229
230     cat <<EOF
231         Path:                   $path
232         Search:                 $search
233 EOF
234     if test $from_local -lt 1 ; then 
235
236         mess 1 "Get list of files from AliEn - can take minutes - be patient"
237         mess 2 "alien_find ${path} ${search}"
238         files=`alien_find ${path} ${search} | \
239           grep -v "\(files found\|AND THE\)" 2>> ${redir}` 
240     else 
241         files=`ls ${top}/${store}/*/input.root | \
242           sed 's,${top}/${store}/,,g'`
243     fi
244     for i in $files ; do 
245         let numf=$numf+1
246     done 
247     mess 1 -n "Total of $numf files ... "
248     ret=$numf
249     if test $maxf -lt 0 ; then 
250         mess 1 "using all" 
251     else
252         mess 1 "using $maxf first of these"
253         ret=$maxf
254     fi
255     return $ret
256 }
257
258 # --- Change permissions on files ------------------------------------
259 fix_perm()
260 {
261     local tgt=$1
262     local opt= 
263     if test -d $tgt ; then opt="-R" ; fi 
264     chmod ${opt} g+rwX $tgt >> /dev/null 2>&1 
265     chmod ${opt} o+rX $tgt >> /dev/null 2>&1 
266 }
267
268 # --- Check if a file is OK ------------------------------------------
269 docheck=1
270 check_file()
271 {
272     if test $docheck -lt 1 ; then return 0; fi 
273     root -l -b  <<EOF >> ${redir} 2>&1 
274 .L ${QA_FWD}/CheckQAFile.C
275 CheckQAFile("$1","QA");
276 .q
277 EOF
278     local ret=$? 
279     mess 2 "Check of $1 -> $ret"
280     # rm -f ${scr}.C 
281     return $ret
282 }
283
284 # --- Analyse a file -------------------------------------------------
285 analyse_file()
286 {
287     local dir=`dirname $1` 
288     local inp=`basename $1` 
289     local r=$2
290     local out=trending.root 
291     # `echo $inp | sed 's/trending_/tree_/'` 
292     local ret=0
293     mess 2 -n "Analysing $inp -> $out ... "
294
295     if test -f $dir/$out ; then 
296         if test $force -lt 1 ; then 
297             mess 2 "exits"
298             return 0
299         fi
300         rm -f $dir/$out
301     fi
302
303     
304     mess 3 "runQA.sh '$inp' '$type' '$prodyear' '$prodfull' '$passid' '$r'"
305     (cd $dir 
306         for i in QABase QAPlotter QARing QAStructs QATrender ; do 
307             rm -f ${i}*
308             ln -s ../${i}* . 
309         done 
310         ${QA_FWD}/runQA.sh \
311             "$inp" "$type" $prodyear "$prodfull" "$passid" "$r" > runQA.log 2>&1
312         ret=$? ) 
313     if test ! -f $dir/trending.root ; then ret=1 ; fi
314     mess 2 " -> $ret"
315     if test $ret -ne 0 ; then 
316         err "Failed to analyse $1"
317     fi
318     return $ret
319 }
320
321 # --- Download a single file -----------------------------------------
322 also_results=0
323 analyse_run()
324 {
325     local source=$1 ; shift 
326     local store=$1 ; shift 
327     local r=`echo $1 | sed 's/^0*//'` ; shift 
328     local rr=`printf %09d $r`
329     local o=${store}/${rr}/input.root
330     mkdir -p ${store}/${rr}
331
332     mess 2 -n "$source -> $o ... "
333     if test -f $o && test $force -lt 2; then 
334         mess 2 "exists" 
335         # sleep 1
336     else
337         rm -f ${o}
338         mess 2 -n "copying ... " 
339         alien_cp alien:${source} file:${o} >> ${redir} 2>&1 
340         fix_perm $o 
341         mess 2 "done"
342     fi
343     if test ! -f $o ; then return 1 ; fi 
344
345     if test $also_results -gt 0 ; then 
346         local s=`dirname ${source}`/${other}
347         local q=${store}/`basename $other .root`_${r}.root
348
349         mess 2 -n "$s -> $q ... "
350         if test -f $q && test $force -lt 2 ; then 
351             mess 2 "exists" 
352         else
353             rm -rf ${q}
354             mess 2 -n "copying ... " 
355             alien_cp alien:${s} file:${q} >> ${redir} 2>&1 
356             fix_perm $q
357             mess 2 "done"
358         fi
359     fi
360
361         
362     check_file ${o} 
363     local ret=$? 
364     case $ret in 
365         0|2) : ;; 
366         1|3|4|5|6) return 2 ;; 
367     esac
368
369     analyse_file ${o} ${r}
370
371     return 0
372 }
373
374 # --- Submit run analysis to background ------------------------------
375 submit_runs()
376 {
377     local out=$1 ; shift
378     local sta=$1 ; shift 
379     local max=$1 ; shift
380     
381     local joblist=
382     local counter=0
383     mess 5 "Submitting $maxjobs jobs from $sta/$maxf" 
384     for i in $@ ; do 
385         let cur=$sta+$counter
386
387         local r
388         if test $from_local -lt 1 ; then 
389             local b=`echo $i | sed -e "s,${path},,"` 
390             r=`echo $b | sed -e "s,/.*,,"` 
391         else
392              r=`basename \`dirname $i\` | sed 's/^0*//'`
393         fi
394
395         local m=`printf "%3d/%3d: %s\n" $cur $max $r` 
396         info "$m"
397         runs[$counter]=$r
398
399         let counter=$counter+1
400         
401         analyse_run $i $out $r &
402         j=`jobs %% | sed -e 's/^[^0-9]*//' -e 's/[^0-9]*$//'` 
403         joblist="$joblist $j"
404     done
405     
406     counter=0
407     mess 5 "will wait for jobs $joblist"
408     for i in $joblist ; do 
409         mess 5 "waiting for $i of $joblist"
410         wait %$i
411         mess 5 "Analysing ${runs[$counter]} returned $?" 
412         let counter=$counter+1
413     done
414 }
415     
416 # --- Analyse each run in turn ---------------------------------------
417 maxjobs=`grep "processor" /proc/cpuinfo | wc -l`
418 analyse_runs()
419 {
420     local out=$1 ; shift 
421     local max=$1 ; shift 
422     
423     local queued=0
424     local counter=0
425     local start=0
426     local list=
427     while test $# -gt 0 ; do 
428         if test $counter -ge $max ; then 
429             break;
430         fi
431
432         list="$list $1" 
433         shift 
434         let queued=$queued+1 
435         let counter=$counter+1 
436
437         if test $queued -eq 1 ; then 
438             start=$counter
439         fi
440         
441         if test $queued -ge $maxjobs ; then 
442             mess 1 "Submitting $queued jobs from $start/$max"
443             submit_runs $out $start $max $list 
444             list=
445             queued=0 
446         fi
447     done
448     if test $queued -gt 0 ; then 
449         mess 1 "Submitting $queued jobs from $start/$max"
450         submit_runs $out $start $max $list 
451     fi
452 }
453
454 # --- Copy style -----------------------------------------------------
455 copy_aliroot_file()
456 {
457     local file=$1 
458     if test ! -f $file ; then return ; fi 
459     base=`basename $file`
460     rm -f $base 
461     cp $file $base 
462     fix_perm $base
463 }
464 copy_style()
465 {
466     copy_aliroot_file $style
467 }       
468
469 # --- Run the final trending -----------------------------------------
470 variance=1
471 make_trend()
472 {
473     local dir=$1 
474     local ret=0
475     info -n "Analysing for trend $dir ... "
476     (cd $dir 
477         mess 1 "hadd trending.root 000*/trending.root"
478         rm -f trending.root 
479         hadd -k trending.root 000*/trending.root 
480         if test $? -eq 0 && test -f trending.root ; then 
481           ${QA_FWD}/periodQA.sh trending.root 
482           ret=$?
483         else 
484           ret=1
485         fi
486     ) >>${redir} 2>&1
487     if test $ret -ne 0 ; then 
488         err "Failed to make trending in $dir"
489     else
490         ok
491     fi
492     return $ret
493 }
494
495
496 # --- Help output ----------------------------------------------
497 usage()
498 {
499     cat <<EOF
500 Usage: $0 [OPTIONS] -p PRODUCTION [-P PASS]
501
502 Options:
503   -b,--barrel       MODE       Fetch barrel data              [$barrel]
504   -d,--directory    DIR        Search custom AliEn directory  [$path]
505   -f,--force                   Force re-run analysis          [$force]
506   -h,--help                    This help 
507   -i,--no-index                Do not make index              [$index]
508   -l,--log-file                Log file output                [$redir]
509   -L,--local                   Local trending_<X>.root files  [$from_local]
510   -m,--max-files    NUMBER     Max number of files to get     [$maxf]
511   -M,--max-jobs     NUMBER     Max number of consequtive jobs [$maxjobs]
512   -p,--production   IDENTIFIER Production identifier          [$prodfull]
513   -P,--pass         IDENTIFIER Pass identifier                [$passfull]
514   -Q,--qa-number    NUMBER     Custom QA id                   [$qanumber]
515   -R,--also-results            Also get QAresults.root/run    [$also_results]
516   -t,--top          DIRECTORY  Output directory               [$top]
517   -T,--min-max                 Errors=min/max
518   -v,--verbose                 Increase verbosity             [$verb]
519   -V,--variance                Errors=variance                [$variance]
520
521 Production identifiers are of the form LHC11h, LHC11h3, or LHC11h_2. 
522 Pass identifers are of the form pass2, pass1_HLT, or cpass1.  
523 If barrel mode>0, then do not assume ESD directory.  
524 If barrel mode>1, then get trending_barrel.root and QAresults_barrel.root
525 Option -d is for hand-made QA passes. 
526 If optiond -d is not specified then official QA passes are assumed.
527 EOF
528 }
529
530
531 # --- Parse command line options -------------------------------------
532 redir=/dev/null
533 maxf=-1
534 top=.
535 index=0
536 while test $# -gt 0 ; do 
537     case $1 in 
538         -b|--barrel)       barrel=$2          ; shift ;;
539         -d|--directory)    path=$2            ; shift ;;
540         -f|--force)        let force=$force+1 ;; 
541         -h|--help)         usage              ; exit 0 ;; 
542         -i|--index)        index=1            ;; 
543         -l|--log-file)     redir=             ;; 
544         -L|--local)        from_local=1       ;;
545         -m|--max-files)    maxf=$2            ; shift ;; 
546         -M|--max-jobs)     maxjobs=$2         ; shift ;;
547         -p|--production)   prodfull=$2        ; shift ; parse_prod ;;
548         -P|--pass)         passfull=$2        ; shift ; parse_pass ;;
549         -Q|--qa-number)    qanumber=$2        ; shift ;;
550         -R|--also-results) also_results=1     ;; 
551         -t|--top)          top=$2             ; shift ;;
552         -T|--min-max)      variance=0         ;; 
553         -v|--verbose)      let verb=$verb+1   ;; 
554         -V|--variance)     variance=1         ;;
555         *) echo "$0: Unknown argument: $1" > /dev/stderr ; exit 1 ;; 
556     esac
557     shift
558 done
559 # === Initial setup ==================================================
560 # --- Check for AliEn token ------------------------------------------
561 check_token
562
563 # --- Check settings -------------------------------------------------
564 if test "x$prodfull" = "x" ; then
565     err "No production specified" 
566     exit 1
567 fi 
568 if test "x$prodpost" = "x" && test "x$passfull" = "x" ; then 
569     err "No pass specified for non-MC production"
570     exit 1
571 elif test "x$passfull" = "x" || test "x$passfull" = "xpassMC"; then 
572     warn "No pass specified, assuming MC"
573     passfull=
574     mc=1
575 fi 
576
577 # --- Construct output -----------------------------------------------
578 proddir=
579 passdir=
580 store=
581 year=20${prodyear}
582 if test $mc -gt 0 ; then 
583     proddir=${prodfull}
584     passdir=passMC
585     store=sim
586 else 
587     proddir=LHC${prodyear}${prodletter}
588     store=data
589     if test "x$passno" = "x" ; then 
590         err "No pass number"
591     fi 
592     if test "x$passpre" != "x" ; then 
593         passdir=${passpre}
594     fi
595     passdir=${passdir}pass${passno}
596     if test "x$passpost" != "x" ; then 
597         passdir=${passdir}_${passpost}
598     fi
599     if test "x$remainder" != "x" ; then 
600         passdir=${passdir}/${remainder}
601     fi
602 fi 
603 store=${store}/${year}/${proddir}/${passdir}
604 if test ! "x$qanumber" = "x" && test $qanumber -gt 0 ; then 
605     store=${store}_QA${qanumber}
606 fi
607 mkdir -p ${top}/$store 
608 fix_perm ${top}/$store
609
610 # --- Check for logging ----------------------------------------------
611 if test "x$redir" = "x" ; then 
612     redir=${top}/$store/qa.log 
613     rm -f $redir
614     fix_perm $redir
615 fi
616
617 check_lock ${top}/$store
618
619 # --- Some friendly information --------------------------------------
620 cat <<EOF
621         Year:                   $year
622         Production:             $prodfull 
623           Year:                 $prodyear
624           Letter:               $prodletter
625           Suffix:               $prodpost
626         Pass:                   $passfull
627           Number:               $passno
628           Prefix:               $passpre
629           Postfix:              $passpost
630         Remainder               $remainder
631           QA number             $qanumber
632         Output directory:       ${store}
633         Lock file:              ${lock}
634         Log:                    ${redir}
635         Force:                  ${force}
636         Use variance:           ${variance}
637         Use pre-downloaded:     ${from_local}
638 EOF
639
640 # --- Do a search to find our files ----------------------------------
641 get_filelist
642 nf=$?
643 if test $nf -le 0 ; then 
644     err "No files to process"
645     exit 1
646 fi
647 if test $maxf -gt 0 && test $maxf -lt $numf ; then 
648     numf=$maxf 
649 fi
650
651 # --- Copy scripts to target and compile -----------------------------
652 for i in QABase.h QAPlotter.C QARing.h QAStructs.h QATrender.C ; do
653     cp ${QA_FWD}/$i ${store}/${i}
654     rm -f ${store}/`echo $i | tr '.' '_'`.{so,d}
655     fix_perm ${store}/${i}
656 done
657 mess 1 "Compiling QATrender.C"
658 (cd $store && root -l -b <<EOF 
659 gROOT->LoadMacro("QABase.h++g");
660 gROOT->LoadMacro("QATrender.C++g");
661 .q
662 EOF
663 ) 2>> ${redir}
664 mess 1 "Compiling QAPlotter.C"
665 (cd $store && root -l -b <<EOF 
666 gROOT->LoadMacro("QABase.h++g");
667 gROOT->LoadMacro("QAPlotter.C++g");
668 .q
669 EOF
670 ) 2>> ${redir}
671 (cd ${store} && for i in *.so *.d ; do fix_perm $i ; done)
672
673 # --- Now get and analyse each run -----------------------------------
674 analyse_runs ${top}/$store $numf $files
675
676 # --- Now analyse all runs -------------------------------------------
677 make_trend ${top}/$store
678
679 # --- Make index files -----------------------------------------------
680 if test $index -gt 0 ; then 
681     info -n "Making index ... "
682     desc="For more information see <a href='https://twiki.cern.ch/twiki/"
683     desc="${desc}bin/viewauth/ALICE/FMDQA'>TWiki pages</a>."
684     $topmk --title "QA for the FMD" \
685         --description "$desc" \
686         --link \
687         --max-depth 4 \
688         --output index.html 
689     # >> ${redir} 2>&1 
690     fix_perm index.html
691     copy_aliroot_file $script
692     ok
693 fi 
694 chmod -R g+rwX ${top}/${proddir} >> ${redir} 2>&1
695
696
697 #
698 # EOF
699 #