]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/FORWARD/analysis2/qa/RunQAMT.sh
Merge branch 'master' into TPCdev
[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=0
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         -l|--log-file)     redir=             ;; 
550         -L|--local)        from_local=1       ;;
551         -m|--max-files)    maxf=$2            ; shift ;; 
552         -M|--max-jobs)     maxjobs=$2         ; shift ;;
553         -p|--production)   prodfull=$2        ; shift ; parse_prod ;;
554         -P|--pass)         passfull=$2        ; shift ; parse_pass ;;
555         -Q|--qa-number)    qanumber=$2        ; shift ;;
556         -R|--also-results) also_results=1     ;; 
557         -t|--top)          top=$2             ; shift ;;
558         -T|--min-max)      variance=0         ;; 
559         -v|--verbose)      let verb=$verb+1   ;; 
560         -V|--variance)     variance=1         ;;
561         -C|--no-check)     docheck=0          ;;
562         *) echo "$0: Unknown argument: $1" > /dev/stderr ; exit 1 ;; 
563     esac
564     shift
565 done
566 # === Initial setup ==================================================
567 # --- Check for AliEn token ------------------------------------------
568 check_token
569
570 # --- Check settings -------------------------------------------------
571 if test "x$prodfull" = "x" ; then
572     err "No production specified" 
573     exit 1
574 fi 
575 if test "x$prodpost" = "x" && test "x$passfull" = "x" ; then 
576     err "No pass specified for non-MC production"
577     exit 1
578 elif test "x$passfull" = "x" || test "x$passfull" = "xpassMC"; then 
579     warn "No pass specified, assuming MC"
580     passfull=
581     mc=1
582 fi 
583
584 # --- Construct output -----------------------------------------------
585 proddir=
586 passdir=
587 store=
588 year=20${prodyear}
589 if test $mc -gt 0 ; then 
590     proddir=${prodfull}
591     passdir=passMC
592     store=sim
593 else 
594     proddir=LHC${prodyear}${prodletter}
595     store=data
596     if test "x$passno" = "x" ; then 
597         err "No pass number"
598     fi 
599     if test "x$passpre" != "x" ; then 
600         passdir=${passpre}
601     fi
602     passdir=${passdir}pass${passno}
603     if test "x$passpost" != "x" ; then 
604         passdir=${passdir}_${passpost}
605     fi
606     if test "x$remainder" != "x" ; then 
607         passdir=${passdir}/${remainder}
608     fi
609 fi 
610 store=${store}/${year}/${proddir}/${passdir}
611 if test ! "x$qanumber" = "x" && test $qanumber -gt 0 ; then 
612     store=${store}_QA${qanumber}
613 fi
614 mkdir -p ${top}/$store 
615 fix_perm ${top}/$store
616
617 # --- Check for logging ----------------------------------------------
618 if test "x$redir" = "x" ; then 
619     redir=${top}/$store/qa.log 
620     rm -f $redir
621     fix_perm $redir
622 fi
623
624 check_lock ${top}/$store
625
626 # --- Some friendly information --------------------------------------
627 cat <<EOF
628         Year:                   $year
629         Production:             $prodfull 
630           Year:                 $prodyear
631           Letter:               $prodletter
632           Suffix:               $prodpost
633         Pass:                   $passfull
634           Number:               $passno
635           Prefix:               $passpre
636           Postfix:              $passpost
637         Remainder               $remainder
638           QA number             $qanumber
639         Output directory:       ${store}
640         Lock file:              ${lock}
641         Log:                    ${redir}
642         Force:                  ${force}
643         Use variance:           ${variance}
644         Use pre-downloaded:     ${from_local}
645 EOF
646
647 # --- Do a search to find our files ----------------------------------
648 get_filelist
649 nf=$?
650 if test $nf -le 0 ; then 
651     err "No files to process"
652     exit 1
653 fi
654 if test $maxf -gt 0 && test $maxf -lt $numf ; then 
655     numf=$maxf 
656 fi
657
658 # --- Copy scripts to target and compile -----------------------------
659 for i in QABase.h QAPlotter.C QARing.h QAStructs.h QATrender.C ; do
660     cp ${QA_FWD}/$i ${store}/${i}
661     rm -f ${store}/`echo $i | tr '.' '_'`.{so,d}
662     fix_perm ${store}/${i}
663 done
664 mess 1 "Compiling QATrender.C"
665 (cd $store && root -l -b <<EOF 
666 gROOT->LoadMacro("QABase.h++g");
667 gROOT->LoadMacro("QATrender.C++g");
668 .q
669 EOF
670 ) 2>> ${redir}
671 mess 1 "Compiling QAPlotter.C"
672 (cd $store && root -l -b <<EOF 
673 gROOT->LoadMacro("QABase.h++g");
674 gROOT->LoadMacro("QAPlotter.C++g");
675 .q
676 EOF
677 ) 2>> ${redir}
678 (cd ${store} && for i in *.so *.d ; do fix_perm $i ; done)
679
680 # --- Now get and analyse each run -----------------------------------
681 analyse_runs ${top}/$store $numf $files
682
683 # --- Now analyse all runs -------------------------------------------
684 make_trend ${top}/$store
685
686 # --- Make index files -----------------------------------------------
687 if test $index -gt 0 ; then 
688     info -n "Making index ... "
689     desc="For more information see <a href='https://twiki.cern.ch/twiki/"
690     desc="${desc}bin/viewauth/ALICE/FMDQA'>TWiki pages</a>."
691     $topmk --title "QA for the FMD" \
692         --description "$desc" \
693         --link \
694         --max-depth 4 \
695         --output index.html 
696     # >> ${redir} 2>&1 
697     fix_perm index.html
698     copy_aliroot_file $script
699     ok
700 fi 
701 chmod -R g+rwX ${top}/${proddir} >> ${redir} 2>&1
702
703
704 #
705 # EOF
706 #