]>
Commit | Line | Data |
---|---|---|
c03351ac | 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 | **************************************************************************/ | |
c03351ac | 15 | //... |
16 | // Checks the quality assurance. | |
17 | // By comparing with reference data | |
18 | // Skeleton for T0 | |
f6c2d5e2 | 19 | //--------------------------------------------- |
20 | //checkig without reference data: | |
21 | //for RAW QA all histograms should have approximatly the same | |
22 | //number of entries as RefPoint | |
23 | //for Rec Points checks | |
24 | // - amplitude measured by 2 methos | |
25 | // - online and offline T0 measurements | |
26 | // for ESD quality of reconstruction ( and measurements): | |
27 | // RMS of vertex and T0 less than 75ps | |
28 | // | |
29 | // Alla.Maevskaya@cern.ch | |
c03351ac | 30 | //... |
31 | ||
32 | // --- ROOT system --- | |
b09247a2 | 33 | #include <Riostream.h> |
c03351ac | 34 | #include <TClass.h> |
35 | #include <TH1F.h> | |
be3ada9f | 36 | #include <TF1.h> |
37 | #include <TFitResultPtr.h> | |
0d849919 | 38 | #include <TH2.h> |
c03351ac | 39 | #include <TIterator.h> |
40 | #include <TKey.h> | |
41 | #include <TFile.h> | |
446d6ec4 | 42 | #include <TMath.h> |
0d849919 | 43 | #include <TString.h> |
be3ada9f | 44 | #include <TPaveText.h> |
c03351ac | 45 | |
46 | // --- Standard library --- | |
47 | ||
48 | // --- AliRoot header files --- | |
49 | #include "AliLog.h" | |
4e25ac79 | 50 | #include "AliQAv1.h" |
c03351ac | 51 | #include "AliQAChecker.h" |
394c1a6d | 52 | #include "AliCDBEntry.h" |
53 | #include "AliQAManager.h" | |
c03351ac | 54 | #include "AliT0QAChecker.h" |
55 | ||
56 | ClassImp(AliT0QAChecker) | |
be3ada9f | 57 | //____________________________________________________________________________ |
58 | AliT0QAChecker::AliT0QAChecker() : | |
59 | AliQACheckerBase("T0","T0 Quality Assurance Checker") | |
60 | ||
61 | { | |
62 | // Standard constructor | |
63 | ||
64 | } | |
65 | ||
49e33ff1 | 66 | //____________________________________________________________________________ |
67 | AliT0QAChecker::AliT0QAChecker(const AliT0QAChecker& qac): | |
68 | AliQACheckerBase(qac.GetName(), qac.GetTitle()) | |
69 | { | |
70 | // copy constructor | |
71 | AliError("Copy should not be used with this class\n"); | |
72 | } | |
73 | //____________________________________________________________________________ | |
74 | AliT0QAChecker& AliT0QAChecker::operator=(const AliT0QAChecker& qac){ | |
75 | // assignment operator | |
76 | this->~AliT0QAChecker(); | |
77 | new(this)AliT0QAChecker(qac); | |
78 | return *this; | |
79 | } | |
80 | ||
81 | ||
be3ada9f | 82 | //____________________________________________________________________________ |
83 | AliT0QAChecker::~AliT0QAChecker(){ | |
84 | // destructor | |
85 | ||
86 | } | |
c03351ac | 87 | |
4e67e173 | 88 | //__________________________________________________________________ |
a42ceb0e | 89 | void AliT0QAChecker::Check(Double_t * test, AliQAv1::ALITASK_t index, TObjArray ** list, const AliDetectorRecoParam * /*recoParam*/) |
3685c21c | 90 | { |
91 | ||
92 | // Super-basic check on the QA histograms on the input list: | |
93 | // look whether they are empty! | |
a42ceb0e | 94 | |
be3ada9f | 95 | char * detOCDBDir = Form("T0/%s/%s", AliQAv1::GetRefOCDBDirName(), AliQAv1::GetRefDataDirName()) ; |
8825d145 | 96 | |
394c1a6d | 97 | AliCDBEntry *QARefRec = AliQAManager::QAManager()->Get(detOCDBDir); |
98 | // QARefRec->Dump(); | |
99 | if( !QARefRec){ | |
100 | AliInfo("QA reference data NOT retrieved for Reconstruction check. No T0 reference distribution"); | |
101 | } | |
c724dd64 | 102 | |
49e33ff1 | 103 | |
104 | for(Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++){ | |
105 | test[specie] = 1.0; //FK// initiate qa flag for the whole set of histograms as good | |
106 | } | |
107 | ||
108 | ||
109 | for(Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) { | |
110 | if(!(AliQAv1::Instance()->IsEventSpecieSet(specie) && list[specie]) || list[specie]->GetEntries() == 0) { | |
92664bc8 | 111 | continue; |
57acd2d2 | 112 | } |
49e33ff1 | 113 | if(index == AliQAv1::kRAW){ |
114 | ||
115 | if(AliRecoParam::ConvertIndex(specie) == AliRecoParam::kCalib){// if (index == AliQAv1::kRAW ) | |
116 | //check laser data efficiencies | |
117 | Double_t qaFlag = CheckLaser(list[specie]); | |
118 | if(qaFlag < test[specie]) test[specie] = qaFlag; | |
119 | } | |
120 | ||
121 | if(AliRecoParam::ConvertIndex(specie) == AliRecoParam::kCalib || | |
122 | AliRecoParam::ConvertIndex(specie) == AliRecoParam::kDefault){ | |
123 | ||
124 | //check BCID | |
125 | Double_t qaFlag = CheckBCID(list[specie]); | |
126 | if(qaFlag < test[specie]) test[specie] = qaFlag; | |
127 | } | |
128 | ||
129 | if(AliRecoParam::ConvertIndex(specie) == AliRecoParam::kDefault){ | |
130 | //check physics | |
131 | Double_t qaFlag = CheckRaw(list[specie]); | |
132 | if(qaFlag < test[specie]) test[specie] = qaFlag; | |
92664bc8 | 133 | } |
49e33ff1 | 134 | } |
135 | ||
136 | if(index == AliQAv1::kESD && AliRecoParam::Convert(specie) != AliRecoParam::kCalib){ | |
92664bc8 | 137 | test[specie] = CheckESD(list[specie]); |
49e33ff1 | 138 | } |
be3ada9f | 139 | } |
140 | } | |
394c1a6d | 141 | |
be3ada9f | 142 | //-------------------------------------------------------------------------- |
49e33ff1 | 143 | Double_t AliT0QAChecker::CheckLaser(TObjArray *listrec) const { |
be3ada9f | 144 | |
49e33ff1 | 145 | TH1 *hdata; |
146 | TH1 *fhRawEff[10]; | |
147 | Int_t nEffHistos=0; | |
148 | ||
149 | //thresholds for warning and error on efficiencies | |
150 | Float_t thrWarning = 0.5; //FK// warning level | |
151 | Float_t thrError = 0.2; //FK// error level | |
152 | ||
153 | const int kNumberOfHistos = 3; | |
154 | Int_t consecutiveHistoNumber[kNumberOfHistos] = { 207, 208, 209}; //Checked histos fhCDFeff, hEffLED, hEffQTC | |
155 | Int_t qualityFlag[kNumberOfHistos]; //quality flag for a given histogram | |
156 | ||
157 | for(Int_t ir=0; ir<kNumberOfHistos; ir++){ | |
158 | qualityFlag[ir] = kT0Info; //init quality flag for a given histogram | |
159 | ||
160 | hdata = (TH1*) listrec->UncheckedAt(consecutiveHistoNumber[ir]); | |
161 | if(hdata){ | |
162 | fhRawEff[nEffHistos] = hdata; | |
163 | nEffHistos++; | |
164 | } | |
165 | } | |
166 | ||
167 | TLine linelowyellow(0, thrWarning, 24, thrWarning); | |
168 | linelowyellow.SetLineColor(5); | |
169 | linelowyellow.SetLineStyle(3); | |
170 | linelowyellow.SetLineWidth(4); | |
171 | TLine linelowred(0, thrError, 24, thrError); | |
172 | linelowred.SetLineColor(2); | |
173 | linelowred.SetLineStyle(3); | |
174 | linelowred.SetLineWidth(4); | |
175 | ||
176 | Bool_t bEffHistosNotEmpty = kFALSE; //check if all histograms have some counts | |
177 | ||
178 | for(Int_t ih = 0; ih < nEffHistos; ih++){ | |
179 | ||
180 | EraseOldMessages((TH1*) fhRawEff[ih]);// clean objects added at previous checks | |
be3ada9f | 181 | |
49e33ff1 | 182 | fhRawEff[ih]->SetLineWidth(2); |
183 | fhRawEff[ih]->SetMaximum(2.); | |
184 | fhRawEff[ih]->SetMinimum(0.); | |
185 | fhRawEff[ih]->GetListOfFunctions()->Add((TLine*)linelowyellow.Clone()); | |
186 | fhRawEff[ih]->GetListOfFunctions()->Add((TLine*)linelowred.Clone()); | |
394c1a6d | 187 | |
49e33ff1 | 188 | if(fhRawEff[ih]->Integral()>0) bEffHistosNotEmpty = kTRUE; //this histo does have some counts in it |
189 | ||
190 | Int_t nbins= fhRawEff[ih]->GetNbinsX(); | |
191 | for(Int_t ib=1; ib<=nbins; ib++){ //loop over bins and check if the efficiency is above level | |
192 | ||
193 | Float_t chcont = fhRawEff[ih]->GetBinContent(ib); | |
194 | if(chcont < thrWarning && qualityFlag[ih] > kT0Error ) qualityFlag[ih] = kT0Warning;//Warning level | |
195 | if(chcont < thrError) qualityFlag[ih] = kT0Error;//Error level | |
be3ada9f | 196 | } |
49e33ff1 | 197 | |
198 | if(qualityFlag[ih] == kT0Info ){ | |
199 | AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 efficiency %s is good", fhRawEff[ih]->GetName() )); | |
200 | }else if(qualityFlag[ih] == kT0Warning){ | |
201 | AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 efficiency %s is not so good", fhRawEff[ih]->GetName() )); | |
202 | }else if(qualityFlag[ih] == kT0Error){ | |
203 | AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 efficiency %s is not good", fhRawEff[ih]->GetName() )); | |
204 | } | |
205 | } | |
206 | ||
207 | //executive summary | |
208 | int lowestQualityFlag = (int) kT0Info; | |
209 | for(Int_t ih = 0; ih < nEffHistos; ih++){ | |
210 | ||
211 | if(!bEffHistosNotEmpty){ //all laser efficiency plots are empty | |
212 | TPaveText text(0.20,0.50,0.99,0.99,"NDC"); | |
213 | text.AddText(Form("1) T0 is in BEAMTUNIG: empty plots are ok")); | |
214 | text.AddText(Form("2) T0 is in READY: check calibriation trigger")); | |
215 | text.AddText(Form("if also physics data are empty report")); | |
216 | text.AddText(Form("readout problem to the T0 on-call expert")); | |
217 | fhRawEff[ih]->GetListOfFunctions()->Add((TPaveText*)text.Clone()); | |
218 | } | |
219 | ||
220 | if( qualityFlag[ih] <lowestQualityFlag ) lowestQualityFlag = qualityFlag[ih]; | |
221 | } | |
222 | ||
223 | return ConvertQualityFlagToDouble(lowestQualityFlag); | |
224 | } | |
225 | //-------------------------------------------------------------------------- | |
226 | Double_t AliT0QAChecker::CheckBCID(TObjArray *listrec) const { | |
227 | ||
228 | Int_t qualityFlagBCID = kT0Info; //init quality flag for a given histogram; | |
229 | ||
230 | TH2F *hBCID = (TH2F*) listrec->UncheckedAt(224); //BCID versus TRM BCID | |
231 | ||
be3ada9f | 232 | |
49e33ff1 | 233 | // clean objects added at previous checks |
234 | EraseOldMessages((TH1*)hBCID); | |
235 | ||
236 | if(hBCID->Integral()>0){ | |
237 | //BCID does have some counts in it | |
238 | ||
239 | Int_t nbinsX = hBCID->GetNbinsX(); | |
240 | Int_t nbinsY = hBCID->GetNbinsY(); | |
241 | double entriesOnDiagonal = 0; //count diagonal and off diagonal entries | |
242 | double entriesOffDiagonal = 0; | |
243 | ||
244 | for(Int_t ix=1; ix<=nbinsX; ix++){ | |
245 | for(Int_t iy=1; iy<=nbinsY; iy++){ | |
246 | if(TMath::Abs(ix-iy)<6) entriesOnDiagonal += hBCID->GetBinContent(ix,iy); //On Diagonal | |
247 | else entriesOffDiagonal += hBCID->GetBinContent(ix,iy); //Off Diagonal | |
57acd2d2 | 248 | } |
49e33ff1 | 249 | } |
250 | if(entriesOnDiagonal<1 || entriesOffDiagonal>0){ | |
251 | qualityFlagBCID = kT0Error; //no entries on diagonal | |
252 | AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 %s is not diagonal", hBCID->GetName() )); | |
253 | ||
254 | TPaveText text(0.20,0.50,0.99,0.99,"NDC"); | |
255 | text.AddText(Form("Check if entries are on a diagonal.")); | |
256 | text.AddText(Form("Report readout problem to the T0 on-call expert")); | |
257 | hBCID->GetListOfFunctions()->Add((TPaveText*)text.Clone()); | |
258 | } | |
259 | }else{ //BCID empty | |
260 | ||
261 | qualityFlagBCID = kT0Error; | |
262 | AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 : %s has NO entries", hBCID->GetName() )); | |
263 | ||
264 | TPaveText text(0.20,0.50,0.99,0.99,"NDC"); | |
265 | text.AddText(Form("NO ENTRIES!!!")); | |
266 | text.AddText(Form("If T0 is READY report")); | |
267 | text.AddText(Form("readout problem to the T0 on-call expert")); | |
268 | hBCID->GetListOfFunctions()->Add((TPaveText*)text.Clone()); | |
269 | } | |
270 | ||
271 | //executive summary | |
272 | int lowestQualityFlag = (int) qualityFlagBCID; | |
273 | ||
274 | return ConvertQualityFlagToDouble(lowestQualityFlag); | |
be3ada9f | 275 | |
3685c21c | 276 | } |
5ed41460 | 277 | |
49e33ff1 | 278 | //-------------------------------------------------------------------------- |
279 | Double_t AliT0QAChecker::CheckRaw(TObjArray *listrec) const { | |
280 | ||
281 | ||
282 | Int_t qualityFlagTrigger = kT0Info; //init quality flag for a given histogram; | |
283 | ||
284 | TH1F *hTrigger = (TH1F*) listrec->UncheckedAt(169);//hRawTrigger | |
285 | ||
286 | ||
287 | // clean objects added at previous checks | |
288 | EraseOldMessages((TH1*) hTrigger); | |
289 | ||
290 | if(hTrigger->Integral()>0){ | |
291 | //trigger plot does have some counts in it | |
292 | //are Mean, ORA and ORC not empty? | |
293 | if( hTrigger->GetBinContent(1)<0.001 || hTrigger->GetBinContent(3)<0.001 || hTrigger->GetBinContent(4)<0.001){ | |
294 | qualityFlagTrigger = kT0Error; //no entries on diagonal | |
295 | AliDebug(AliQAv1::GetQADebugLevel(), Form("T0: too little ORA and ORC in %s", hTrigger->GetName() )); | |
296 | ||
297 | TPaveText text(0.20,0.50,0.99,0.99,"NDC"); | |
298 | text.AddText(Form("Check ORA and ORC")); | |
299 | text.AddText(Form("Report problem to the T0 on-call expert")); | |
300 | hTrigger->GetListOfFunctions()->Add((TPaveText*)text.Clone()); | |
301 | } | |
302 | }else{ //Trigger histo empty | |
303 | ||
304 | qualityFlagTrigger = kT0Error; | |
305 | AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hTrigger->GetName() )); | |
306 | ||
307 | TPaveText text(0.20,0.50,0.99,0.99,"NDC"); | |
308 | text.AddText(Form("NO ENTRIES!!!")); | |
309 | text.AddText(Form("If T0 is READY report")); | |
310 | text.AddText(Form("readout problem to the T0 on-call expert")); | |
311 | hTrigger->GetListOfFunctions()->Add((TPaveText*)text.Clone()); | |
312 | } | |
313 | ||
314 | //executive summary | |
315 | int lowestQualityFlag = (int) qualityFlagTrigger; | |
316 | ||
317 | ||
318 | return ConvertQualityFlagToDouble(lowestQualityFlag); | |
319 | ||
320 | } | |
be3ada9f | 321 | |
394c1a6d | 322 | //-------------------------------------------------------------------------- |
be3ada9f | 323 | Double_t AliT0QAChecker::CheckESD(TObjArray *listrec ) const |
394c1a6d | 324 | { |
394c1a6d | 325 | Float_t checkr = 0; |
be3ada9f | 326 | TH1 *fhESD; |
327 | ||
328 | fhESD = (TH1*) listrec->UncheckedAt(2); | |
329 | if(fhESD){ | |
330 | AliDebug(AliQAv1::GetQADebugLevel(), Form("count %s ", fhESD->GetName()) ); | |
331 | TF1 *f1 = new TF1("f1","gaus",-1,1); | |
332 | fhESD->Fit("f1","R","Q", -1,1); | |
333 | Double_t par[3]; | |
334 | f1->GetParameters(&par[0]); | |
335 | ||
105ff51c | 336 | TPaveText text(0.30,0.50,0.99,0.99,"NDC"); |
be3ada9f | 337 | |
105ff51c | 338 | text.AddText(Form("T0 RUN %d ",AliCDBManager::Instance()->GetRun())); |
be3ada9f | 339 | |
db33b25a | 340 | AliDebug(AliQAv1::GetQADebugLevel(), Form("numentries %d mean %f #sigma %f", (int)fhESD->GetEntries(),par[1], par[2])); |
be3ada9f | 341 | |
342 | ||
343 | if (par[2] > 0.07 && par[2] < 1.) { | |
344 | checkr=0.5; | |
105ff51c | 345 | text.AddText(Form("not good resolution :\n %f ns\n", par[2] )); |
346 | text.SetFillColor(5); | |
be3ada9f | 347 | printf("T0 detector resolution is not good enouph: %f ns\n",par[2] ); |
348 | } | |
349 | if(TMath::Abs(par[1])>0.05) { | |
350 | checkr = 0.5; | |
105ff51c | 351 | text.AddText(Form(" Check clock shift on %f ns", par[1])); |
352 | text.SetFillColor(5); | |
be3ada9f | 353 | } |
354 | if (par[2] > 1. || TMath::Abs(par[1])>0.1) { | |
355 | checkr = 0.25; | |
105ff51c | 356 | text.AddText(Form(" Bad resolution:\n mean %f ns sigma %f ns", par[1], par[2])); |
357 | text.SetFillColor(2); | |
358 | { // RS Clean previous additions | |
359 | TList* lstF = fhESD->GetListOfFunctions(); | |
360 | if (lstF) { | |
361 | TObject *stats = lstF->FindObject("stats"); | |
362 | lstF->Remove(stats); | |
363 | TObject *obj; | |
364 | while ((obj = lstF->First())) { | |
365 | while(lstF->Remove(obj)) { } | |
366 | delete obj; | |
367 | } | |
368 | if (stats) lstF->Add(stats); | |
369 | } | |
370 | } | |
371 | fhESD->GetListOfFunctions()->Add((TPaveText*)text.Clone()); | |
372 | AliDebug(AliQAv1::GetQADebugLevel(), | |
373 | Form("Please, check calibration: shift= %f resolution %f test=%f\n", | |
374 | par[1], par[2], checkr) ) ; | |
be3ada9f | 375 | } |
394c1a6d | 376 | } |
be3ada9f | 377 | else |
378 | { | |
379 | AliDebug(AliQAv1::GetQADebugLevel(), | |
380 | Form("No ESD QA histogram found, nothing to check")); | |
381 | checkr=0; | |
382 | } | |
383 | ||
332b9234 | 384 | |
394c1a6d | 385 | return checkr; |
386 | } | |
49e33ff1 | 387 | |
388 | ||
389 | //-------------------------------------------------------------------------- | |
390 | void AliT0QAChecker::EraseOldMessages(TH1* h) const | |
391 | { | |
392 | //erase the old captions | |
393 | TList* lstF = h->GetListOfFunctions(); | |
394 | if(lstF){ | |
395 | TObject *stats = lstF->FindObject("stats"); | |
396 | lstF->Remove(stats); | |
397 | TObject *obj; | |
398 | while ((obj = lstF->First())) { | |
399 | while(lstF->Remove(obj)) { } | |
400 | delete obj; | |
401 | } | |
402 | if (stats) lstF->Add(stats); | |
403 | } | |
404 | } | |
405 | //-------------------------------------------------------------------------- | |
406 | Double_t AliT0QAChecker::ConvertQualityFlagToDouble(int qualityFlag) const | |
407 | { | |
408 | //covert quality flag to double | |
409 | Double_t checkr=1.0; | |
410 | ||
411 | switch ( qualityFlag ){ | |
412 | case kT0Info: | |
413 | checkr = 1.0; break; | |
414 | case kT0Warning: | |
415 | checkr = 0.75; break; | |
416 | case kT0Error: | |
417 | checkr = 0.25; break; | |
418 | case kT0Fatal: | |
419 | checkr = -1.0; break; | |
420 | default: | |
421 | AliError("Invalid ecc value. FIXME !"); | |
422 | checkr = 0.25; break; | |
423 | }; | |
424 | ||
425 | return checkr; | |
426 | } |