]>
Commit | Line | Data |
---|---|---|
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" | |
37 | #include "AliQAv1.h" | |
38 | #include "Riostream.h" | |
39 | #include "TAxis.h" | |
40 | #include "TDirectory.h" | |
41 | #include "TH1.h" | |
42 | #include "TLine.h" | |
43 | #include "TMath.h" | |
44 | #include "TPaveText.h" | |
b71c3d2d | 45 | #include "TGaxis.h" |
46 | #include "TVirtualPad.h" | |
ece56eb9 | 47 | |
48 | /// \cond CLASSIMP | |
49 | ClassImp(AliMUONTrackerQAChecker) | |
50 | /// \endcond | |
51 | ||
52 | namespace { | |
53 | ||
54 | //___________________________________________________________________________ | |
55 | int trim(Int_t n, | |
56 | Double_t* x, | |
57 | Double_t alpha, | |
58 | Double_t& tmean, | |
59 | Double_t& tvar, | |
60 | Double_t& min, | |
61 | Double_t& max) | |
62 | { | |
63 | // | |
64 | // Calculates the trimmed (tmean) mean | |
65 | // of a sample (x) and estimates the variance (tvar) | |
66 | // of that mean. | |
67 | // | |
68 | ||
69 | // First check input parameters | |
70 | ||
71 | // number of observations | |
72 | if ( n < 2 ) | |
73 | { | |
74 | return -1; | |
75 | } | |
76 | ||
77 | if ( alpha < 0 || alpha >= 0.5 ) | |
78 | // proportion of observations | |
79 | // to be trimmed at each end of the sorted sample | |
80 | { | |
81 | return -2; | |
82 | } | |
83 | ||
84 | // Input parameters are good. Let's move on. | |
85 | ||
86 | // Insure we use a sample sorted into ascending order. | |
87 | ||
88 | Int_t* indices = new Int_t[n]; | |
89 | ||
90 | TMath::Sort(n,x,indices,kFALSE); | |
91 | ||
92 | Double_t* sx = new Double_t[n]; | |
93 | ||
94 | for ( Int_t i = 0; i < n; ++i ) | |
95 | { | |
96 | sx[i] = x[indices[i]]; | |
97 | } | |
98 | delete[] indices; | |
99 | ||
100 | ||
101 | // Number of observations trimmed at each end. | |
102 | ||
103 | Int_t k = TMath::FloorNint(alpha * n); | |
104 | ||
105 | double sum = 0.0; | |
106 | ||
107 | for ( Int_t i = k; i < n - k ; ++i ) | |
108 | { | |
109 | sum += sx[i]; | |
110 | } | |
111 | ||
112 | tmean = sum / ( n - 2 * k ); | |
113 | ||
114 | double t2 = 0.0; | |
115 | ||
116 | for ( Int_t i = k; i < n - k; ++i ) | |
117 | { | |
118 | t2 += (sx[i] - tmean) * (sx[i] - tmean); | |
119 | } | |
120 | ||
121 | tvar = ( | |
122 | t2 + | |
123 | k * (sx[k] - tmean) * (sx[k] - tmean) + | |
124 | k * (sx[n - k - 1] - tmean) * (sx[n - k - 1] - tmean) | |
125 | ) / (n * n); | |
126 | ||
127 | // get the min and max for the non-rejected values | |
128 | min = DBL_MAX; | |
129 | max = 0.0; | |
130 | ||
131 | for ( Int_t i = k; i < n-k; ++i ) | |
132 | { | |
133 | min = TMath::Min(min,sx[i]); | |
134 | max = TMath::Max(max,sx[i]); | |
135 | } | |
136 | ||
137 | delete[] sx; | |
138 | ||
139 | return 0; | |
140 | } | |
f2e6387f | 141 | |
142 | //___________________________________________________________________________ | |
143 | void SetPaveColor(TPaveText& text, AliMUONVQAChecker::ECheckCode code) | |
144 | { | |
145 | const Int_t INFOCOLOR(3); // green = INFO | |
146 | const Int_t WARNINGCOLOR(5); // yellow = WARNING | |
147 | const Int_t ERRORCOLOR(6); // pink = ERROR | |
148 | const Int_t FATALCOLOR(2); // red = FATAL | |
149 | ||
150 | if ( code == AliMUONVQAChecker::kInfo ) text.SetFillColor(INFOCOLOR); | |
151 | else if ( code == AliMUONVQAChecker::kWarning ) text.SetFillColor(WARNINGCOLOR); | |
152 | else if ( code == AliMUONVQAChecker::kFatal) text.SetFillColor(FATALCOLOR); | |
153 | else text.SetFillColor(ERRORCOLOR); | |
154 | } | |
155 | ||
ece56eb9 | 156 | } |
157 | ||
158 | //__________________________________________________________________ | |
159 | AliMUONTrackerQAChecker::AliMUONTrackerQAChecker() : AliMUONVQAChecker() | |
160 | { | |
161 | /// ctor | |
162 | } | |
163 | ||
164 | //__________________________________________________________________ | |
165 | AliMUONTrackerQAChecker::~AliMUONTrackerQAChecker() | |
166 | { | |
167 | /// dtor | |
168 | } | |
169 | ||
170 | //__________________________________________________________________ | |
171 | AliMUONTrackerQAChecker::AliMUONTrackerQAChecker(const AliMUONTrackerQAChecker& qac) : | |
172 | AliMUONVQAChecker(qac) | |
173 | { | |
174 | /// copy ctor | |
175 | } | |
176 | ||
177 | //______________________________________________________________________________ | |
178 | AliMUONVQAChecker::ECheckCode* | |
486788fc | 179 | AliMUONTrackerQAChecker::CheckRecPoints(TObjArray ** list, const AliMUONRecoParam* /*recoParam*/) |
ece56eb9 | 180 | { |
181 | /// Check rec points | |
182 | /// Very binary check for the moment. | |
183 | ||
184 | AliCodeTimerAuto("",0); | |
185 | ||
186 | AliMUONVQAChecker::ECheckCode * rv = new AliMUONVQAChecker::ECheckCode[AliRecoParam::kNSpecies] ; | |
187 | for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) | |
188 | rv[specie] = AliMUONVQAChecker::kInfo; | |
189 | ||
6482f70b | 190 | |
ece56eb9 | 191 | for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) |
192 | { | |
6482f70b | 193 | TH1* h = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerNumberOfClustersPerDE,AliRecoParam::ConvertIndex(specie)); |
ece56eb9 | 194 | |
195 | if ( !h ) rv[specie] = AliMUONVQAChecker::kWarning; // only a warning if histo not found, in order not to kill anything because QA failed... | |
196 | ||
197 | else if ( h->GetMean() == 0.0 ) rv[specie] = MarkHisto(*h,AliMUONVQAChecker::kFatal); | |
198 | } | |
199 | return rv; | |
200 | } | |
201 | ||
202 | //______________________________________________________________________________ | |
203 | AliMUONVQAChecker::ECheckCode | |
204 | AliMUONTrackerQAChecker::MarkHisto(TH1& histo, AliMUONVQAChecker::ECheckCode value) const | |
205 | { | |
206 | /// Mark histo as originator of some QA error/warning | |
207 | ||
208 | if ( value != AliMUONVQAChecker::kInfo ) | |
209 | { | |
210 | histo.SetBit(AliQAv1::GetQABit()); | |
211 | } | |
212 | ||
213 | return value; | |
214 | } | |
215 | ||
216 | //______________________________________________________________________________ | |
217 | AliMUONVQAChecker::ECheckCode* | |
486788fc | 218 | AliMUONTrackerQAChecker::CheckESD(TObjArray ** list, const AliMUONRecoParam* /*recoParam*/) |
ece56eb9 | 219 | { |
220 | /// Check ESD | |
221 | ||
222 | AliCodeTimerAuto("",0); | |
223 | ||
224 | AliMUONVQAChecker::ECheckCode * rv = new AliMUONVQAChecker::ECheckCode[AliRecoParam::kNSpecies] ; | |
225 | for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) | |
226 | rv[specie] = AliMUONVQAChecker::kInfo; | |
227 | ||
228 | for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) { | |
229 | ||
6482f70b | 230 | TH1* h = AliQAv1::GetData(list,AliMUONQAIndices::kESDnTracks,AliRecoParam::ConvertIndex(specie)); |
ece56eb9 | 231 | |
232 | if (!h) rv[specie] = AliMUONVQAChecker::kWarning; | |
233 | ||
234 | else if ( h->GetMean() == 0.0 ) rv[specie] = MarkHisto(*h,AliMUONVQAChecker::kFatal); // no track -> fatal | |
235 | ||
6482f70b | 236 | h = AliQAv1::GetData(list,AliMUONQAIndices::kESDMatchTrig,AliRecoParam::ConvertIndex(specie)); |
ece56eb9 | 237 | |
238 | if (!h) rv[specie] = AliMUONVQAChecker::kWarning; | |
239 | ||
240 | else if (h->GetMean() == 0.0 ) rv[specie] = MarkHisto(*h,AliMUONVQAChecker::kError); // no trigger matching -> error | |
241 | } | |
242 | return rv; | |
243 | } | |
244 | ||
245 | //______________________________________________________________________________ | |
246 | AliMUONVQAChecker::ECheckCode* | |
486788fc | 247 | AliMUONTrackerQAChecker::CheckRaws(TObjArray ** list, const AliMUONRecoParam* recoParam) |
ece56eb9 | 248 | { |
249 | /// Check raws | |
250 | ||
251 | AliCodeTimerAuto("",0); | |
252 | ||
253 | if (!recoParam) return 0x0; | |
254 | ||
255 | AliMUONVQAChecker::ECheckCode * rv = new AliMUONVQAChecker::ECheckCode[AliRecoParam::kNSpecies] ; | |
256 | ||
257 | for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) | |
258 | { | |
259 | rv[specie] = AliMUONVQAChecker::kInfo; | |
260 | } | |
261 | ||
262 | for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) | |
263 | { | |
6482f70b | 264 | TH1* hbp = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchOccupancy,AliRecoParam::ConvertIndex(specie)); |
ece56eb9 | 265 | |
6482f70b | 266 | TH1* hnpads = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchNofPads,AliRecoParam::ConvertIndex(specie)); |
ece56eb9 | 267 | |
6482f70b | 268 | TH1* hbpconfig = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchConfig,AliRecoParam::ConvertIndex(specie)); |
ece56eb9 | 269 | |
64c2397e | 270 | TH1* hnevents = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerNofRawEventSeen,AliRecoParam::ConvertIndex(specie)); |
271 | ||
b71c3d2d | 272 | TH1* hddl = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerDDLOccupancy,AliRecoParam::ConvertIndex(specie)); |
f2e6387f | 273 | |
274 | TH1* hroe = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerReadoutErrors,AliRecoParam::ConvertIndex(specie)); | |
275 | ||
276 | TH1* hbuspatchtokenerrors = AliQAv1::GetData(list,AliMUONQAIndices::kTrackerBusPatchTokenLostErrors,AliRecoParam::ConvertIndex(specie)); | |
b71c3d2d | 277 | |
f2e6387f | 278 | if ( !hbp || !hnpads || !hnevents || !hddl || !hroe || ! hbuspatchtokenerrors ) |
ece56eb9 | 279 | { |
280 | continue; | |
281 | } | |
64c2397e | 282 | |
b71c3d2d | 283 | Int_t nevents = TMath::Nint(hnevents->GetBinContent(1)); |
284 | ||
f2e6387f | 285 | rv[specie] = BeautifyHistograms(*hddl,*hbp,*hroe,hbpconfig,*hnpads,*hbuspatchtokenerrors,nevents,*recoParam); |
ece56eb9 | 286 | } |
287 | ||
288 | return rv; | |
289 | } | |
290 | ||
291 | //____________________________________________________________________________ | |
292 | AliMUONVQAChecker::ECheckCode | |
f2e6387f | 293 | AliMUONTrackerQAChecker::BeautifyHistograms(TH1& hddl, |
294 | TH1& hbp, | |
295 | TH1& hroe, | |
296 | const TH1* hbuspatchconfig, | |
297 | const TH1& hnpads, | |
298 | const TH1& hbuspatchtokenerrors, | |
299 | Int_t nevents, | |
300 | const AliMUONRecoParam& recoParam) | |
ece56eb9 | 301 | { |
f2e6387f | 302 | /// Put labels, limits and so on on the TrackerBusPatchOccupancy and TrackerReadoutErrors histograms |
ece56eb9 | 303 | /// hbuspatchconfig and hbp must have the same bin definitions |
304 | ||
305 | if ( hbuspatchconfig ) | |
306 | { | |
307 | if ( hbp.GetNbinsX() != hbuspatchconfig->GetNbinsX() || | |
308 | hbp.GetXaxis()->GetXmin() != hbuspatchconfig->GetXaxis()->GetXmin() || | |
309 | hbp.GetXaxis()->GetXmax() != hbuspatchconfig->GetXaxis()->GetXmax() ) | |
310 | { | |
311 | AliError("hbp and hbuspatchconfig histograms are not compatible !"); | |
312 | return AliMUONVQAChecker::kFatal; | |
313 | } | |
314 | } | |
315 | ||
316 | hbp.SetXTitle("Absolute Bus Patch Id"); | |
317 | hbp.SetYTitle("Occupancy (percent)"); | |
318 | hbp.SetStats(kFALSE); | |
319 | ||
320 | Double_t xmin = hbp.GetXaxis()->GetXmin(); | |
321 | Double_t xmax = hbp.GetXaxis()->GetXmax(); | |
322 | ||
323 | Double_t occMax(0.1); // 0.1% y-limit for the plot | |
324 | Double_t maxToleratedOccupancy(recoParam.BuspatchOccupancyHighLimit()*100.0); | |
325 | Double_t minToleratedOccupancy(recoParam.BuspatchOccupancyLowLimit()*100.0); | |
326 | TLine* line1 = new TLine(xmin,maxToleratedOccupancy,xmax,maxToleratedOccupancy); | |
327 | line1->SetLineColor(1); | |
328 | line1->SetLineWidth(1); | |
329 | ||
330 | TLine* line2 = new TLine(xmin,minToleratedOccupancy,xmax,minToleratedOccupancy); | |
331 | line2->SetLineColor(1); | |
332 | line2->SetLineWidth(1); | |
333 | ||
334 | hbp.GetListOfFunctions()->Add(line1); | |
335 | hbp.GetListOfFunctions()->Add(line2); | |
336 | ||
337 | TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator()); | |
338 | AliMpBusPatch* bp(0x0); | |
339 | ||
340 | Int_t nMissingPads(0); | |
341 | Int_t nPads(0); | |
342 | Int_t nBusPatches(0); | |
343 | Int_t nMissingBusPatches(0); | |
344 | ||
345 | while ( ( bp = static_cast<AliMpBusPatch*>(next())) ) | |
346 | { | |
347 | Int_t bin = hbp.FindBin(bp->GetId()); | |
b1f9e9c3 | 348 | Int_t n = TMath::Nint(hnpads.GetBinContent(bin)); |
ece56eb9 | 349 | |
350 | ++nBusPatches; | |
351 | ||
352 | nPads += n; | |
353 | ||
354 | if ( hbp.GetBinContent(bin) <= 0 ) | |
355 | { | |
356 | nMissingPads += n; | |
357 | ++nMissingBusPatches; | |
358 | } | |
359 | } | |
360 | ||
361 | next.Reset(); | |
362 | ||
363 | Int_t ok(-1); | |
364 | Int_t n(0); | |
365 | Int_t nBusPatchesAboveLimit(0); | |
366 | Int_t nBusPatchesBelowLimit(0); | |
367 | Double_t alpha(0.1); // trim 10% of data | |
368 | Double_t tmean(0.0),tvar(0.0); | |
369 | Double_t ymin(0.0),ymax(0.0); | |
370 | AliMUONVQAChecker::ECheckCode rv(AliMUONVQAChecker::kFatal); // default value = serious problem | |
371 | ||
372 | if ( nBusPatches ) | |
373 | { | |
374 | Double_t* x = new Double_t[nBusPatches]; | |
375 | ||
376 | while ( ( bp = static_cast<AliMpBusPatch*>(next())) ) | |
377 | { | |
378 | Int_t bin = hbp.FindBin(bp->GetId()); | |
379 | if ( hbp.GetBinContent(bin) > 0 ) | |
380 | { | |
381 | x[n] = hbp.GetBinContent(bin); | |
382 | ++n; | |
383 | } | |
384 | if ( hbp.GetBinContent(bin) > maxToleratedOccupancy ) | |
385 | { | |
386 | ++nBusPatchesAboveLimit; | |
387 | } | |
388 | if ( hbp.GetBinContent(bin) < minToleratedOccupancy ) | |
389 | { | |
390 | // check whether this buspatch has a reason to be absent (only valid | |
391 | // if we got the config, otherwise we cannot do the test) | |
392 | if ( hbuspatchconfig && hbuspatchconfig->GetBinContent(bin) > 0 ) | |
393 | { | |
394 | // should be there, so it's an error | |
395 | ++nBusPatchesBelowLimit; | |
396 | } | |
397 | } | |
398 | } | |
399 | ||
400 | // computed the truncated mean of the occupancy values, in order to get a | |
401 | // reasonable y-range for the histogram (without giant peaks to the roof | |
402 | // for misbehaving buspatches). | |
403 | ok = trim(n,x,alpha,tmean,tvar,ymin,ymax); | |
404 | ||
405 | delete[] x; | |
406 | } | |
407 | ||
408 | if ( ok < 0 ) | |
409 | { | |
410 | ymax = occMax; | |
411 | } | |
412 | else | |
413 | { | |
414 | ymax = TMath::Max(ymax,occMax); | |
415 | } | |
416 | ||
417 | hbp.SetMaximum(ymax*1.4); | |
418 | ||
b71c3d2d | 419 | TPaveText* text = new TPaveText(0.30,0.50,0.99,0.99,"NDC"); |
ece56eb9 | 420 | |
64c2397e | 421 | text->AddText(Form("MCH RUN %d - %d events",AliCDBManager::Instance()->GetRun(),nevents)); |
422 | ||
423 | if ( ok < 0 ) | |
ece56eb9 | 424 | { |
425 | text->AddText("Could not compute truncated mean. Not enough events ?"); | |
64c2397e | 426 | text->AddText(Form("nBusPatches=%d n=%d",nBusPatches,n)); |
ece56eb9 | 427 | } |
428 | else if (!nPads || !nBusPatches) | |
429 | { | |
64c2397e | 430 | text->AddText(Form("Could not get the total number of pads (%d) or total number of buspatches (%d). ERROR !!!", |
431 | nPads,nBusPatches)); | |
ece56eb9 | 432 | } |
433 | else | |
434 | { | |
435 | Float_t missingPadFraction = nMissingPads*100.0/nPads; | |
436 | Float_t missingBusPatchFraction = nMissingBusPatches*100.0/nBusPatches; | |
437 | Float_t aboveLimitFraction = nBusPatchesAboveLimit*100.0/nBusPatches; | |
438 | Float_t belowLimitFraction = nBusPatchesBelowLimit*100.0/nBusPatches; | |
439 | ||
ece56eb9 | 440 | text->AddText(Form("%5.2f %% of missing buspatches (%d out of %d)",missingBusPatchFraction,nMissingBusPatches,nBusPatches)); |
441 | text->AddText(Form("%5.2f %% of missing pads (%d out of %d)",missingPadFraction,nMissingPads,nPads)); | |
442 | text->AddText(Form("%5.2f %% bus patches above the %5.2f %% limit",aboveLimitFraction,maxToleratedOccupancy)); | |
443 | text->AddText(Form("%5.2f %% bus patches below the %e %% limit",belowLimitFraction,minToleratedOccupancy)); | |
b71c3d2d | 444 | text->AddText(Form("Bus patch mean occupancy (truncated at %2d %%) is %7.2f %%",(Int_t)(alpha*100),tmean)); |
ece56eb9 | 445 | |
446 | if ( missingPadFraction >= 100.0 ) | |
447 | { | |
448 | rv = AliMUONVQAChecker::kFatal; | |
449 | } | |
450 | ||
451 | else if ( missingPadFraction > recoParam.MissingPadFractionLimit()*100.0 || | |
452 | aboveLimitFraction > recoParam.FractionOfBuspatchOutsideOccupancyLimit()*100.0 || | |
453 | belowLimitFraction > recoParam.FractionOfBuspatchOutsideOccupancyLimit()*100.0 ) | |
454 | { | |
455 | rv = AliMUONVQAChecker::kError; | |
456 | } | |
457 | else | |
458 | { | |
459 | rv = AliMUONVQAChecker::kInfo; | |
460 | } | |
461 | } | |
462 | ||
463 | hbp.GetListOfFunctions()->Add(text); | |
464 | ||
ece56eb9 | 465 | |
f2e6387f | 466 | SetPaveColor(*text,rv); |
467 | ||
b71c3d2d | 468 | /// Make as well a version for DDL occupancy, that'll be used by the shifter |
469 | ||
470 | hddl.GetListOfFunctions()->Add(text->Clone()); | |
471 | ||
472 | Bool_t aboveOnePercent(kFALSE); | |
473 | Bool_t aboveTwoPercent(kFALSE); | |
474 | ||
475 | for ( Int_t i = 1; i <= hddl.GetXaxis()->GetNbins(); ++i ) | |
476 | { | |
477 | Double_t b = hddl.GetBinContent(i); | |
478 | if ( b > 1.0 ) aboveOnePercent = kTRUE; | |
479 | if ( b > 2.0 ) aboveTwoPercent = kTRUE; | |
480 | ||
481 | } | |
482 | ||
483 | hddl.SetMaximum(2); | |
484 | hddl.SetFillStyle(0); | |
485 | if ( aboveOnePercent ) | |
486 | { | |
487 | hddl.SetFillStyle(1001); | |
488 | hddl.SetFillColor(kOrange); | |
489 | } | |
490 | if ( aboveTwoPercent ) | |
491 | { | |
492 | hddl.SetFillStyle(1001); | |
493 | hddl.SetFillColor(kRed); | |
494 | } | |
495 | hddl.SetLineWidth(3); | |
496 | hddl.SetStats(kFALSE); | |
497 | ||
f2e6387f | 498 | /// Finally make another pavetext for readout errors, in particular TokenLost ones ! |
499 | ||
500 | Double_t tokenLost = hroe.GetBinContent(hroe.FindBin(1.0*AliMUONQAIndices::kTrackerRawNofTokenLostErrors)); | |
501 | ||
502 | AliInfo(Form("tokenLost=%e",tokenLost)); | |
503 | ||
504 | if ( tokenLost > 0 ) | |
505 | { | |
506 | TPaveText* errText = new TPaveText(0.30,0.50,0.9,0.9,"NDC"); | |
507 | ||
508 | errText->AddText(Form("MCH RUN %d - %d events",AliCDBManager::Instance()->GetRun(),nevents)); | |
509 | errText->AddText("There are some token lost errors !"); | |
510 | errText->AddText("PLEASE CHECK THE BUSY TIME FOR MUON !"); | |
511 | errText->AddText("If above 5 ms please have the MUON expert"); | |
512 | errText->AddText("check the following bus patches :"); | |
513 | ||
514 | for ( Int_t i = 1; i <= hbuspatchtokenerrors.GetNbinsX(); ++i ) | |
515 | { | |
516 | if ( hbuspatchtokenerrors.GetBinContent(i) > 0 ) | |
517 | { | |
518 | errText->AddText(Form("BP %4d",i)); | |
519 | } | |
520 | } | |
521 | ||
522 | hroe.GetListOfFunctions()->Add(errText); | |
523 | ||
524 | rv = AliMUONVQAChecker::kFatal; | |
525 | ||
526 | SetPaveColor(*errText,rv); | |
527 | } | |
528 | ||
ece56eb9 | 529 | return rv; |
530 | } |