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