]>
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" | |
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 | |
50 | 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 | 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 | //__________________________________________________________________ |
230 | AliMUONTrackerQAChecker::AliMUONTrackerQAChecker() : AliMUONVQAChecker() | |
231 | { | |
232 | /// ctor | |
233 | } | |
234 | ||
235 | //__________________________________________________________________ | |
236 | AliMUONTrackerQAChecker::~AliMUONTrackerQAChecker() | |
237 | { | |
238 | /// dtor | |
239 | } | |
240 | ||
241 | //__________________________________________________________________ | |
242 | AliMUONTrackerQAChecker::AliMUONTrackerQAChecker(const AliMUONTrackerQAChecker& qac) : | |
243 | AliMUONVQAChecker(qac) | |
244 | { | |
245 | /// copy ctor | |
246 | } | |
247 | ||
248 | //______________________________________________________________________________ | |
249 | AliMUONVQAChecker::ECheckCode* | |
486788fc | 250 | AliMUONTrackerQAChecker::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 | //______________________________________________________________________________ | |
274 | AliMUONVQAChecker::ECheckCode | |
275 | AliMUONTrackerQAChecker::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 | //______________________________________________________________________________ | |
288 | AliMUONVQAChecker::ECheckCode* | |
486788fc | 289 | AliMUONTrackerQAChecker::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 | //______________________________________________________________________________ | |
317 | AliMUONVQAChecker::ECheckCode* | |
486788fc | 318 | AliMUONTrackerQAChecker::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 | //____________________________________________________________________________ | |
411 | AliMUONVQAChecker::ECheckCode | |
b3d57767 | 412 | AliMUONTrackerQAChecker::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 | //______________________________________________________________________________ | |
604 | AliMUONVQAChecker::ECheckCode | |
605 | AliMUONTrackerQAChecker::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 | //______________________________________________________________________________ | |
672 | AliMUONVQAChecker::ECheckCode | |
673 | AliMUONTrackerQAChecker::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 |