]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONTrackerQAChecker.cxx
Coverity fix
[u/mrichter/AliRoot.git] / MUON / AliMUONTrackerQAChecker.cxx
CommitLineData
ece56eb9 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"
6482f70b 32#include "AliMUONQAIndices.h"
ece56eb9 33#include "AliMUONRecoParam.h"
ece56eb9 34#include "AliMpBusPatch.h"
35#include "AliMpDDLStore.h"
36#include "AliQAv1.h"
ece56eb9 37#include "Riostream.h"
38#include "TAxis.h"
39#include "TDirectory.h"
b3d57767 40#include "TGaxis.h"
ece56eb9 41#include "TH1.h"
42#include "TLine.h"
43#include "TMath.h"
44#include "TPaveText.h"
b71c3d2d 45#include "TVirtualPad.h"
ffae31e4 46#include "TStyle.h"
47#include "TLatex.h"
ece56eb9 48
49/// \cond CLASSIMP
50ClassImp(AliMUONTrackerQAChecker)
51/// \endcond
52
53namespace {
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 }
b3d57767 142
143 //___________________________________________________________________________
144 Int_t GetColorFromCheckCode(AliMUONVQAChecker::ECheckCode code)
145 {
bd6fae1e 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;
b3d57767 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;
f2e6387f 157
158 //___________________________________________________________________________
b3d57767 159 void SetupHisto(Int_t neventsseen, Int_t neventsused, const TObjArray& messages, TH1& histo, AliMUONVQAChecker::ECheckCode code, const char* extraopt="")
f2e6387f 160 {
b3d57767 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
6fa4feac 197 histo.SetBit(TH1::kNoTitle);
b3d57767 198
ffae31e4 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 }
b3d57767 206
ffae31e4 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 }
f2e6387f 226 }
ece56eb9 227
ffae31e4 228}
ece56eb9 229//__________________________________________________________________
230AliMUONTrackerQAChecker::AliMUONTrackerQAChecker() : AliMUONVQAChecker()
231{
232 /// ctor
233}
234
235//__________________________________________________________________
236AliMUONTrackerQAChecker::~AliMUONTrackerQAChecker()
237{
238 /// dtor
239}
240
241//__________________________________________________________________
242AliMUONTrackerQAChecker::AliMUONTrackerQAChecker(const AliMUONTrackerQAChecker& qac) :
243 AliMUONVQAChecker(qac)
244{
245 /// copy ctor
246}
247
248//______________________________________________________________________________
249AliMUONVQAChecker::ECheckCode*
486788fc 250AliMUONTrackerQAChecker::CheckRecPoints(TObjArray ** list, const AliMUONRecoParam* /*recoParam*/)
ece56eb9 251{
252 /// Check rec points
253 /// Very binary check for the moment.
254
255 AliCodeTimerAuto("",0);
256
257 AliMUONVQAChecker::ECheckCode * rv = new AliMUONVQAChecker::ECheckCode[AliRecoParam::kNSpecies] ;
258 for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++)
259 rv[specie] = AliMUONVQAChecker::kInfo;
260
6482f70b 261
ece56eb9 262 for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++)
263 {
6482f70b 264 TH1* h = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerNumberOfClustersPerDE,AliRecoParam::ConvertIndex(specie));
ece56eb9 265
266 if ( !h ) rv[specie] = AliMUONVQAChecker::kWarning; // only a warning if histo not found, in order not to kill anything because QA failed...
267
268 else if ( h->GetMean() == 0.0 ) rv[specie] = MarkHisto(*h,AliMUONVQAChecker::kFatal);
269 }
270 return rv;
271}
272
273//______________________________________________________________________________
274AliMUONVQAChecker::ECheckCode
275AliMUONTrackerQAChecker::MarkHisto(TH1& histo, AliMUONVQAChecker::ECheckCode value) const
276{
277 /// Mark histo as originator of some QA error/warning
278
279 if ( value != AliMUONVQAChecker::kInfo )
280 {
281 histo.SetBit(AliQAv1::GetQABit());
282 }
283
284 return value;
285}
286
287//______________________________________________________________________________
288AliMUONVQAChecker::ECheckCode*
486788fc 289AliMUONTrackerQAChecker::CheckESD(TObjArray ** list, const AliMUONRecoParam* /*recoParam*/)
ece56eb9 290{
291 /// Check ESD
292
293 AliCodeTimerAuto("",0);
294
295 AliMUONVQAChecker::ECheckCode * rv = new AliMUONVQAChecker::ECheckCode[AliRecoParam::kNSpecies] ;
296 for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++)
297 rv[specie] = AliMUONVQAChecker::kInfo;
298
299 for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
300
6482f70b 301 TH1* h = AliQAv1::GetData(list,AliMUONQAIndices::kESDnTracks,AliRecoParam::ConvertIndex(specie));
ece56eb9 302
303 if (!h) rv[specie] = AliMUONVQAChecker::kWarning;
304
305 else if ( h->GetMean() == 0.0 ) rv[specie] = MarkHisto(*h,AliMUONVQAChecker::kFatal); // no track -> fatal
306
6482f70b 307 h = AliQAv1::GetData(list,AliMUONQAIndices::kESDMatchTrig,AliRecoParam::ConvertIndex(specie));
ece56eb9 308
309 if (!h) rv[specie] = AliMUONVQAChecker::kWarning;
310
311 else if (h->GetMean() == 0.0 ) rv[specie] = MarkHisto(*h,AliMUONVQAChecker::kError); // no trigger matching -> error
312 }
313 return rv;
314}
315
316//______________________________________________________________________________
317AliMUONVQAChecker::ECheckCode*
486788fc 318AliMUONTrackerQAChecker::CheckRaws(TObjArray ** list, const AliMUONRecoParam* recoParam)
ece56eb9 319{
320 /// Check raws
321
322 AliCodeTimerAuto("",0);
323
324 if (!recoParam) return 0x0;
325
326 AliMUONVQAChecker::ECheckCode * rv = new AliMUONVQAChecker::ECheckCode[AliRecoParam::kNSpecies] ;
327
328 for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++)
329 {
330 rv[specie] = AliMUONVQAChecker::kInfo;
331 }
332
333 for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++)
334 {
b3d57767 335 TH1* hneventsseen = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerNofPhysicsEventsSeen,AliRecoParam::ConvertIndex(specie));
336 TH1* hneventsused = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerNofGoodPhysicsEventsUsed,AliRecoParam::ConvertIndex(specie));
ece56eb9 337
b3d57767 338 if (!hneventsseen || !hneventsused ) continue;
339
340 Int_t neventsseen = TMath::Nint(hneventsseen->GetBinContent(1));
341 Int_t neventsused = TMath::Nint(hneventsused->GetBinContent(1));
342
b3d57767 343 AliMUONVQAChecker::ECheckCode c1 = AliMUONVQAChecker::kInfo;
344 AliMUONVQAChecker::ECheckCode c2 = AliMUONVQAChecker::kInfo;
345 AliMUONVQAChecker::ECheckCode c3 = AliMUONVQAChecker::kInfo;
346
347 TH1* hbp = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchOccupancy,AliRecoParam::ConvertIndex(specie));
6482f70b 348 TH1* hbpconfig = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchConfig,AliRecoParam::ConvertIndex(specie));
b3d57767 349 TH1* hddl = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerDDLOccupancy,AliRecoParam::ConvertIndex(specie));
ece56eb9 350
b3d57767 351 if ( hbp && hbpconfig && hddl )
352 {
353 c1 = BeautifyOccupancyHistograms(*hddl,*hbp,hbpconfig,neventsseen,neventsused,*recoParam);
354 }
355 else
356 {
357 AliError(Form("Could not BeautifyOccupancyHistograms : hddl=%p hbpconfig=%p hbp=%p",hddl,hbpconfig,hbp));
358 }
359
f2e6387f 360 TH1* hbuspatchtokenerrors = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchTokenLostErrors,AliRecoParam::ConvertIndex(specie));
b3d57767 361 TH1* hrostatus = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerReadoutStatus,AliRecoParam::ConvertIndex(specie));
362 TH1* hrostatusnorm = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerReadoutStatusPerEvent,AliRecoParam::ConvertIndex(specie));
b71c3d2d 363
b3d57767 364 if ( hrostatus && hrostatusnorm && hbuspatchtokenerrors )
ece56eb9 365 {
b3d57767 366 c2 = BeautifyReadoutHistograms(*hrostatus,*hrostatusnorm,*hbuspatchtokenerrors,
367 neventsseen,neventsused,*recoParam);
368 }
369 else
370 {
371 AliError(Form("Could not BeautifyReadoutHistograms : hrostatus=%p hrostatusnorm=%p hbuspatchtokenerrors=%p",
372 hrostatus,hrostatusnorm,hbuspatchtokenerrors));
ece56eb9 373 }
64c2397e 374
b3d57767 375
376 TH1* heventsize = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerDDLEventSize,AliRecoParam::ConvertIndex(specie));
377 TH1* heventsizeperevent = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerDDLEventSizePerEvent,AliRecoParam::ConvertIndex(specie));
378
379 if ( heventsize && heventsizeperevent )
380 {
381 c3 = BeautifyEventsizeHistograms(*heventsize,*heventsizeperevent,
382 neventsseen,neventsused,*recoParam);
383 }
384 else
385 {
386 AliError(Form("Could not BeautifyEventsizeHistograms heventsize=%p heventsizeperevent=%p",heventsize,heventsizeperevent));
387 }
388
389 if ( c1 == AliMUONVQAChecker::kFatal || c2 == AliMUONVQAChecker::kFatal || c3 == AliMUONVQAChecker::kFatal )
390 {
391 rv[specie] = AliMUONVQAChecker::kFatal;
392 }
393 else if ( c1 == AliMUONVQAChecker::kError || c2 == AliMUONVQAChecker::kError || c3 == AliMUONVQAChecker::kError )
394 {
395 rv[specie] = AliMUONVQAChecker::kError;
396 }
397 else if ( c1 == AliMUONVQAChecker::kWarning || c2 == AliMUONVQAChecker::kWarning || c3 == AliMUONVQAChecker::kWarning )
398 {
399 rv[specie] = AliMUONVQAChecker::kWarning;
400 }
401 else
402 {
403 rv[specie] = AliMUONVQAChecker::kInfo;
404 }
ece56eb9 405 }
406
407 return rv;
408}
409
410//____________________________________________________________________________
411AliMUONVQAChecker::ECheckCode
b3d57767 412AliMUONTrackerQAChecker::BeautifyOccupancyHistograms(TH1& hddl,
413 TH1& hbp,
414 const TH1* hbuspatchconfig,
415 Int_t neventsseen,
416 Int_t neventsused,
417 const AliMUONRecoParam& recoParam)
ece56eb9 418{
b3d57767 419 /// Put labels, limits and so on on the TrackerBusPatchOccupancy histograms
ece56eb9 420 /// hbuspatchconfig and hbp must have the same bin definitions
421
422 if ( hbuspatchconfig )
423 {
424 if ( hbp.GetNbinsX() != hbuspatchconfig->GetNbinsX() ||
425 hbp.GetXaxis()->GetXmin() != hbuspatchconfig->GetXaxis()->GetXmin() ||
426 hbp.GetXaxis()->GetXmax() != hbuspatchconfig->GetXaxis()->GetXmax() )
427 {
428 AliError("hbp and hbuspatchconfig histograms are not compatible !");
429 return AliMUONVQAChecker::kFatal;
430 }
431 }
432
b3d57767 433 hddl.SetStats(kFALSE);
ece56eb9 434 hbp.SetXTitle("Absolute Bus Patch Id");
435 hbp.SetYTitle("Occupancy (percent)");
436 hbp.SetStats(kFALSE);
437
438 Double_t xmin = hbp.GetXaxis()->GetXmin();
439 Double_t xmax = hbp.GetXaxis()->GetXmax();
440
441 Double_t occMax(0.1); // 0.1% y-limit for the plot
442 Double_t maxToleratedOccupancy(recoParam.BuspatchOccupancyHighLimit()*100.0);
443 Double_t minToleratedOccupancy(recoParam.BuspatchOccupancyLowLimit()*100.0);
444 TLine* line1 = new TLine(xmin,maxToleratedOccupancy,xmax,maxToleratedOccupancy);
445 line1->SetLineColor(1);
446 line1->SetLineWidth(1);
447
448 TLine* line2 = new TLine(xmin,minToleratedOccupancy,xmax,minToleratedOccupancy);
449 line2->SetLineColor(1);
450 line2->SetLineWidth(1);
451
ffae31e4 452 TList* lstF = hbp.GetListOfFunctions();
453 if (lstF) {
454 TObject *stats = lstF->FindObject("stats");
455 lstF->Remove(stats);
456 TObject *obj;
457 while ((obj = lstF->First())) { while(lstF->Remove(obj)) { } delete obj; }
458 if (stats) lstF->Add(stats);
459 }
bd6fae1e 460
ece56eb9 461 hbp.GetListOfFunctions()->Add(line1);
462 hbp.GetListOfFunctions()->Add(line2);
463
464 TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
465 AliMpBusPatch* bp(0x0);
466
ece56eb9 467 Int_t nBusPatches(0);
468 Int_t nMissingBusPatches(0);
469
470 while ( ( bp = static_cast<AliMpBusPatch*>(next())) )
471 {
ece56eb9 472 ++nBusPatches;
473
b3d57767 474 Int_t bin = hbp.FindBin(bp->GetId());
ece56eb9 475
b3d57767 476 if ( hbp.GetBinContent(bin) <= 0.0 )
ece56eb9 477 {
ece56eb9 478 ++nMissingBusPatches;
479 }
480 }
481
482 next.Reset();
483
484 Int_t ok(-1);
485 Int_t n(0);
486 Int_t nBusPatchesAboveLimit(0);
487 Int_t nBusPatchesBelowLimit(0);
488 Double_t alpha(0.1); // trim 10% of data
489 Double_t tmean(0.0),tvar(0.0);
490 Double_t ymin(0.0),ymax(0.0);
ece56eb9 491
492 if ( nBusPatches )
493 {
494 Double_t* x = new Double_t[nBusPatches];
495
496 while ( ( bp = static_cast<AliMpBusPatch*>(next())) )
497 {
498 Int_t bin = hbp.FindBin(bp->GetId());
499 if ( hbp.GetBinContent(bin) > 0 )
500 {
501 x[n] = hbp.GetBinContent(bin);
502 ++n;
503 }
504 if ( hbp.GetBinContent(bin) > maxToleratedOccupancy )
505 {
506 ++nBusPatchesAboveLimit;
507 }
508 if ( hbp.GetBinContent(bin) < minToleratedOccupancy )
509 {
510 // check whether this buspatch has a reason to be absent (only valid
511 // if we got the config, otherwise we cannot do the test)
512 if ( hbuspatchconfig && hbuspatchconfig->GetBinContent(bin) > 0 )
513 {
514 // should be there, so it's an error
515 ++nBusPatchesBelowLimit;
516 }
517 }
518 }
519
520 // computed the truncated mean of the occupancy values, in order to get a
521 // reasonable y-range for the histogram (without giant peaks to the roof
522 // for misbehaving buspatches).
523 ok = trim(n,x,alpha,tmean,tvar,ymin,ymax);
524
525 delete[] x;
526 }
527
528 if ( ok < 0 )
529 {
530 ymax = occMax;
531 }
532 else
533 {
534 ymax = TMath::Max(ymax,occMax);
535 }
536
537 hbp.SetMaximum(ymax*1.4);
538
b3d57767 539 AliMUONVQAChecker::ECheckCode rv(AliMUONVQAChecker::kInfo);
540
541 TObjArray messages;
542 messages.SetOwner(kTRUE);
64c2397e 543
b3d57767 544 if ( neventsseen < NOTENOUGHEVENTLIMIT )
ece56eb9 545 {
b3d57767 546 messages.Add(new TObjString(NOTENOUGHEVENTMESSAGE));
ece56eb9 547 }
548 else
549 {
b3d57767 550 if ( ok < 0 )
ece56eb9 551 {
b3d57767 552 messages.Add(new TObjString("Could not compute truncated mean. Not enough events ?"));
553
554 if ( neventsused < TMath::Nint(0.1*neventsseen) )
555 {
556 messages.Add(new TObjString(Form("We've actually seen %d events, but used only %d !",neventsseen,neventsused)));
557 messages.Add(new TObjString("For a normal physics run, this is highly suspect !"));
558 messages.Add(new TObjString(NOTIFYEXPERTMESSAGE));
559 rv = AliMUONVQAChecker::kFatal;
560 }
ece56eb9 561 }
b3d57767 562 else if (!nBusPatches)
ece56eb9 563 {
b3d57767 564 messages.Add(new TObjString(Form("Could not get the total number of buspatches (%d). ERROR !!!",
565 nBusPatches)));
566 messages.Add(new TObjString("Please check with expert !"));
567 rv = AliMUONVQAChecker::kFatal;
ece56eb9 568 }
569 else
570 {
b3d57767 571 Float_t missingBusPatchFraction = nMissingBusPatches*100.0/nBusPatches;
572 Float_t aboveLimitFraction = nBusPatchesAboveLimit*100.0/nBusPatches;
573 Float_t belowLimitFraction = nBusPatchesBelowLimit*100.0/nBusPatches;
574
575 messages.Add(new TObjString(Form("%5.2f %% of missing buspatches (%d out of %d)",missingBusPatchFraction,nMissingBusPatches,nBusPatches)));
576 messages.Add(new TObjString(Form("%5.2f %% bus patches above the %5.2f %% limit",aboveLimitFraction,maxToleratedOccupancy)));
577 messages.Add(new TObjString(Form("%5.2f %% bus patches below the %e %% limit",belowLimitFraction,minToleratedOccupancy)));
578 messages.Add(new TObjString(Form("Bus patch mean occupancy (truncated at %2d %%) is %7.2f %%",(Int_t)(alpha*100),tmean)));
579
580 if ( aboveLimitFraction > recoParam.FractionOfBuspatchOutsideOccupancyLimit()*100.0 ||
581 belowLimitFraction > recoParam.FractionOfBuspatchOutsideOccupancyLimit()*100.0 )
582 {
583 rv = AliMUONVQAChecker::kError;
584 }
585 else
586 {
587 rv = AliMUONVQAChecker::kInfo;
588 }
ece56eb9 589 }
590 }
591
b3d57767 592 SetupHisto(neventsseen,neventsused,messages,hbp,rv);
ece56eb9 593
b71c3d2d 594 /// Make as well a version for DDL occupancy, that'll be used by the shifter
b3d57767 595 SetupHisto(neventsseen,neventsused,messages,hddl,rv);
b71c3d2d 596
b71c3d2d 597
b71c3d2d 598 hddl.SetStats(kFALSE);
599
b3d57767 600 return rv;
601}
602
603//______________________________________________________________________________
604AliMUONVQAChecker::ECheckCode
605AliMUONTrackerQAChecker::BeautifyReadoutHistograms(TH1& hrostatus,
606 TH1& hrostatusnorm,
607 const TH1& hbuspatchtokenerrors,
608 Int_t neventsseen,
609 Int_t neventsused,
610 const AliMUONRecoParam& recoParam)
611{
612 /// Normalize and put some text on the readout error histogram
613 /// Note in particular the treatment of tokenlost errors !
614
b3d57767 615 hrostatusnorm.Reset();
f2e6387f 616
b3d57767 617 AliMUONVQAChecker::ECheckCode rv(AliMUONVQAChecker::kInfo);
f2e6387f 618
b3d57767 619 TObjArray messages;
620 messages.SetOwner(kTRUE);
f2e6387f 621
b3d57767 622 if ( neventsseen < NOTENOUGHEVENTLIMIT )
f2e6387f 623 {
b3d57767 624 messages.Add(new TObjString(NOTENOUGHEVENTMESSAGE));
625 }
626 else
627 {
628 hrostatusnorm.Add(&hrostatus,100.0/neventsseen);
629 hrostatusnorm.SetOption("TEXT45"); // note : cannot use HIST option, otherwise the associated function (i.e. the tpavetext) is not drawn...
630 hrostatusnorm.SetMinimum(0.0);
ffae31e4 631 hrostatusnorm.SetMaximum(100.0);
f2e6387f 632
b3d57767 633 Double_t tokenLost = hrostatusnorm.GetBinContent(hrostatusnorm.FindBin(1.0*AliMUONQAIndices::kTrackerRawNofTokenLostErrors));
f2e6387f 634
b3d57767 635 if ( tokenLost > recoParam.TokenLostLimit() )
f2e6387f 636 {
b3d57767 637 rv = AliMUONVQAChecker::kError;
638
639 messages.Add(new TObjString("There are some token lost errors !"));
640 messages.Add(new TObjString("PLEASE CHECK THE BUSY TIME FOR MUON !"));
641 messages.Add(new TObjString("If above 5 ms please have the MUON expert"));
642 messages.Add(new TObjString("check the following bus patches :"));
643
644 for ( Int_t i = 1; i <= hbuspatchtokenerrors.GetNbinsX(); ++i )
f2e6387f 645 {
b3d57767 646 if ( hbuspatchtokenerrors.GetBinContent(i) > 0 )
647 {
648 messages.Add(new TObjString(Form("BP %4d",i)));
649 }
f2e6387f 650 }
651 }
652
b3d57767 653 if ( hrostatusnorm.GetBinContent(hrostatusnorm.FindBin(AliMUONQAIndices::kTrackerRawNofEmptyEvents)) > 25.0 )
654 {
655 messages.Add(new TObjString("Too many empty events !"));
656 messages.Add(new TObjString(NOTIFYEXPERTMESSAGE));
ffae31e4 657 rv = AliMUONVQAChecker::kFatal;
658 }
b3d57767 659 }
660
661 SetupHisto(neventsseen,neventsused,messages,hrostatusnorm,rv,"text45");
662
ffae31e4 663 ShowTrueValue(hrostatusnorm,AliMUONQAIndices::kTrackerRawNofTokenLostErrors);
664 ShowTrueValue(hrostatusnorm,AliMUONQAIndices::kTrackerRawNofParityErrors);
665 ShowTrueValue(hrostatusnorm,AliMUONQAIndices::kTrackerRawNofPaddingErrors);
666 ShowTrueValue(hrostatusnorm,AliMUONQAIndices::kTrackerRawNofGlitchErrors);
667
b3d57767 668 return rv;
669}
670
671//______________________________________________________________________________
672AliMUONVQAChecker::ECheckCode
673AliMUONTrackerQAChecker::BeautifyEventsizeHistograms(TH1& heventsize,
674 TH1& heventsizeperevent,
675 Int_t neventsseen,
676 Int_t neventsused,
677 const AliMUONRecoParam& recoParam)
678{
679 /// Normalize and put some text on the event size histogram
680
681 AliMUONVQAChecker::ECheckCode rv(AliMUONVQAChecker::kInfo);
682
b3d57767 683 heventsizeperevent.Reset();
f2e6387f 684
b3d57767 685 TObjArray messages;
686 messages.SetOwner(kTRUE);
687
688 if ( neventsseen < NOTENOUGHEVENTLIMIT )
689 {
690 messages.Add(new TObjString(NOTENOUGHEVENTMESSAGE));
691 }
692 else
693 {
9074a9a9 694 heventsizeperevent.Add(&heventsize,1.0/neventsseen/1024.0);
b3d57767 695 heventsizeperevent.SetMinimum(0);
696
697 Double_t totalEventSizePerEvent = heventsizeperevent.Integral();
698
699 TString msg;
700 TString action;
701
702 if ( totalEventSizePerEvent > recoParam.EventSizeHardLimit() )
703 {
bd6fae1e 704 rv = AliMUONVQAChecker::kError;
b3d57767 705 msg = "That is really too high.";
706 action = NOTIFYEXPERTMESSAGE;
707 }
708 else if ( totalEventSizePerEvent > recoParam.EventSizeSoftLimit() )
709 {
710 msg = "That is a bit high.";
711 action = "Please keep an eye on it.";
bd6fae1e 712 rv = AliMUONVQAChecker::kWarning;
b3d57767 713 }
714 else
715 {
716 rv = AliMUONVQAChecker::kInfo;
717 }
f2e6387f 718
b3d57767 719 messages.Add(new TObjString(Form("<MCH event size> %5.1f KB/event\n",totalEventSizePerEvent)));
720 if (msg.Length()>0)
721 {
722 messages.Add(new TObjString(msg));
723 messages.Add(new TObjString(action));
724 }
f2e6387f 725 }
726
b3d57767 727 SetupHisto(neventsseen,neventsused,messages,heventsizeperevent,rv);
728
ece56eb9 729 return rv;
730}
b3d57767 731
732
733