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