]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/FORWARD/analysis2/qa/RunQAMT.sh
Important bug fixes for QA trains.
[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 style=$ALICE_ROOT/PWGLF/FORWARD/analysis2/qa/style.css 
10 favicon=$ALICE_ROOT/PWGLF/FORWARD/analysis2/qa/fmd_favicon.png
11 logo=$ALICE_ROOT/PWGLF/FORWARD/analysis2/qa/fmd_logo.png
12
13 # --- Help output ----------------------------------------------
14 usage()
15 {
16     cat <<EOF
17 Usage: $0 [OPTIONS] -j [JOBID]
18        $0 [OPTIONS] -p PRODUCTION -P PASS 
19
20 Options:
21         -h,--help                  This help 
22         -j,--jobid      NUMBER     The master job id of the production [$jobid]
23         -v,--verbose               Increase verbosity [$verb]
24         -m,--max-files  NUMBER     Max number of files to get [$maxf]
25         -M,--max-jobs   NUMBER     Max number of consequtive jobs [$maxjobs]
26         -t,--top        DIRECTORY  Output directory [$top]
27         -R,--also-results          Also get QAresults.root for each run
28         -Q,--qa-number  NUMBER     Custom QA id [$qanumber]
29         -p,--production IDENTIFIER Production identifier [$prodfull]
30         -P,--pass       IDENTIFIER Pass identifier [$passfull]
31         -l,--log-file              Log file output [$redir]
32         -b,--barrel     MODE       Fetch barrel data  [$barrel]
33         -f,--force                 Force re-run analysis [$force]
34
35 Note the option -j and the options -p and -P are mutually exclusive,
36 The option -Q is only used if the options -p and -P are given.
37 Production identifiers are of the form LHC11h, LHC11h3, or LHC11h_2. 
38 Pass identifers are of the form pass2, pass1_HLT, or cpass1.  If barrel mode
39 is >0, then do not assume ESD directory.  If mode>1, then get 
40 trending_barrel.root and QAresults_barrel.root
41 EOF
42 }
43
44 # --- Check AliEn token ----------------------------------------------
45 check_token()
46 {
47     uid=`id -u`
48     genv_file=/tmp/gclient_env_${uid}
49     
50     if test ! -f ${genv_file} ; then 
51         echo "No such file: ${genv_file}, please do alien-token-init" \
52             >/dev/stderr
53         exit 1
54     fi
55     . ${genv_file}
56     alien-token-info | grep -q "Token is still valid"
57     if test $? -ne 0 ; then 
58         echo "Token not valid, please re-new" > /dev/stderr 
59         exit 1
60     fi
61 }
62
63 # --- Diagnostics output ---------------------------------------------
64 verb=0
65 mess()
66 {
67     if test $1 -gt $verb ; then return ; fi 
68     shift
69     echo $*
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     echo "Error: $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         echo "Another QA process is already running:" > /dev/stderr 
109         echo "Content of ${lock}:" > /dev/stderr 
110         cat $lock > /dev/stderr 
111         trap - EXIT
112     exit 1
113     local now=`date` 
114     cat <<EOF > $lock
115 Process: $$
116 User:    $USER
117 Start:   $now
118 EOF
119     fi
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 get_parts()
152 {
153     mess 1 "Parsing information from job $@" 
154     year=$1 ; shift 
155     prodfull=$1 ; shift 
156     local lrunn=$1 ; shift
157     local ltype=$1 ; shift 
158     passfull=$1 ; shift 
159     remainder=$1 
160
161     mess 10 "year=$year" 
162     mess 10 "prodfull=$prodfull" 
163     mess 10 "lrunn=$lrunn" 
164     mess 10 "ltype=$ltype" 
165     mess 10 "passfull=$passfull" 
166     mess 10 "remainder=$remainder"
167
168     if test "x$passfull" = "x" ; then 
169         remainder=
170         passfull=$ltype 
171     fi
172     case x$passfull in 
173         *pass*) ;; 
174         *) remainder=$passfull 
175             passfull= 
176             ;;
177     esac
178     parse_pass 
179     parse_prod
180
181     case x$remainder in 
182         xQA*) qanumber=`echo $remainder | sed 's/QA//'`  ;; 
183         *) ;; 
184     esac
185
186 }
187 # --- Get the index for information ----------------------------------
188 skip=0
189 jobu="http://alimonitor.cern.ch/prod/jobs.jsp?t="
190 jobid=
191 get_job() 
192
193     mess 1 "Getting the job information" 
194     wget -q ${jobu}${jobid} -O job.html
195     local lskip
196     let lskip=$skip+1
197     p=`grep "/catalogue/index.jsp?path" job.html | head -n $lskip | tail -n 1 | sed -e 's,.*/alice/\(data\|sim\)/\([^<]*\)<.*,\2,' | tr '/' ' '` 
198     rm -f job.html
199     get_parts $p 
200 }
201
202 # --- Append path element --------------------------------------------
203 append_to_path()
204 {
205     local tmp=$1 ; shift 
206     local add=$1
207     if test "x$tmp" != "x" ; then tmp="${tmp}/" ; fi 
208     echo ${tmp}${add}
209 }
210
211 # --- Get a list of files to get -------------------------------------
212 file=trending.root
213 other=QAresults.root
214 files=
215 path=
216 numf=0
217 get_filelist()
218 {
219     mess 3 "Getting file list" 
220     
221     local datd=data
222     local esdd=ESDs/
223     if test ${barrel} -gt 0 ; then
224         esdd=
225     fi
226     if test ${barrel} -gt 1 ; then      
227         file=trending_barrel.root
228         other=QAresults_barrel.root
229     fi
230     case x$prodpost in 
231         x_*) ;; 
232         x) ;; 
233         *)  mess 3 "Assuming simulation output"
234             datd=sim 
235             esdd= 
236             ;; 
237     esac
238     
239     local paid=
240     if echo "$passno" | grep -q -E '^[0-9]*[.]?[0-9]*$' ; then 
241         if test "x$passfull" != "x" && test $passno -gt 0 ; then 
242             paid=pass${passno}
243         fi
244     else
245         paid=${passfull}
246         passpre=
247         post=
248     fi
249     local post=${passpost}
250     case x$post in 
251         x_*) ;; 
252         x) ;; 
253         *) post="_${post}" ;; 
254     esac
255
256     path=/alice/${datd}/${year}/${prodfull}/
257     local search="${esdd}${passpre}${paid}${post}"
258
259     if test $qanumber -gt 0 ; then 
260         qapost=`printf "QA%02d" $qanumber` 
261         search=`append_to_path "$search" $qapost` 
262     fi
263     
264     search=`append_to_path "$search" $file` 
265
266     cat <<EOF
267         Path:                   $path
268         Search:                 $search
269 EOF
270     mess 1 "Getting list of files from AliEn - can take minutes - be patient"
271     mess 2 "alien_find ${path} ${search}"
272     files=`alien_find ${path} ${search} | grep -v "\(files found\|AND THE\)" 2>> ${redir}` 
273     for i in $files ; do 
274         let numf=$numf+1
275     done 
276     mess 1 -n "Total of $numf files ... "
277     if test $maxf -lt 0 ; then 
278         mess 1 "using all" 
279     else
280         mess 1 "using $maxf first of these"
281     fi
282 }
283
284 # --- Change permissions on files ------------------------------------
285 fix_perm()
286 {
287     # if test ! -f $1 ; then return ; fi 
288     chmod g+rwX $1 >> ${redir} 2>&1 
289     chmod o+rX $1 >> ${redir} 2>&1 
290 }
291
292 # --- Check if a file is OK ------------------------------------------
293 docheck=1
294 check_file()
295 {
296     if test $docheck -lt 1 ; then return 0; fi 
297     root -l -b  <<EOF >> ${redir} 2>&1 
298 .L $ALICE_ROOT/PWGLF/FORWARD/analysis2/qa/CheckQAFile.C
299 CheckQAFile("$1");
300 .q
301 EOF
302     local ret=$? 
303     mess 2 "Check of $1 -> $ret"
304     # rm -f ${scr}.C 
305     return $ret
306 }
307
308 # --- Analyse a file -------------------------------------------------
309 analyse_file()
310 {
311     local dir=`dirname $1` 
312     local inp=`basename $1` 
313     local out=`echo $inp | sed 's/trending_/tree_/'` 
314     local ret=0
315     mess 2 -n "Analysing $inp -> $out ... "
316
317     if test -f $dir/$out ; then 
318         if test $force -lt 1 ; then 
319             mess 2 "exits"
320             return 0
321         fi
322         rm -f $dir/$out
323     fi
324
325     (cd $dir 
326         root -l -b  <<EOF 
327 .L RunFileQA.C
328 RunFileQA("$inp", "$out", $prodyear, "$prodletter");
329 .q
330 EOF
331         ret=$? 
332         mess 2 " -> $ret"
333         # rm -f ${scr}.C 
334     ) 2>> $redir
335     return $ret
336 }
337
338 # --- Download a single file -----------------------------------------
339 also_results=0
340 analyse_run()
341 {
342     local source=$1 ; shift 
343     local store=$1 ; shift 
344     local r=$1 ; shift 
345     local o=${store}/`basename $file .root`_${r}.root 
346
347     mess 2 -n "$source -> $o ... "
348     if test -f $o && test $force -lt 2; then 
349         mess 2 "exists" 
350         # sleep 1
351     else
352         rm -f ${o}
353         mess 2 -n "copying ... " 
354         alien_cp alien:${source} file:${o} >> ${redir} 2>&1 
355         fix_perm $o 
356         mess 2 "done"
357     fi
358     if test ! -f $o ; then return 1 ; fi 
359
360     if test $also_results -gt 0 ; then 
361         local s=`dirname ${source}`/${other}
362         local q=${store}/`basename $other .root`_${r}.root
363
364         mess 2 -n "$s -> $q ... "
365         if test -f $q && test $force -lt 2 ; then 
366             mess 2 "exists" 
367         else
368             rm -rf ${q}
369             mess 2 -n "copying ... " 
370             alien_cp alien:${s} file:${q} >> ${redir} 2>&1 
371             fix_perm $q
372             mess 2 "done"
373         fi
374     fi
375
376         
377     check_file ${o} 
378     local ret=$? 
379     case $ret in 
380         0|2) ;; 
381         1|3|4|5|6) return 2 ;; 
382     esac
383
384     analyse_file ${o}
385
386     return 0
387 }
388
389 # --- Submit run analysis to background ------------------------------
390 submit_runs()
391 {
392     local out=$1 ; shift
393     local sta=$1 ; shift 
394     local max=$1 ; shift
395     
396     local joblist=
397     local counter=0
398     mess 5 "Submitting $maxjobs jobs from $sta/$maxf" 
399     for i in $@ ; do 
400         let cur=$sta+$counter
401
402         local b=`echo $i | sed -e "s,${path},,"` 
403         local r=`echo $b | sed -e "s,/.*,,"` 
404
405         printf "%3d/%3d: %s\n" $cur $max $r 
406         runs[$counter]=$r
407
408         let counter=$counter+1
409         
410         analyse_run $i $out $r &
411         j=`jobs %% | sed -e 's/^[^0-9]*//' -e 's/[^0-9]*$//'` 
412         joblist="$joblist $j"
413     done
414     
415     counter=0
416     mess 5 "will wait for jobs $joblist"
417     for i in $joblist ; do 
418         mess 5 "waiting for $i of $joblist"
419         wait %$i
420         mess 5 "Analysing ${runs[$counter]} returned $?" 
421         let counter=$counter+1
422     done
423 }
424     
425 # --- Analyse each run in turn ---------------------------------------
426 maxjobs=`grep "processor" /proc/cpuinfo | wc -l`
427 analyse_runs()
428 {
429     local out=$1 ; shift 
430     local max=$1 ; shift 
431     
432     local queued=0
433     local counter=0
434     local start=0
435     local list=
436     while test $# -gt 0 ; do 
437         if test $counter -ge $max ; then 
438             break;
439         fi
440
441         list="$list $1" 
442         shift 
443         let queued=$queued+1 
444         let counter=$counter+1 
445
446         if test $queued -eq 1 ; then 
447             start=$counter
448         fi
449         
450         if test $queued -ge $maxjobs ; then 
451             mess 1 "Submitting $queued jobs from $start/$max"
452             submit_runs $out $start $max $list 
453             list=
454             queued=0 
455         fi
456     done
457     if test $queued -gt 0 ; then 
458         mess 1 "Submitting $queued jobs from $start/$max"
459         submit_runs $out $start $max $list 
460     fi
461 }
462
463 # --- Copy style -----------------------------------------------------
464 copy_aliroot_file()
465 {
466     local file=$1 
467     if test ! -f $file ; then return ; fi 
468     base=`basename $file`
469     rm -f $base 
470     cp $file $base 
471     fix_perm $base
472 }
473 copy_style()
474 {
475     copy_aliroot_file $style
476 }       
477
478 # --- Run the final trending -----------------------------------------
479 make_trend()
480 {
481     local dir=$1 
482     local ret=0
483     mess 1 -n "Analysing $dir ... "
484     (cd $dir 
485         rm -f trend_*_*.html 
486         rm -f trend_*_*.pdf
487         rm -f trend_*_*.root
488
489         root -l -b <<EOF 
490 .L RunFinalQA.C
491 RunFinalQA(".", $prodyear, "$prodletter");
492 .q
493 EOF
494         mess 1 -n " ... "
495         # mess 3 -n "root -l -b -q ${scr}.C "
496         # root -l -b -q ${scr}.C  > /dev/null 2>&1 
497         # local ret=$? 
498         # mess 1 " -> $ret"
499         # rm -f ${scr}.C 
500
501         # do the index file 
502         local idx=`ls trend_*_*.html 2> /dev/null` 
503         for i in $idx ; do 
504             mess 1 "Making index.html point to $i" 
505             sed -e 's,index.html,../index.html,' \
506                 -e "s,!--JOBID--,a target='_blank' href='${jobu}${jobid}'>Job</a," \
507                 < $i > index.html 
508             cp index.html $i
509         done
510         
511         if test ! -f index.html ; then 
512             echo "No index file found" 
513             ret=1
514         else 
515             fix_perm index.html 
516             fix_perm . > /dev/null 2>&1 
517         fi
518
519         copy_style
520         copy_aliroot_file $favicon
521         copy_aliroot_file $logo
522     ) 2>> $redir
523     return $ret
524 }
525
526 # --- Make index file ------------------------------------------------
527 make_index()
528 {
529     local dir=$1   ; shift  
530     local title=$1 ; shift
531     local desc=$1  ; shift 
532     mess 1 "Making index in $dir ($title)"
533     
534     (cd $dir
535         local date=`date` 
536         
537         rm -f index.html 
538
539         cat <<EOF > index.html
540 <!DOCTYPE html>
541 <html>
542   <head>
543     <title>$title</title>
544     <link rel='stylesheet' href='style.css'>
545     <link rel='shortcut icon' href='fmd_favicon.png' type='image/x-png'>
546   </head>
547   <body>
548     <h1><img style='width: 200px;' src='fmd_logo.png'>  &nbsp;$title</h1>
549 EOF
550         if test ! "x$desc" = "x" ; then 
551             echo "<p>$desc</p>" >> index.html
552         fi
553         echo "      <ul>" >> index.html
554         for i in * ; do 
555             if test ! -d $i ; then continue ; fi 
556             echo "      <li><a href='$i'>$i</a></li>" >> index.html
557         done
558         echo "      </ul>" >> index.html 
559         if test "x$desc" = "x" ; then 
560             echo "      <div class='back'><a href='../'>Back</a></div>" \
561                 >> index.html
562         fi
563         cat <<EOF >> index.html    
564     <div class='change'>Last update: $date</div>
565   </body>
566 </html>
567 EOF
568         copy_style 
569         copy_aliroot_file $favicon
570         copy_aliroot_file $logo
571         fix_perm index.html
572         fix_perm . > /dev/null 2>&1 
573     )
574 }
575
576
577 # --- Pass command line options --------------------------------------
578 redir=/dev/null
579 maxf=-1
580 top=.
581 while test $# -gt 0 ; do 
582     case $1 in 
583         -h|--help) usage ; exit 0 ;; 
584         -v|--verbose)      let verb=$verb+1   ;; 
585         -j|--jobid)        jobid=$2           ; shift ;; 
586         -m|--max-files)    maxf=$2            ; shift ;; 
587         -M|--max-jobs)     maxjobs=$2         ; shift ;;
588         -t|--top)          top=$2             ; shift ;;
589         -R|--also-results) also_results=1     ;; 
590         -Q|--qa-number)    qanumber=$2        ; shift ;;
591         -l|--log-file)     redir=             ;; 
592         -b|--barrel)       barrel=$2          ; shift ;;
593         -f|--force)        let force=$force+1 ;; 
594         -p|--production) 
595             prodfull=$2; shift; parse_prod ; year=20${prodyear} ;;
596         -P|--pass) 
597             passfull=$2; shift; parse_pass ;;
598         *) echo "$0: Unknown argument: $1" > /dev/stderr ; exit 1 ;; 
599     esac
600     shift
601 done
602 # --- Initial setup --------------------------------------------------
603 # First, check we have a valid AliEn token, then retrieve the job 
604 # information to parse out the location of the files we need, and 
605 # finally make our output directory and check the lock 
606 check_token
607
608 if test ! "x$jobid" = x ; then 
609     if test ! "x$prodfull" = "x" || test ! "x$passfull" = "x" ; then 
610         cat <<EOF > /dev/stderr
611 Option -j ${jobid} and options -p and -P are mutually exclusive 
612 EOF
613         exit 1
614     fi
615     get_job
616 else 
617     if test "x$prodfull" = "x" || test "x$passfull" = "x" ; then 
618         cat<<EOF > /dev/stderr
619 When specifying prodcution and/or pass both options -p and -P _must_ 
620 be specified. 
621 EOF
622         exit 1
623     elif test ! "x$jobid"  = "x" ; then 
624         cat <<EOF > /dev/stderr
625 Option -j and options -p ${prodfull} and -P ${passfull} are mutually exclusive 
626 EOF
627         exit 1
628     fi
629 fi      
630
631 proddir=LHC${prodyear}${prodletter}
632 store=${proddir}
633 if test ! "x$passno" = "x" ; then 
634     if test "x${passpre}" = "xv" || test "x${passpre}" = "xc"; then 
635         store=${store}/${passpre}pass${passno}
636     else
637         store=${store}/pass${passno}
638     fi
639 elif test ! "x$prodpost" = "x" ; then 
640     proddir=${proddir}${prodpost}
641     store=${proddir}/sim
642 elif test ! "x$remainder" = "x" ; then 
643     store=${store}/${remainder}
644 fi
645 if test ! "x$qanumber" = "x" && test $qanumber -gt 0 ; then 
646     store=${store}_QA${qanumber}
647 fi
648 mkdir -p ${top}/$store 
649 fix_perm ${top}/${proddir}
650 fix_perm ${top}/$store
651
652 if test "x$redir" = "x" ; then 
653     redir=${top}/$store/qa.log 
654     rm -f $redir
655     fix_perm $redir
656 fi
657
658 check_lock ${top}/$store
659
660 # --- Some friendly information --------------------------------------
661 cat <<EOF
662         Year:                   $year
663         Production:             $prodfull 
664           Year:                 $prodyear
665           Letter:               $prodletter
666           Suffix:               $prodpost
667         Pass:                   $passfull
668           Number:               $passno
669           Prefix:               $passpre
670           Postfix:              $passpost
671         Remainder               $remainder
672           QA number             $qanumber
673         Output directory:       ${store}
674         Lock file:              ${lock}
675         Log:                    ${redir}
676         Force:                  ${force}
677 EOF
678 # --- Do a search to find our files ----------------------------------
679 get_filelist
680
681 if test $maxf -gt 0 && test $maxf -lt $numf ; then 
682     numf=$maxf 
683 fi
684
685 # --- Copy scripts to target and compile -----------------------------
686 for i in QABase.h QAPlotter.C QARing.h QAStructs.h QATrender.C \
687     RunFileQA.C RunFinalQA.C ; do
688     cp $ALICE_ROOT/PWGLF/FORWARD/analysis2/qa/$i ${store}/${i}
689     rm -f ${store}/`echo $i | tr '.' '_'`.{so,d}
690     fix_perm ${store}/${i}
691 done
692 mess 1 "Compiling QATrender.C"
693 (cd $store && root -l -b <<EOF 
694 gROOT->LoadMacro("QABase.h++g");
695 gROOT->LoadMacro("QATrender.C++g");
696 .q
697 EOF
698 )
699 mess 1 "Compiling QAPlotter.C"
700 (cd $store && root -l -b <<EOF 
701 gROOT->LoadMacro("QABase.h++g");
702 gROOT->LoadMacro("QAPlotter.C++g");
703 .q
704 EOF
705 )
706 (cd ${store} && for i in *.so *.d ; do fix_perm $i ; done)
707
708 # --- Now get and analyse each run -----------------------------------
709 analyse_runs ${top}/$store $numf $files
710
711 # --- Now analyse all runs -------------------------------------------
712 make_trend ${top}/$store
713
714 # --- Make index files -----------------------------------------------
715 make_index ${top}/${proddir} ${proddir}
716 make_index ${top} "QA for the FMD" \
717     "For more information see <a href='https://twiki.cern.ch/twiki/bin/viewauth/ALICE/FMDQA'>TWiki pages</a>."
718
719 chmod -R g+rwX ${top}/${proddir} >> ${redir} 2>&1
720
721 #
722 # EOF
723 #