]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONTrackerQAChecker.cxx
- Update to read the "new" data format for the TailCancelation Filter Analysis
[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     if ( !hneventsseen || !hneventsused )
320     {
321       continue;
322     }
323     
324     AliMUONVQAChecker::ECheckCode c1 = AliMUONVQAChecker::kInfo;
325     AliMUONVQAChecker::ECheckCode c2 = AliMUONVQAChecker::kInfo;
326     AliMUONVQAChecker::ECheckCode c3 = AliMUONVQAChecker::kInfo;
327     
328     TH1* hbp = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchOccupancy,AliRecoParam::ConvertIndex(specie));    
329     TH1* hbpconfig = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchConfig,AliRecoParam::ConvertIndex(specie));
330     TH1* hddl = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerDDLOccupancy,AliRecoParam::ConvertIndex(specie));    
331
332     if ( hbp && hbpconfig && hddl ) 
333     {
334       c1 = BeautifyOccupancyHistograms(*hddl,*hbp,hbpconfig,neventsseen,neventsused,*recoParam);  
335     }
336     else
337     {
338       AliError(Form("Could not BeautifyOccupancyHistograms : hddl=%p hbpconfig=%p hbp=%p",hddl,hbpconfig,hbp));
339     }
340     
341     TH1* hbuspatchtokenerrors = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchTokenLostErrors,AliRecoParam::ConvertIndex(specie));
342     TH1* hrostatus = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerReadoutStatus,AliRecoParam::ConvertIndex(specie));    
343     TH1* hrostatusnorm = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerReadoutStatusPerEvent,AliRecoParam::ConvertIndex(specie));
344     
345     if ( hrostatus && hrostatusnorm && hbuspatchtokenerrors )
346     {
347       c2 = BeautifyReadoutHistograms(*hrostatus,*hrostatusnorm,*hbuspatchtokenerrors,
348                                      neventsseen,neventsused,*recoParam);
349     }
350     else
351     {
352       AliError(Form("Could not BeautifyReadoutHistograms : hrostatus=%p hrostatusnorm=%p hbuspatchtokenerrors=%p",
353                     hrostatus,hrostatusnorm,hbuspatchtokenerrors));
354     }
355     
356     
357     TH1* heventsize = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerDDLEventSize,AliRecoParam::ConvertIndex(specie));    
358     TH1* heventsizeperevent = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerDDLEventSizePerEvent,AliRecoParam::ConvertIndex(specie));
359     
360     if ( heventsize && heventsizeperevent ) 
361     {
362       c3 = BeautifyEventsizeHistograms(*heventsize,*heventsizeperevent,
363                                        neventsseen,neventsused,*recoParam);
364     }
365     else
366     {
367       AliError(Form("Could not BeautifyEventsizeHistograms heventsize=%p heventsizeperevent=%p",heventsize,heventsizeperevent));
368     }
369     
370     if ( c1 == AliMUONVQAChecker::kFatal || c2 == AliMUONVQAChecker::kFatal || c3 == AliMUONVQAChecker::kFatal )
371     {
372       rv[specie] = AliMUONVQAChecker::kFatal;
373     }
374     else if ( c1 == AliMUONVQAChecker::kError || c2 == AliMUONVQAChecker::kError || c3 == AliMUONVQAChecker::kError )
375     {
376       rv[specie] = AliMUONVQAChecker::kError;
377     }
378     else if ( c1 == AliMUONVQAChecker::kWarning || c2 == AliMUONVQAChecker::kWarning || c3 == AliMUONVQAChecker::kWarning )
379     {
380       rv[specie] = AliMUONVQAChecker::kWarning;
381     }
382     else
383     {
384       rv[specie] = AliMUONVQAChecker::kInfo;
385     }
386   }
387   
388   return rv;
389 }
390
391 //____________________________________________________________________________ 
392 AliMUONVQAChecker::ECheckCode
393 AliMUONTrackerQAChecker::BeautifyOccupancyHistograms(TH1& hddl,
394                                                      TH1& hbp, 
395                                                      const TH1* hbuspatchconfig, 
396                                                      Int_t neventsseen,
397                                                      Int_t neventsused,
398                                                      const AliMUONRecoParam& recoParam)
399 {
400   /// Put labels, limits and so on on the TrackerBusPatchOccupancy histograms
401   /// hbuspatchconfig and hbp must have the same bin definitions
402   
403   if ( hbuspatchconfig )
404   {
405     if ( hbp.GetNbinsX() != hbuspatchconfig->GetNbinsX() ||
406         hbp.GetXaxis()->GetXmin() != hbuspatchconfig->GetXaxis()->GetXmin() ||
407         hbp.GetXaxis()->GetXmax() != hbuspatchconfig->GetXaxis()->GetXmax() )
408     {
409       AliError("hbp and hbuspatchconfig histograms are not compatible !");
410       return AliMUONVQAChecker::kFatal;
411     }
412   }
413   
414   hddl.SetStats(kFALSE);
415   hbp.SetXTitle("Absolute Bus Patch Id");
416   hbp.SetYTitle("Occupancy (percent)");
417   hbp.SetStats(kFALSE);
418   
419   Double_t xmin = hbp.GetXaxis()->GetXmin();
420   Double_t xmax = hbp.GetXaxis()->GetXmax();
421   
422   Double_t occMax(0.1); // 0.1% y-limit for the plot
423   Double_t maxToleratedOccupancy(recoParam.BuspatchOccupancyHighLimit()*100.0); 
424   Double_t minToleratedOccupancy(recoParam.BuspatchOccupancyLowLimit()*100.0);   
425   TLine* line1 = new TLine(xmin,maxToleratedOccupancy,xmax,maxToleratedOccupancy);
426   line1->SetLineColor(1);
427   line1->SetLineWidth(1);
428
429   TLine* line2 = new TLine(xmin,minToleratedOccupancy,xmax,minToleratedOccupancy);
430   line2->SetLineColor(1);
431   line2->SetLineWidth(1);
432   
433   hbp.GetListOfFunctions()->Delete();
434   
435   hbp.GetListOfFunctions()->Add(line1);
436   hbp.GetListOfFunctions()->Add(line2);
437     
438   TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
439   AliMpBusPatch* bp(0x0);
440
441   Int_t nBusPatches(0);
442   Int_t nMissingBusPatches(0);
443   
444   while ( ( bp = static_cast<AliMpBusPatch*>(next())) )
445   {
446     ++nBusPatches;
447     
448     Int_t bin = hbp.FindBin(bp->GetId());
449     
450     if ( hbp.GetBinContent(bin) <= 0.0 ) 
451     {
452       ++nMissingBusPatches;
453     }
454   }
455   
456   next.Reset();
457   
458   Int_t ok(-1);
459   Int_t n(0);
460   Int_t nBusPatchesAboveLimit(0);
461   Int_t nBusPatchesBelowLimit(0);
462   Double_t alpha(0.1); // trim 10% of data
463   Double_t tmean(0.0),tvar(0.0);
464   Double_t ymin(0.0),ymax(0.0);
465   
466   if ( nBusPatches ) 
467   {
468     Double_t* x = new Double_t[nBusPatches];
469     
470     while ( ( bp = static_cast<AliMpBusPatch*>(next())) )
471     {
472       Int_t bin = hbp.FindBin(bp->GetId());
473       if ( hbp.GetBinContent(bin) > 0 )
474       {
475         x[n] = hbp.GetBinContent(bin);
476         ++n;
477       }
478       if ( hbp.GetBinContent(bin) > maxToleratedOccupancy )
479       {
480         ++nBusPatchesAboveLimit;
481       }
482       if ( hbp.GetBinContent(bin) < minToleratedOccupancy )
483       {
484         // check whether this buspatch has a reason to be absent (only valid
485         // if we got the config, otherwise we cannot do the test)
486         if ( hbuspatchconfig && hbuspatchconfig->GetBinContent(bin) > 0 )
487         {
488           // should be there, so it's an error
489           ++nBusPatchesBelowLimit;
490         }
491       }
492     }
493     
494     // computed the truncated mean of the occupancy values, in order to get a 
495     // reasonable y-range for the histogram (without giant peaks to the roof 
496     // for misbehaving buspatches).
497     ok = trim(n,x,alpha,tmean,tvar,ymin,ymax);
498     
499     delete[] x;
500   }
501   
502   if ( ok < 0 ) 
503   {
504     ymax = occMax;
505   }
506   else
507   {
508     ymax = TMath::Max(ymax,occMax);
509   }
510   
511   hbp.SetMaximum(ymax*1.4);
512   
513   AliMUONVQAChecker::ECheckCode rv(AliMUONVQAChecker::kInfo);
514
515   TObjArray messages;
516   messages.SetOwner(kTRUE);
517   
518   if ( neventsseen < NOTENOUGHEVENTLIMIT ) 
519   {
520     messages.Add(new TObjString(NOTENOUGHEVENTMESSAGE));
521   }
522   else
523   {
524     if ( ok < 0 ) 
525     {
526       messages.Add(new TObjString("Could not compute truncated mean. Not enough events ?"));
527       
528       if ( neventsused < TMath::Nint(0.1*neventsseen) )
529       {
530         messages.Add(new TObjString(Form("We've actually seen %d events, but used only %d !",neventsseen,neventsused)));
531         messages.Add(new TObjString("For a normal physics run, this is highly suspect !"));
532         messages.Add(new TObjString(NOTIFYEXPERTMESSAGE));
533         rv = AliMUONVQAChecker::kFatal;
534       }
535     }
536     else if (!nBusPatches)
537     {
538       messages.Add(new TObjString(Form("Could not get the total number of buspatches (%d). ERROR !!!",
539                          nBusPatches)));
540       messages.Add(new TObjString("Please check with expert !"));
541       rv = AliMUONVQAChecker::kFatal;
542     }
543     else
544     {
545       Float_t missingBusPatchFraction = nMissingBusPatches*100.0/nBusPatches;
546       Float_t aboveLimitFraction = nBusPatchesAboveLimit*100.0/nBusPatches;
547       Float_t belowLimitFraction = nBusPatchesBelowLimit*100.0/nBusPatches;
548       
549       messages.Add(new TObjString(Form("%5.2f %% of missing buspatches (%d out of %d)",missingBusPatchFraction,nMissingBusPatches,nBusPatches)));
550       messages.Add(new TObjString(Form("%5.2f %% bus patches above the %5.2f %% limit",aboveLimitFraction,maxToleratedOccupancy)));
551       messages.Add(new TObjString(Form("%5.2f %% bus patches below the %e %% limit",belowLimitFraction,minToleratedOccupancy)));
552       messages.Add(new TObjString(Form("Bus patch mean occupancy (truncated at %2d %%) is %7.2f %%",(Int_t)(alpha*100),tmean)));
553       
554       if ( aboveLimitFraction > recoParam.FractionOfBuspatchOutsideOccupancyLimit()*100.0 || 
555           belowLimitFraction > recoParam.FractionOfBuspatchOutsideOccupancyLimit()*100.0 ) 
556       {
557         rv = AliMUONVQAChecker::kError;
558       }
559       else
560       {
561         rv = AliMUONVQAChecker::kInfo;
562       }
563     }
564   }
565   
566   SetupHisto(neventsseen,neventsused,messages,hbp,rv);
567   
568   /// Make as well a version for DDL occupancy, that'll be used by the shifter
569   SetupHisto(neventsseen,neventsused,messages,hddl,rv);
570   
571   
572   hddl.SetStats(kFALSE);
573   
574   return rv;
575 }
576
577 //______________________________________________________________________________
578 AliMUONVQAChecker::ECheckCode 
579 AliMUONTrackerQAChecker::BeautifyReadoutHistograms(TH1& hrostatus,
580                                                    TH1& hrostatusnorm,
581                                                    const TH1& hbuspatchtokenerrors,
582                                                    Int_t neventsseen,
583                                                    Int_t neventsused,
584                                                    const AliMUONRecoParam& recoParam)
585 {
586   /// Normalize and put some text on the readout error histogram
587   /// Note in particular the treatment of tokenlost errors !
588   
589   hrostatusnorm.Reset();
590   
591   AliMUONVQAChecker::ECheckCode rv(AliMUONVQAChecker::kInfo);
592   
593   TObjArray messages;
594   messages.SetOwner(kTRUE);
595   
596   if ( neventsseen < NOTENOUGHEVENTLIMIT )
597   {
598     messages.Add(new TObjString(NOTENOUGHEVENTMESSAGE));
599   }
600   else
601   {
602     hrostatusnorm.Add(&hrostatus,100.0/neventsseen);
603     hrostatusnorm.SetOption("TEXT45"); // note : cannot use HIST option, otherwise the associated function (i.e. the tpavetext) is not drawn...
604     hrostatusnorm.SetMinimum(0.0);
605     
606     Double_t tokenLost = hrostatusnorm.GetBinContent(hrostatusnorm.FindBin(1.0*AliMUONQAIndices::kTrackerRawNofTokenLostErrors));
607     
608     if ( tokenLost > recoParam.TokenLostLimit() )
609     {
610       rv = AliMUONVQAChecker::kError;
611       
612       messages.Add(new TObjString("There are some token lost errors !"));
613       messages.Add(new TObjString("PLEASE CHECK THE BUSY TIME FOR MUON !"));
614       messages.Add(new TObjString("If above 5 ms please have the MUON expert"));
615       messages.Add(new TObjString("check the following bus patches :"));
616       
617       for ( Int_t i = 1; i <= hbuspatchtokenerrors.GetNbinsX(); ++i ) 
618       {
619         if ( hbuspatchtokenerrors.GetBinContent(i) > 0 ) 
620         {
621           messages.Add(new TObjString(Form("BP %4d",i)));
622         }
623       }
624     }
625     
626     if ( hrostatusnorm.GetBinContent(hrostatusnorm.FindBin(AliMUONQAIndices::kTrackerRawNofEmptyEvents)) > 25.0 )
627     {
628       messages.Add(new TObjString("Too many empty events !"));
629       messages.Add(new TObjString(NOTIFYEXPERTMESSAGE));
630       rv = AliMUONVQAChecker::kFatal;
631       
632     }
633   }
634    
635   SetupHisto(neventsseen,neventsused,messages,hrostatusnorm,rv,"text45");
636   
637   return rv;
638 }
639
640 //______________________________________________________________________________
641 AliMUONVQAChecker::ECheckCode 
642 AliMUONTrackerQAChecker::BeautifyEventsizeHistograms(TH1& heventsize,
643                                                      TH1& heventsizeperevent,
644                                                      Int_t neventsseen,
645                                                      Int_t neventsused,
646                                                      const AliMUONRecoParam& recoParam)
647 {
648   /// Normalize and put some text on the event size histogram
649
650   AliMUONVQAChecker::ECheckCode rv(AliMUONVQAChecker::kInfo);
651
652   heventsizeperevent.Reset();
653
654   TObjArray messages;
655   messages.SetOwner(kTRUE);
656   
657   if ( neventsseen < NOTENOUGHEVENTLIMIT )
658   {
659     messages.Add(new TObjString(NOTENOUGHEVENTMESSAGE));
660   }
661   else
662   {
663     heventsizeperevent.Add(&heventsize,1.0/neventsseen/1024.0);
664     heventsizeperevent.SetMinimum(0);
665     
666     Double_t totalEventSizePerEvent = heventsizeperevent.Integral();
667     
668     TString msg;
669     TString action;
670     
671     if ( totalEventSizePerEvent > recoParam.EventSizeHardLimit() ) 
672     {
673       rv = AliMUONVQAChecker::kError;
674       msg = "That is really too high.";
675       action = NOTIFYEXPERTMESSAGE;
676     }
677     else if ( totalEventSizePerEvent > recoParam.EventSizeSoftLimit() ) 
678     {
679       msg = "That is a bit high.";
680       action = "Please keep an eye on it.";
681       rv = AliMUONVQAChecker::kWarning;
682     }
683     else 
684     {
685       rv = AliMUONVQAChecker::kInfo;
686     }
687     
688     messages.Add(new TObjString(Form("<MCH event size> %5.1f KB/event\n",totalEventSizePerEvent)));
689     if (msg.Length()>0)
690     {
691       messages.Add(new TObjString(msg));
692       messages.Add(new TObjString(action));
693     }
694   }
695   
696   SetupHisto(neventsseen,neventsused,messages,heventsizeperevent,rv);
697   
698   return rv;
699 }
700
701
702