]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/FORWARD/analysis2/qa/RunQAMT.sh
Merge remote-tracking branch 'origin/master' into mergingFlat
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / qa / RunQAMT.sh
1 #!/bin/bash
2 #
3 # This script runs the Forwardqq 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 search=
172 get_filelist()
173 {
174     mess 3 "Getting file list" 
175
176     local datd=data
177     local esdd=ESDs/
178     if test ${barrel} -gt 0 ; then
179         esdd=
180     fi
181     if test ${barrel} -gt 1 ; then      
182         file=trending_barrel.root
183         other=QAresults_barrel.root
184     fi
185     if test $mc -gt 0 ; then 
186         datd=sim 
187         type=sim
188         esdd= 
189     fi 
190
191     local post=${passpost}
192     case x$post in 
193         x_*) ;; 
194         x) ;; 
195         *) post="_${post}" ;; 
196     esac
197
198     local paid=
199     if test "x${passpre}pass${passno}${post}" != "x$passfull" ; then 
200         passpre=
201         paid=${passfull}
202         post=
203     elif echo "$passno" | grep -q -E '^[0-9]*[.]?[0-9]*$' ; then 
204         if test "x$passfull" != "x" && test $passno -gt 0 ; then 
205             paid=pass${passno}
206         fi
207     else
208         paid=${passfull}
209         passpre=
210         post=
211     fi
212     passid=${paid}
213     if test $mc -gt 0 ; then passid="passMC" ; fi 
214
215     search=
216     if test "x$path" = "x" ; then 
217         # Assume official productions 
218         path=/alice/${datd}/${year}/${prodfull}/
219         search="${esdd}${passpre}${paid}${post}"
220     else
221         search="*"
222     fi
223
224     if test $qanumber -gt 0 ; then 
225         qapost=`printf "QA%02d" $qanumber` 
226         search=`append_to_path "$search" $qapost` 
227     fi
228     
229     search=`append_to_path "$search" $file` 
230
231     cat <<EOF
232         Path:                   $path
233         Search:                 $search
234 EOF
235     if test $from_local -lt 1 ; then 
236
237         mess 1 "Get list of files from AliEn - can take minutes - be patient"
238         mess 2 "alien_find ${path} ${search}"
239         files=`alien_find ${path} ${search} | \
240           grep -v "\(files found\|AND THE\)" 2>> ${redir}` 
241     else 
242         files=`ls ${top}/${store}/*/input.root | \
243           sed 's,${top}/${store}/,,g'`
244     fi
245     for i in $files ; do 
246         let numf=$numf+1
247     done 
248     mess 1 -n "Total of $numf files ... "
249     ret=$numf
250     if test $maxf -lt 0 ; then 
251         mess 1 "using all" 
252     else
253         mess 1 "using $maxf first of these"
254         ret=$maxf
255     fi
256     return $ret
257 }
258
259 # --- Change permissions on files ------------------------------------
260 fix_perm()
261 {
262     local tgt=$1
263     local opt= 
264     if test -d $tgt ; then opt="-R" ; fi 
265     chmod ${opt} g+rwX $tgt >> /dev/null 2>&1 
266     chmod ${opt} o+rX $tgt >> /dev/null 2>&1 
267 }
268
269 # --- Check if a file is OK ------------------------------------------
270 docheck=1
271 check_file()
272 {
273     if test $docheck -lt 1 ; then return 0; fi 
274     root -l -b  <<EOF >> ${redir} 2>&1 
275 .L ${QA_FWD}/CheckQAFile.C
276 CheckQAFile("$1","QA");
277 .q
278 EOF
279     local ret=$? 
280     mess 2 "Check of $1 -> $ret"
281     # rm -f ${scr}.C 
282     return $ret
283 }
284
285 # --- Analyse a file -------------------------------------------------
286 analyse_file()
287 {
288     local dir=`dirname $1` 
289     local inp=`basename $1` 
290     local r=$2
291     local out=trending.root 
292     # `echo $inp | sed 's/trending_/tree_/'` 
293     local ret=0
294     mess 2 -n "Analysing $inp -> $out ... "
295
296     if test -f $dir/$out ; then 
297         if test $force -lt 1 ; then 
298             mess 2 "exits"
299             return 0
300         fi
301         rm -f $dir/$out
302     fi
303
304     
305     mess 3 "runQA.sh '$inp' '$type' '$prodyear' '$prodfull' '$passid' '$r'"
306     (cd $dir 
307         for i in QABase QAPlotter QARing QAStructs QATrender ; do 
308             rm -f ${i}*
309             ln -s ../${i}* . 
310         done 
311         ${QA_FWD}/runQA.sh \
312             "$inp" "$type" $prodyear "$prodfull" "$passid" "$r" > runQA.log 2>&1
313         ret=$? ) 
314     if test ! -f $dir/trending.root ; then ret=1 ; fi
315     mess 2 " -> $ret"
316     if test $ret -ne 0 ; then 
317         err "Failed to analyse $1"
318     fi
319     return $ret
320 }
321
322 # --- Download a single file -----------------------------------------
323 also_results=0
324 analyse_run()
325 {
326     local source=$1 ; shift 
327     local store=$1 ; shift 
328     local r=`echo $1 | sed 's/^0*//'` ; shift 
329     local rr=`printf %09d $r`
330     local o=${store}/${rr}/input.root
331     mkdir -p ${store}/${rr}
332
333     mess 2 -n "$source ($store) -> $o ... "
334     if test -f $o && test $force -lt 2; then 
335         mess 2 "exists" 
336         # sleep 1
337     else
338         rm -f ${o}
339         mess 2 -n "copying ... " 
340         alien_cp alien:${source} file:${o} >> ${redir} 2>&1 
341         fix_perm $o 
342         mess 2 "done"
343     fi
344     if test ! -f $o ; then return 1 ; fi 
345
346     if test $also_results -gt 0 ; then 
347         local s=`dirname ${source}`/${other}
348         local q=${store}/`basename $other .root`_${r}.root
349
350         mess 2 -n "$s -> $q ... "
351         if test -f $q && test $force -lt 2 ; then 
352             mess 2 "exists" 
353         else
354             rm -rf ${q}
355             mess 2 -n "copying ... " 
356             alien_cp alien:${s} file:${q} >> ${redir} 2>&1 
357             fix_perm $q
358             mess 2 "done"
359         fi
360     fi
361
362         
363     check_file ${o} 
364     local ret=$? 
365     case $ret in 
366         0|2) : ;; 
367         1|3|4|5|6) return 2 ;; 
368     esac
369
370     analyse_file ${o} ${r}
371
372     return 0
373 }
374
375 # --- Submit run analysis to background ------------------------------
376 submit_runs()
377 {
378     local out=$1 ; shift
379     local sta=$1 ; shift 
380     local max=$1 ; shift
381     
382     local joblist=
383     local counter=0
384     mess 5 "Submitting $maxjobs jobs from $sta/$maxf" 
385     for i in $@ ; do 
386         let cur=$sta+$counter
387
388         local r
389         if test $from_local -lt 1 ; then 
390             local b=`echo $i | sed -e "s,${path}/*,,"` 
391             if test "x$search" != "x" ; then 
392                 b=`echo $b | sed -s "s,/*${search},,"`
393             fi
394             r=`echo $b | sed -e "s,/.*,," | sed 's/^0*//'` 
395             # local b=`basename $(dirname $i)`
396             # r=`echo $b | sed 's/^0*//'`
397         else
398              r=`basename \`dirname $i\` | sed 's/^0*//'`
399         fi
400
401         local m=`printf "%3d/%3d: %s\n" $cur $max $r` 
402         info "$m"
403         runs[$counter]=$r
404
405         let counter=$counter+1
406         
407         analyse_run $i $out $r &
408         j=`jobs %% | sed -e 's/^[^0-9]*//' -e 's/[^0-9]*$//'` 
409         joblist="$joblist $j"
410     done
411     
412     counter=0
413     mess 5 "will wait for jobs $joblist"
414     for i in $joblist ; do 
415         mess 5 "waiting for $i of $joblist"
416         wait %$i
417         mess 5 "Analysing ${runs[$counter]} returned $?" 
418         let counter=$counter+1
419     done
420 }
421     
422 # --- Analyse each run in turn ---------------------------------------
423 maxjobs=`grep "processor" /proc/cpuinfo | wc -l`
424 analyse_runs()
425 {
426     local out=$1 ; shift 
427     local max=$1 ; shift 
428     
429     local queued=0
430     local counter=0
431     local start=0
432     local list=
433     while test $# -gt 0 ; do 
434         if test $counter -ge $max ; then 
435             break;
436         fi
437
438         list="$list $1" 
439         shift 
440         let queued=$queued+1 
441         let counter=$counter+1 
442
443         if test $queued -eq 1 ; then 
444             start=$counter
445         fi
446         
447         if test $queued -ge $maxjobs ; then 
448             mess 1 "Submitting $queued jobs from $start/$max"
449             submit_runs $out $start $max $list 
450             list=
451             queued=0 
452         fi
453     done
454     if test $queued -gt 0 ; then 
455         mess 1 "Submitting $queued jobs from $start/$max"
456         submit_runs $out $start $max $list 
457     fi
458 }
459
460 # --- Copy style -----------------------------------------------------
461 copy_aliroot_file()
462 {
463     local file=$1 
464     if test ! -f $file ; then return ; fi 
465     base=`basename $file`
466     rm -f $base 
467     cp $file $base 
468     fix_perm $base
469 }
470 copy_style()
471 {
472     copy_aliroot_file $style
473 }       
474
475 # --- Run the final trending -----------------------------------------
476 variance=1
477 make_trend()
478 {
479     local dir=$1 
480     local ret=0
481     info -n "Analysing for trend $dir ... "
482     (cd $dir 
483         mess 1 "hadd trending.root 000*/trending.root"
484         rm -f trending.root 
485         hadd -k trending.root 000*/trending.root 
486         if test $? -eq 0 && test -f trending.root ; then 
487           ${QA_FWD}/periodQA.sh trending.root 
488           ret=$?
489         else 
490           ret=1
491         fi
492     ) >>${redir} 2>&1
493     if test $ret -ne 0 ; then 
494         err "Failed to make trending in $dir"
495     else
496         ok
497     fi
498     return $ret
499 }
500
501
502 # --- Help output ----------------------------------------------
503 usage()
504 {
505     cat <<EOF
506 Usage: $0 [OPTIONS] -p PRODUCTION [-P PASS]
507
508 Options:
509   -b,--barrel       MODE       Fetch barrel data              [$barrel]
510   -d,--directory    DIR        Search custom AliEn directory  [$path]
511   -f,--force                   Force re-run analysis          [$force]
512   -h,--help                    This help 
513   -i,--no-index                Do not make index              [$index]
514   -l,--log-file                Log file output                [$redir]
515   -L,--local                   Local trending_<X>.root files  [$from_local]
516   -m,--max-files    NUMBER     Max number of files to get     [$maxf]
517   -M,--max-jobs     NUMBER     Max number of consequtive jobs [$maxjobs]
518   -p,--production   IDENTIFIER Production identifier          [$prodfull]
519   -P,--pass         IDENTIFIER Pass identifier                [$passfull]
520   -Q,--qa-number    NUMBER     Custom QA id                   [$qanumber]
521   -R,--also-results            Also get QAresults.root/run    [$also_results]
522   -t,--top          DIRECTORY  Output directory               [$top]
523   -T,--min-max                 Errors=min/max
524   -v,--verbose                 Increase verbosity             [$verb]
525   -V,--variance                Errors=variance                [$variance]
526
527 Production identifiers are of the form LHC11h, LHC11h3, or LHC11h_2. 
528 Pass identifers are of the form pass2, pass1_HLT, or cpass1.  
529 If barrel mode>0, then do not assume ESD directory.  
530 If barrel mode>1, then get trending_barrel.root and QAresults_barrel.root
531 Option -d is for hand-made QA passes. 
532 If optiond -d is not specified then official QA passes are assumed.
533 EOF
534 }
535
536
537 # --- Parse command line options -------------------------------------
538 redir=/dev/null
539 maxf=-1
540 top=.
541 index=1
542 while test $# -gt 0 ; do 
543     case $1 in 
544         -b|--barrel)       barrel=$2          ; shift ;;
545         -d|--directory)    path=$2            ; shift ;;
546         -f|--force)        let force=$force+1 ;; 
547         -h|--help)         usage              ; exit 0 ;; 
548         -i|--index)        index=1            ;; 
549         --no-index)        index=0            ;;
550         -l|--log-file)     redir=             ;; 
551         -L|--local)        from_local=1       ;;
552         -m|--max-files)    maxf=$2            ; shift ;; 
553         -M|--max-jobs)     maxjobs=$2         ; shift ;;
554         -p|--production)   prodfull=$2        ; shift ; parse_prod ;;
555         -P|--pass)         passfull=$2        ; shift ; parse_pass ;;
556         -Q|--qa-number)    qanumber=$2        ; shift ;;
557         -R|--also-results) also_results=1     ;; 
558         -t|--top)          top=$2             ; shift ;;
559         -T|--min-max)      variance=0         ;; 
560         -v|--verbose)      let verb=$verb+1   ;; 
561         -V|--variance)     variance=1         ;;
562         -C|--no-check)     docheck=0          ;;
563         *) echo "$0: Unknown argument: $1" > /dev/stderr ; exit 1 ;; 
564     esac
565     shift
566 done
567 # === Initial setup ==================================================
568 # --- Check for AliEn token ------------------------------------------
569 check_token
570
571 # --- Check settings -------------------------------------------------
572 if test "x$prodfull" = "x" ; then
573     err "No production specified" 
574     exit 1
575 fi 
576 if test "x$prodpost" = "x" && test "x$passfull" = "x" ; then 
577     err "No pass specified for non-MC production"
578     exit 1
579 elif test "x$passfull" = "x" || test "x$passfull" = "xpassMC"; then 
580     warn "No pass specified, assuming MC"
581     passfull=
582     mc=1
583 fi 
584
585 # --- Construct output -----------------------------------------------
586 proddir=
587 passdir=
588 store=
589 year=20${prodyear}
590 if test $mc -gt 0 ; then 
591     proddir=${prodfull}
592     passdir=passMC
593     store=sim
594 else 
595     proddir=LHC${prodyear}${prodletter}
596     store=data
597     if test "x$passno" = "x" ; then 
598         err "No pass number"
599     fi 
600     if test "x$passpre" != "x" ; then 
601         passdir=${passpre}
602     fi
603     passdir=${passdir}pass${passno}
604     if test "x$passpost" != "x" ; then 
605         passdir=${passdir}_${passpost}
606     fi
607     if test "x$remainder" != "x" ; then 
608         passdir=${passdir}/${remainder}
609     fi
610 fi 
611 store=${store}/${year}/${proddir}/${passdir}
612 if test ! "x$qanumber" = "x" && test $qanumber -gt 0 ; then 
613     store=${store}_QA${qanumber}
614 fi
615 mkdir -p ${top}/$store 
616 fix_perm ${top}/$store
617
618 # --- Check for logging ----------------------------------------------
619 if test "x$redir" = "x" ; then 
620     redir=${top}/$store/qa.log 
621     rm -f $redir
622     fix_perm $redir
623 fi
624
625 check_lock ${top}/$store
626
627 # --- Some friendly information --------------------------------------
628 cat <<EOF
629         Year:                   $year
630         Production:             $prodfull 
631           Year:                 $prodyear
632           Letter:               $prodletter
633           Suffix:               $prodpost
634         Pass:                   $passfull
635           Number:               $passno
636           Prefix:               $passpre
637           Postfix:              $passpost
638         Remainder               $remainder
639           QA number             $qanumber
640         Output directory:       ${store}
641         Lock file:              ${lock}
642         Log:                    ${redir}
643         Force:                  ${force}
644         Use variance:           ${variance}
645         Use pre-downloaded:     ${from_local}
646 EOF
647
648 # --- Do a search to find our files ----------------------------------
649 get_filelist
650 nf=$?
651 if test $nf -le 0 ; then 
652     err "No files to process"
653     exit 1
654 fi
655 if test $maxf -gt 0 && test $maxf -lt $numf ; then 
656     numf=$maxf 
657 fi
658
659 # --- Copy scripts to target and compile -----------------------------
660 for i in QABase.h QAPlotter.C QARing.h QAStructs.h QATrender.C ; do
661     cp ${QA_FWD}/$i ${store}/${i}
662     rm -f ${store}/`echo $i | tr '.' '_'`.{so,d}
663     fix_perm ${store}/${i}
664 done
665 mess 1 "Compiling QATrender.C"
666 (cd $store && root -l -b <<EOF 
667 gROOT->LoadMacro("QABase.h++g");
668 gROOT->LoadMacro("QATrender.C++g");
669 .q
670 EOF
671 ) 2>> ${redir}
672 mess 1 "Compiling QAPlotter.C"
673 (cd $store && root -l -b <<EOF 
674 gROOT->LoadMacro("QABase.h++g");
675 gROOT->LoadMacro("QAPlotter.C++g");
676 .q
677 EOF
678 ) 2>> ${redir}
679 (cd ${store} && for i in *.so *.d ; do fix_perm $i ; done)
680
681 # --- Now get and analyse each run -----------------------------------
682 analyse_runs ${top}/$store $numf $files
683
684 # --- Now analyse all runs -------------------------------------------
685 make_trend ${top}/$store
686
687 # --- Make index files -----------------------------------------------
688 if test $index -gt 0 ; then 
689     info -n "Making index ... "
690     desc="For more see <a href='http://cern.ch/go/6Bwz'>TWiki</a>"
691     $topmk --title "QA for the FMD" \
692         --description "$desc" \
693         --link \
694         --max-depth 4 \
695         --frame \
696         --output index.html 
697     # >> ${redir} 2>&1 
698     fix_perm index.html
699     copy_aliroot_file $script
700     ok
701 fi 
702 chmod -R g+rwX ${top}/${proddir} >> ${redir} 2>&1
703
704
705 #
706 # EOF
707 #