Flexible pt range for the efficiency histogramming
[u/mrichter/AliRoot.git] / MUON / AliMUONTrackerQAChecker.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 // $Id$
17
18 #include "AliMUONTrackerQAChecker.h"
19
20 /// \class AliMUONTrackerQAChecker
21 ///
22 /// Implementation of AliQACheckerBase for MCH and MTR
23 ///
24 /// For the moment we only implement the checking of raw data QA for the tracker
25 /// by looking at the occupancy at the bus patch level.
26 ///
27 /// \author Laurent Aphecetche, Subatech
28
29 #include "AliCDBManager.h"
30 #include "AliCodeTimer.h"
31 #include "AliLog.h"
32 #include "AliMUONQAIndices.h"
33 #include "AliMUONRecoParam.h"
34 #include "AliMpBusPatch.h"
35 #include "AliMpDDLStore.h"
36 #include "AliQAv1.h"
37 #include "Riostream.h"
38 #include "TAxis.h"
39 #include "TDirectory.h"
40 #include "TGaxis.h"
41 #include "TH1.h"
42 #include "TLine.h"
43 #include "TMath.h"
44 #include "TPaveText.h"
45 #include "TVirtualPad.h"
46 #include "TStyle.h"
47 #include "TLatex.h"
48
49 /// \cond CLASSIMP
50 ClassImp(AliMUONTrackerQAChecker)
51 /// \endcond
52
53 namespace {
54   
55   //___________________________________________________________________________  
56   int trim(Int_t n, 
57            Double_t* x,
58            Double_t alpha,
59            Double_t& tmean,
60            Double_t& tvar,
61            Double_t& min,
62            Double_t& max)
63   {
64     //
65     // Calculates the trimmed (tmean) mean
66     // of a sample (x) and estimates the variance (tvar)
67     // of that mean.
68     //
69     
70     // First check input parameters
71     
72     // number of observations
73     if ( n < 2 )
74     {
75       return -1;
76     }
77     
78     if ( alpha < 0 || alpha >= 0.5 )
79       // proportion of observations
80       // to be trimmed at each end of the sorted sample
81     {
82       return -2;
83     }
84     
85     // Input parameters are good. Let's move on.
86     
87     // Insure we use a sample sorted into ascending order.
88     
89     Int_t* indices = new Int_t[n];
90     
91     TMath::Sort(n,x,indices,kFALSE);
92     
93     Double_t* sx = new Double_t[n];
94     
95     for ( Int_t i = 0; i < n; ++i )
96     {
97       sx[i] = x[indices[i]];
98     }
99     delete[] indices;
100     
101     
102     // Number of observations trimmed at each end.
103     
104     Int_t k = TMath::FloorNint(alpha * n);
105     
106     double sum = 0.0;
107     
108     for ( Int_t i = k; i < n - k ; ++i )
109     {
110       sum += sx[i];
111     }
112     
113     tmean = sum / ( n - 2 * k );
114     
115     double t2 = 0.0;
116     
117     for ( Int_t i = k; i < n - k; ++i )
118     {
119       t2 += (sx[i] - tmean) * (sx[i] - tmean);
120     }
121     
122     tvar = (
123             t2 +
124             k * (sx[k] - tmean) * (sx[k] - tmean) +
125             k * (sx[n - k - 1] - tmean) * (sx[n - k - 1] - tmean)
126             ) / (n * n);
127     
128     // get the min and max for the non-rejected values
129     min = DBL_MAX;
130     max = 0.0;
131     
132     for ( Int_t i = k; i < n-k; ++i ) 
133     {
134       min = TMath::Min(min,sx[i]);
135       max = TMath::Max(max,sx[i]);
136     }
137     
138     delete[] sx;
139     
140     return 0;
141   }
142
143   //___________________________________________________________________________  
144   Int_t GetColorFromCheckCode(AliMUONVQAChecker::ECheckCode code)
145   {
146     if ( code == AliMUONVQAChecker::kInfo ) return AliMUONVQAChecker::kInfoColor;
147     else if ( code == AliMUONVQAChecker::kWarning ) return AliMUONVQAChecker::kWarningColor;
148     else if ( code ==  AliMUONVQAChecker::kFatal) return AliMUONVQAChecker::kFatalColor;
149     else return AliMUONVQAChecker::kErrorColor;
150   }
151   
152   const char* NOTENOUGHEVENTMESSAGE = "Not enough event to judge. Please wait a bit";
153   const char* NOTIFYEXPERTMESSAGE = "PLEASE NOTIFY EXPERT !";
154   const char* ALLISFINEMESSAGE = "All is fine. Just enjoy.";
155   
156   const int NOTENOUGHEVENTLIMIT = 50;
157   
158   //___________________________________________________________________________  
159   void SetupHisto(Int_t neventsseen, Int_t neventsused, const TObjArray& messages, TH1& histo, AliMUONVQAChecker::ECheckCode code, const char* extraopt="")
160   {
161     Bool_t allIsFine(kFALSE);
162     
163     if ( code == AliMUONVQAChecker::kInfo ) 
164     {
165       allIsFine = kTRUE;
166     }    
167     
168     Double_t y1 = 0.99 - (messages.GetLast()+(allIsFine?1:0)+2)*0.075;
169     
170     TPaveText* text = new TPaveText(0.5,y1,0.99,0.99,"NDC");
171     
172     text->AddText(Form("MCH RUN %d - %d events seen - %d events used",AliCDBManager::Instance()->GetRun(),neventsseen,neventsused));
173     
174     TIter next(&messages);
175     TObjString* str;
176     
177     while ( ( str = static_cast<TObjString*>(next()) ) )
178     {
179       text->AddText(str->String());
180     }
181     
182     if ( allIsFine )
183     {
184       text->AddText(ALLISFINEMESSAGE);
185     }
186                     
187     text->SetFillColor(GetColorFromCheckCode(code));
188                       
189     Int_t color = GetColorFromCheckCode(code);
190     
191     histo.SetFillStyle(1001);
192     histo.SetFillColor(color);    
193     TString sopt("BAR");
194     sopt += extraopt;
195     histo.SetOption(sopt.Data());
196     
197     histo.SetBit(TH1::kNoTitle); 
198     
199     TList* lstF = histo.GetListOfFunctions();
200     TObject* title = lstF->FindObject("title");
201     if (title) delete lstF->Remove(title);
202     // 
203     lstF->Add(text);  
204     
205   }
206
207   //___________________________________________________________________________  
208   void ShowTrueValue(TH1& hrostatusnorm, Int_t v)
209   {
210     // For a bar > 100% we put the text inside the bar (as TEXT45 option is putting above which
211     // would go offscreen)
212     
213     Int_t bin = hrostatusnorm.FindBin(1.0*v);
214     
215     Double_t value = hrostatusnorm.GetBinContent(bin);
216     
217     if ( value > 100.0 ) 
218     {
219       TLatex* l = new TLatex(hrostatusnorm.GetBinCenter(bin),50,Form("%g",value));
220       l->SetTextFont(gStyle->GetTextFont());
221       l->SetTextAlign(22);
222       l->SetTextAngle(45);
223       l->SetTextSize(0.02*hrostatusnorm.GetMarkerSize());
224       hrostatusnorm.GetListOfFunctions()->Add(l);
225     }
226   }
227
228 }
229 //__________________________________________________________________
230 AliMUONTrackerQAChecker::AliMUONTrackerQAChecker() : AliMUONVQAChecker()
231 {
232         /// ctor
233 }          
234
235 //__________________________________________________________________
236 AliMUONTrackerQAChecker::~AliMUONTrackerQAChecker() 
237 {
238         /// dtor
239 }
240
241 //______________________________________________________________________________
242 AliMUONVQAChecker::ECheckCode*
243 AliMUONTrackerQAChecker::CheckRecPoints(TObjArray ** list, const AliMUONRecoParam* /*recoParam*/)
244 {
245   /// Check rec points
246   /// Very binary check for the moment. 
247   
248   AliCodeTimerAuto("",0);
249   
250   AliMUONVQAChecker::ECheckCode * rv = new AliMUONVQAChecker::ECheckCode[AliRecoParam::kNSpecies] ; 
251   for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) 
252     rv[specie] =  AliMUONVQAChecker::kInfo; 
253   
254   
255   for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) 
256   {
257     TH1* h = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerNumberOfClustersPerDE,AliRecoParam::ConvertIndex(specie));
258
259     if ( !h ) rv[specie] = AliMUONVQAChecker::kWarning; // only a warning if histo not found, in order not to kill anything because QA failed...
260   
261     else if ( h->GetMean() == 0.0 ) rv[specie] =  MarkHisto(*h,AliMUONVQAChecker::kFatal);
262   }
263   return rv;
264 }
265
266 //______________________________________________________________________________
267 AliMUONVQAChecker::ECheckCode 
268 AliMUONTrackerQAChecker::MarkHisto(TH1& histo, AliMUONVQAChecker::ECheckCode value) const
269 {
270   /// Mark histo as originator of some QA error/warning
271   
272   if ( value != AliMUONVQAChecker::kInfo )
273   {
274     histo.SetBit(AliQAv1::GetQABit());
275   }
276   
277   return value;
278 }
279
280 //______________________________________________________________________________
281 AliMUONVQAChecker::ECheckCode*
282 AliMUONTrackerQAChecker::CheckESD(TObjArray ** list, const AliMUONRecoParam* /*recoParam*/)
283 {
284   /// Check ESD
285   
286   AliCodeTimerAuto("",0);
287   
288   AliMUONVQAChecker::ECheckCode * rv = new AliMUONVQAChecker::ECheckCode[AliRecoParam::kNSpecies] ; 
289   for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) 
290     rv[specie] = AliMUONVQAChecker::kInfo; 
291   
292   for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
293     
294     TH1* h = AliQAv1::GetData(list,AliMUONQAIndices::kESDnTracks,AliRecoParam::ConvertIndex(specie));
295   
296     if (!h) rv[specie] = AliMUONVQAChecker::kWarning;
297   
298     else if ( h->GetMean() == 0.0 ) rv[specie] =  MarkHisto(*h,AliMUONVQAChecker::kFatal); // no track -> fatal
299   
300     h = AliQAv1::GetData(list,AliMUONQAIndices::kESDMatchTrig,AliRecoParam::ConvertIndex(specie));
301   
302     if (!h) rv[specie] = AliMUONVQAChecker::kWarning;
303   
304     else if (h->GetMean() == 0.0 ) rv[specie] = MarkHisto(*h,AliMUONVQAChecker::kError); // no trigger matching -> error
305   }
306   return rv;
307 }
308
309 //______________________________________________________________________________
310 AliMUONVQAChecker::ECheckCode*
311 AliMUONTrackerQAChecker::CheckRaws(TObjArray ** list, const AliMUONRecoParam* recoParam)
312 {
313   /// Check raws
314
315   AliCodeTimerAuto("",0);
316   
317   if (!recoParam) return 0x0;
318   
319   AliMUONVQAChecker::ECheckCode * rv = new AliMUONVQAChecker::ECheckCode[AliRecoParam::kNSpecies] ; 
320
321   for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) 
322   {
323     rv[specie] = AliMUONVQAChecker::kInfo; 
324   }
325   
326   for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) 
327   {
328     TH1* hneventsseen = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerNofPhysicsEventsSeen,AliRecoParam::ConvertIndex(specie));
329     TH1* hneventsused = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerNofGoodPhysicsEventsUsed,AliRecoParam::ConvertIndex(specie));
330
331     if (!hneventsseen || !hneventsused ) continue;
332     
333     Int_t neventsseen = TMath::Nint(hneventsseen->GetBinContent(1));
334     Int_t neventsused = TMath::Nint(hneventsused->GetBinContent(1));
335         
336     AliMUONVQAChecker::ECheckCode c1 = AliMUONVQAChecker::kInfo;
337     AliMUONVQAChecker::ECheckCode c2 = AliMUONVQAChecker::kInfo;
338     AliMUONVQAChecker::ECheckCode c3 = AliMUONVQAChecker::kInfo;
339     
340     TH1* hbp = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchOccupancy,AliRecoParam::ConvertIndex(specie));    
341     TH1* hbpconfig = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchConfig,AliRecoParam::ConvertIndex(specie));
342     TH1* hddl = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerDDLOccupancy,AliRecoParam::ConvertIndex(specie));    
343
344     if ( hbp && hbpconfig && hddl ) 
345     {
346       c1 = BeautifyOccupancyHistograms(*hddl,*hbp,hbpconfig,neventsseen,neventsused,*recoParam);  
347     }
348     else
349     {
350       AliError(Form("Could not BeautifyOccupancyHistograms : hddl=%p hbpconfig=%p hbp=%p",hddl,hbpconfig,hbp));
351     }
352     
353     TH1* hbuspatchtokenerrors = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchTokenLostErrors,AliRecoParam::ConvertIndex(specie));
354     TH1* hrostatus = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerReadoutStatus,AliRecoParam::ConvertIndex(specie));    
355     TH1* hrostatusnorm = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerReadoutStatusPerEvent,AliRecoParam::ConvertIndex(specie));
356     
357     if ( hrostatus && hrostatusnorm && hbuspatchtokenerrors )
358     {
359       c2 = BeautifyReadoutHistograms(*hrostatus,*hrostatusnorm,*hbuspatchtokenerrors,
360                                      neventsseen,neventsused,*recoParam);
361     }
362     else
363     {
364       AliError(Form("Could not BeautifyReadoutHistograms : hrostatus=%p hrostatusnorm=%p hbuspatchtokenerrors=%p",
365                     hrostatus,hrostatusnorm,hbuspatchtokenerrors));
366     }
367     
368     
369     TH1* heventsize = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerDDLEventSize,AliRecoParam::ConvertIndex(specie));    
370     TH1* heventsizeperevent = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerDDLEventSizePerEvent,AliRecoParam::ConvertIndex(specie));
371     
372     if ( heventsize && heventsizeperevent ) 
373     {
374       c3 = BeautifyEventsizeHistograms(*heventsize,*heventsizeperevent,
375                                        neventsseen,neventsused,*recoParam);
376     }
377     else
378     {
379       AliError(Form("Could not BeautifyEventsizeHistograms heventsize=%p heventsizeperevent=%p",heventsize,heventsizeperevent));
380     }
381     
382     if ( c1 == AliMUONVQAChecker::kFatal || c2 == AliMUONVQAChecker::kFatal || c3 == AliMUONVQAChecker::kFatal )
383     {
384       rv[specie] = AliMUONVQAChecker::kFatal;
385     }
386     else if ( c1 == AliMUONVQAChecker::kError || c2 == AliMUONVQAChecker::kError || c3 == AliMUONVQAChecker::kError )
387     {
388       rv[specie] = AliMUONVQAChecker::kError;
389     }
390     else if ( c1 == AliMUONVQAChecker::kWarning || c2 == AliMUONVQAChecker::kWarning || c3 == AliMUONVQAChecker::kWarning )
391     {
392       rv[specie] = AliMUONVQAChecker::kWarning;
393     }
394     else
395     {
396       rv[specie] = AliMUONVQAChecker::kInfo;
397     }
398   }
399   
400   return rv;
401 }
402
403 //____________________________________________________________________________ 
404 AliMUONVQAChecker::ECheckCode
405 AliMUONTrackerQAChecker::BeautifyOccupancyHistograms(TH1& hddl,
406                                                      TH1& hbp, 
407                                                      const TH1* hbuspatchconfig, 
408                                                      Int_t neventsseen,
409                                                      Int_t neventsused,
410                                                      const AliMUONRecoParam& recoParam)
411 {
412   /// Put labels, limits and so on on the TrackerBusPatchOccupancy histograms
413   /// hbuspatchconfig and hbp must have the same bin definitions
414   
415   if ( hbuspatchconfig )
416   {
417     if ( hbp.GetNbinsX() != hbuspatchconfig->GetNbinsX() ||
418         hbp.GetXaxis()->GetXmin() != hbuspatchconfig->GetXaxis()->GetXmin() ||
419         hbp.GetXaxis()->GetXmax() != hbuspatchconfig->GetXaxis()->GetXmax() )
420     {
421       AliError("hbp and hbuspatchconfig histograms are not compatible !");
422       return AliMUONVQAChecker::kFatal;
423     }
424   }
425   
426   hddl.SetStats(kFALSE);
427   hbp.SetXTitle("Absolute Bus Patch Id");
428   hbp.SetYTitle("Occupancy (percent)");
429   hbp.SetStats(kFALSE);
430   
431   Double_t xmin = hbp.GetXaxis()->GetXmin();
432   Double_t xmax = hbp.GetXaxis()->GetXmax();
433   
434   Double_t occMax(0.1); // 0.1% y-limit for the plot
435   Double_t maxToleratedOccupancy(recoParam.BuspatchOccupancyHighLimit()*100.0); 
436   Double_t minToleratedOccupancy(recoParam.BuspatchOccupancyLowLimit()*100.0);   
437   TLine* line1 = new TLine(xmin,maxToleratedOccupancy,xmax,maxToleratedOccupancy);
438   line1->SetLineColor(1);
439   line1->SetLineWidth(1);
440
441   TLine* line2 = new TLine(xmin,minToleratedOccupancy,xmax,minToleratedOccupancy);
442   line2->SetLineColor(1);
443   line2->SetLineWidth(1);
444   
445   TList* lstF = hbp.GetListOfFunctions();
446   if (lstF) {
447     TObject *stats = lstF->FindObject("stats");
448     lstF->Remove(stats);
449     TObject *obj;
450     while ((obj = lstF->First())) { while(lstF->Remove(obj)) { } delete obj; }
451     if (stats) lstF->Add(stats);
452   } 
453   
454   hbp.GetListOfFunctions()->Add(line1);
455   hbp.GetListOfFunctions()->Add(line2);
456     
457   TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
458   AliMpBusPatch* bp(0x0);
459
460   Int_t nBusPatches(0);
461   Int_t nMissingBusPatches(0);
462   
463   while ( ( bp = static_cast<AliMpBusPatch*>(next())) )
464   {
465     ++nBusPatches;
466     
467     Int_t bin = hbp.FindBin(bp->GetId());
468     
469     if ( hbp.GetBinContent(bin) <= 0.0 ) 
470     {
471       ++nMissingBusPatches;
472     }
473   }
474   
475   next.Reset();
476   
477   Int_t ok(-1);
478   Int_t n(0);
479   Int_t nBusPatchesAboveLimit(0);
480   Int_t nBusPatchesBelowLimit(0);
481   Double_t alpha(0.1); // trim 10% of data
482   Double_t tmean(0.0),tvar(0.0);
483   Double_t ymin(0.0),ymax(0.0);
484   
485   if ( nBusPatches ) 
486   {
487     Double_t* x = new Double_t[nBusPatches];
488     
489     while ( ( bp = static_cast<AliMpBusPatch*>(next())) )
490     {
491       Int_t bin = hbp.FindBin(bp->GetId());
492       if ( hbp.GetBinContent(bin) > 0 )
493       {
494         x[n] = hbp.GetBinContent(bin);
495         ++n;
496       }
497       if ( hbp.GetBinContent(bin) > maxToleratedOccupancy )
498       {
499         ++nBusPatchesAboveLimit;
500       }
501       if ( hbp.GetBinContent(bin) < minToleratedOccupancy )
502       {
503         // check whether this buspatch has a reason to be absent (only valid
504         // if we got the config, otherwise we cannot do the test)
505         if ( hbuspatchconfig && hbuspatchconfig->GetBinContent(bin) > 0 )
506         {
507           // should be there, so it's an error
508           ++nBusPatchesBelowLimit;
509         }
510       }
511     }
512     
513     // computed the truncated mean of the occupancy values, in order to get a 
514     // reasonable y-range for the histogram (without giant peaks to the roof 
515     // for misbehaving buspatches).
516     ok = trim(n,x,alpha,tmean,tvar,ymin,ymax);
517     
518     delete[] x;
519   }
520   
521   if ( ok < 0 ) 
522   {
523     ymax = occMax;
524   }
525   else
526   {
527     ymax = TMath::Max(ymax,occMax);
528   }
529   
530   hbp.SetMaximum(ymax*1.4);
531   
532   AliMUONVQAChecker::ECheckCode rv(AliMUONVQAChecker::kInfo);
533
534   TObjArray messages;
535   messages.SetOwner(kTRUE);
536   
537   if ( neventsseen < NOTENOUGHEVENTLIMIT ) 
538   {
539     messages.Add(new TObjString(NOTENOUGHEVENTMESSAGE));
540   }
541   else
542   {
543     if ( ok < 0 ) 
544     {
545       messages.Add(new TObjString("Could not compute truncated mean. Not enough events ?"));
546       
547       if ( neventsused < TMath::Nint(0.1*neventsseen) )
548       {
549         messages.Add(new TObjString(Form("We've actually seen %d events, but used only %d !",neventsseen,neventsused)));
550         messages.Add(new TObjString("For a normal physics run, this is highly suspect !"));
551         messages.Add(new TObjString(NOTIFYEXPERTMESSAGE));
552         rv = AliMUONVQAChecker::kFatal;
553       }
554     }
555     else if (!nBusPatches)
556     {
557       messages.Add(new TObjString(Form("Could not get the total number of buspatches (%d). ERROR !!!",
558                          nBusPatches)));
559       messages.Add(new TObjString("Please check with expert !"));
560       rv = AliMUONVQAChecker::kFatal;
561     }
562     else
563     {
564       Float_t missingBusPatchFraction = nMissingBusPatches*100.0/nBusPatches;
565       Float_t aboveLimitFraction = nBusPatchesAboveLimit*100.0/nBusPatches;
566       Float_t belowLimitFraction = nBusPatchesBelowLimit*100.0/nBusPatches;
567       
568       messages.Add(new TObjString(Form("%5.2f %% of missing buspatches (%d out of %d)",missingBusPatchFraction,nMissingBusPatches,nBusPatches)));
569       messages.Add(new TObjString(Form("%5.2f %% bus patches above the %5.2f %% limit",aboveLimitFraction,maxToleratedOccupancy)));
570       messages.Add(new TObjString(Form("%5.2f %% bus patches below the %e %% limit",belowLimitFraction,minToleratedOccupancy)));
571       messages.Add(new TObjString(Form("Bus patch mean occupancy (truncated at %2d %%) is %7.2f %%",(Int_t)(alpha*100),tmean)));
572       
573       if ( aboveLimitFraction > recoParam.FractionOfBuspatchOutsideOccupancyLimit()*100.0 || 
574           belowLimitFraction > recoParam.FractionOfBuspatchOutsideOccupancyLimit()*100.0 ) 
575       {
576         rv = AliMUONVQAChecker::kError;
577       }
578       else
579       {
580         rv = AliMUONVQAChecker::kInfo;
581       }
582     }
583   }
584   
585   SetupHisto(neventsseen,neventsused,messages,hbp,rv);
586   
587   /// Make as well a version for DDL occupancy, that'll be used by the shifter
588   SetupHisto(neventsseen,neventsused,messages,hddl,rv);
589   
590   
591   hddl.SetStats(kFALSE);
592   
593   return rv;
594 }
595
596 //______________________________________________________________________________
597 AliMUONVQAChecker::ECheckCode 
598 AliMUONTrackerQAChecker::BeautifyReadoutHistograms(TH1& hrostatus,
599                                                    TH1& hrostatusnorm,
600                                                    const TH1& hbuspatchtokenerrors,
601                                                    Int_t neventsseen,
602                                                    Int_t neventsused,
603                                                    const AliMUONRecoParam& recoParam)
604 {
605   /// Normalize and put some text on the readout error histogram
606   /// Note in particular the treatment of tokenlost errors !
607   
608   hrostatusnorm.Reset();
609   
610   AliMUONVQAChecker::ECheckCode rv(AliMUONVQAChecker::kInfo);
611   
612   TObjArray messages;
613   messages.SetOwner(kTRUE);
614   
615   if ( neventsseen < NOTENOUGHEVENTLIMIT )
616   {
617     messages.Add(new TObjString(NOTENOUGHEVENTMESSAGE));
618   }
619   else
620   {
621     hrostatusnorm.Add(&hrostatus,100.0/neventsseen);
622     hrostatusnorm.SetOption("TEXT45"); // note : cannot use HIST option, otherwise the associated function (i.e. the tpavetext) is not drawn...
623     hrostatusnorm.SetMinimum(0.0);
624     hrostatusnorm.SetMaximum(100.0);
625     
626     Double_t tokenLost = hrostatusnorm.GetBinContent(hrostatusnorm.FindBin(1.0*AliMUONQAIndices::kTrackerRawNofTokenLostErrors));
627     
628     if ( tokenLost > recoParam.TokenLostLimit() )
629     {
630       rv = AliMUONVQAChecker::kError;
631       
632       messages.Add(new TObjString("There are some token lost errors !"));
633       messages.Add(new TObjString("PLEASE CHECK THE BUSY TIME FOR MUON !"));
634       messages.Add(new TObjString("If above 5 ms please have the MUON expert"));
635       messages.Add(new TObjString("check the following bus patches :"));
636       
637       for ( Int_t i = 1; i <= hbuspatchtokenerrors.GetNbinsX(); ++i ) 
638       {
639         if ( hbuspatchtokenerrors.GetBinContent(i) > 0 ) 
640         {
641           messages.Add(new TObjString(Form("BP %4d",i)));
642         }
643       }
644     }
645     
646     if ( hrostatusnorm.GetBinContent(hrostatusnorm.FindBin(AliMUONQAIndices::kTrackerRawNofEmptyEvents)) > 25.0 )
647     {
648       messages.Add(new TObjString("Too many empty events !"));
649       messages.Add(new TObjString(NOTIFYEXPERTMESSAGE));
650       rv = AliMUONVQAChecker::kFatal;      
651     }    
652   }
653    
654   SetupHisto(neventsseen,neventsused,messages,hrostatusnorm,rv,"text45");
655   
656   ShowTrueValue(hrostatusnorm,AliMUONQAIndices::kTrackerRawNofTokenLostErrors);
657   ShowTrueValue(hrostatusnorm,AliMUONQAIndices::kTrackerRawNofParityErrors);
658   ShowTrueValue(hrostatusnorm,AliMUONQAIndices::kTrackerRawNofPaddingErrors);
659   ShowTrueValue(hrostatusnorm,AliMUONQAIndices::kTrackerRawNofGlitchErrors);
660   
661   return rv;
662 }
663
664 //______________________________________________________________________________
665 AliMUONVQAChecker::ECheckCode 
666 AliMUONTrackerQAChecker::BeautifyEventsizeHistograms(TH1& heventsize,
667                                                      TH1& heventsizeperevent,
668                                                      Int_t neventsseen,
669                                                      Int_t neventsused,
670                                                      const AliMUONRecoParam& recoParam)
671 {
672   /// Normalize and put some text on the event size histogram
673
674   AliMUONVQAChecker::ECheckCode rv(AliMUONVQAChecker::kInfo);
675
676   heventsizeperevent.Reset();
677
678   TObjArray messages;
679   messages.SetOwner(kTRUE);
680   
681   if ( neventsseen < NOTENOUGHEVENTLIMIT )
682   {
683     messages.Add(new TObjString(NOTENOUGHEVENTMESSAGE));
684   }
685   else
686   {
687     heventsizeperevent.Add(&heventsize,1.0/neventsseen/1024.0);
688     heventsizeperevent.SetMinimum(0);
689     
690     Double_t totalEventSizePerEvent = heventsizeperevent.Integral();
691     
692     TString msg;
693     TString action;
694     
695     if ( totalEventSizePerEvent > recoParam.EventSizeHardLimit() ) 
696     {
697       rv = AliMUONVQAChecker::kError;
698       msg = "That is really too high.";
699       action = NOTIFYEXPERTMESSAGE;
700     }
701     else if ( totalEventSizePerEvent > recoParam.EventSizeSoftLimit() ) 
702     {
703       msg = "That is a bit high.";
704       action = "Please keep an eye on it.";
705       rv = AliMUONVQAChecker::kWarning;
706     }
707     else 
708     {
709       rv = AliMUONVQAChecker::kInfo;
710     }
711     
712     messages.Add(new TObjString(Form("<MCH event size> %5.1f KB/event\n",totalEventSizePerEvent)));
713     if (msg.Length()>0)
714     {
715       messages.Add(new TObjString(msg));
716       messages.Add(new TObjString(action));
717     }
718   }
719   
720   SetupHisto(neventsseen,neventsused,messages,heventsizeperevent,rv);
721   
722   return rv;
723 }
724
725
726