Line data Source code
1 : /**************************************************************************
2 : * Coyright(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 : // Checks the quality assurance.
17 : // By comparing with reference data
18 : // Skeleton for T0
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
30 : //...
31 :
32 : // --- ROOT system ---
33 : #include <Riostream.h>
34 : #include <TClass.h>
35 : #include <TH1F.h>
36 : #include <TF1.h>
37 : #include <TFitResultPtr.h>
38 : #include <TH2.h>
39 : #include <TIterator.h>
40 : #include <TKey.h>
41 : #include <TFile.h>
42 : #include <TMath.h>
43 : #include <TString.h>
44 : #include <TPaveText.h>
45 : #include <TLegend.h>
46 :
47 : // --- Standard library ---
48 :
49 : // --- AliRoot header files ---
50 : #include "AliLog.h"
51 : #include "AliQAv1.h"
52 : #include "AliQAChecker.h"
53 : #include "AliCDBEntry.h"
54 : #include "AliQAManager.h"
55 : #include "AliT0QAChecker.h"
56 : #include "AliQAThresholds.h"
57 : #include "AliDAQ.h"
58 :
59 20 : ClassImp(AliT0QAChecker)
60 : //____________________________________________________________________________
61 : AliT0QAChecker::AliT0QAChecker() :
62 3 : AliQACheckerBase("T0","T0 Quality Assurance Checker"),
63 3 : fCFDErrorThreshold(0),
64 3 : fLEDErrorThreshold(0),
65 3 : fQTCErrorThreshold(0),
66 3 : fRatioCFDEffLEDEffErrorThreshold(1),
67 3 : fQTCEfficiencyErrorThreshold(0),
68 3 : fBCIDPeriodParam(3564),
69 3 : fBCIDOffsetParam(37),
70 3 : fBCIDBandWidthParam(10),
71 3 : fTZeroAPlusCErrorThreshold(2000.0),
72 3 : fTZeroAMinusCErrorThreshold(2000.0)
73 15 : {
74 : // Standard constructor
75 150 : for(Int_t i=0; i<24; i++){
76 72 : fMeanCFDFromGoodRunParam[i]=0;
77 72 : fMeanLEDFromGoodRunParam[i]=0;
78 72 : fMeanQTCFromGoodRunParam[i]=0;
79 : }
80 :
81 6 : }
82 :
83 : //____________________________________________________________________________
84 : AliT0QAChecker::AliT0QAChecker(const AliT0QAChecker& qac):
85 0 : AliQACheckerBase(qac.GetName(), qac.GetTitle()),
86 0 : fCFDErrorThreshold(qac.fCFDErrorThreshold),
87 0 : fLEDErrorThreshold(qac.fLEDErrorThreshold),
88 0 : fQTCErrorThreshold(qac.fQTCErrorThreshold),
89 0 : fRatioCFDEffLEDEffErrorThreshold(qac.fRatioCFDEffLEDEffErrorThreshold),
90 0 : fQTCEfficiencyErrorThreshold(qac.fQTCEfficiencyErrorThreshold),
91 0 : fBCIDPeriodParam(qac.fBCIDPeriodParam),
92 0 : fBCIDOffsetParam(qac.fBCIDOffsetParam),
93 0 : fBCIDBandWidthParam(qac.fBCIDBandWidthParam),
94 0 : fTZeroAPlusCErrorThreshold(qac.fTZeroAPlusCErrorThreshold),
95 0 : fTZeroAMinusCErrorThreshold(qac.fTZeroAMinusCErrorThreshold)
96 0 : {
97 : // copy constructor
98 0 : AliError("Copy should not be used with this class\n");
99 0 : for(Int_t i=0; i<24; i++){
100 0 : fMeanCFDFromGoodRunParam[i]=qac.fMeanCFDFromGoodRunParam[i];
101 0 : fMeanLEDFromGoodRunParam[i]=qac.fMeanLEDFromGoodRunParam[i];
102 0 : fMeanQTCFromGoodRunParam[i]=qac.fMeanQTCFromGoodRunParam[i];
103 : }
104 :
105 0 : }
106 : //____________________________________________________________________________
107 : AliT0QAChecker& AliT0QAChecker::operator=(const AliT0QAChecker& qac){
108 : // assignment operator
109 0 : this->~AliT0QAChecker();
110 0 : new(this)AliT0QAChecker(qac);
111 0 : return *this;
112 0 : }
113 :
114 :
115 : //____________________________________________________________________________
116 0 : AliT0QAChecker::~AliT0QAChecker(){
117 : // destructor
118 :
119 0 : }
120 :
121 : //__________________________________________________________________
122 : void AliT0QAChecker::Check(Double_t * test, AliQAv1::ALITASK_t index, TObjArray ** list, const AliDetectorRecoParam * /*recoParam*/)
123 : {
124 :
125 18 : AliCDBManager* man = AliCDBManager::Instance();
126 : //man->SetDefaultStorage(gSystem->Getenv("AMORE_CDB_URI"));
127 9 : if(!man) return;
128 18 : AliCDBEntry* entry = man->Get("GRP/Calib/QAThresholds");
129 9 : if(!entry) return;
130 9 : TObjArray* t0branch = (TObjArray*) entry->GetObject();
131 9 : if(!list) return;
132 9 : AliQAThresholds* thresholds = (AliQAThresholds*) t0branch->FindObject("T00");
133 : // here you should test that you got a non-null pointer
134 :
135 18 : if(!thresholds) return;
136 0 : if(AliDAQ::DetectorID("T0")!= thresholds->GetDetectorId()){
137 0 : AliInfo(Form("DETECTOR ID %d DOES NOT MATCH TO TZERO",thresholds->GetDetectorId()));
138 0 : return;
139 : }
140 :
141 : int iparam;
142 0 : for(int ipmt=0; ipmt<24;ipmt++){
143 0 : iparam = ipmt + 1; //current consecutive number of parameter
144 0 : if((TParameter<float>*) thresholds->GetThreshold(iparam)){ // mean CFD from a good run
145 0 : fMeanCFDFromGoodRunParam[ipmt] = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
146 0 : }
147 :
148 0 : iparam = ipmt + 25;
149 0 : if((TParameter<float>*) thresholds->GetThreshold(iparam)){ // mean LED from a good run
150 0 : fMeanLEDFromGoodRunParam[ipmt] = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
151 0 : }
152 0 : iparam = ipmt + 49;
153 0 : if((TParameter<float>*) thresholds->GetThreshold(iparam)){ // mean QTC from a good run
154 0 : fMeanQTCFromGoodRunParam[ipmt] = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
155 0 : }
156 : }
157 : iparam = 73; //CFD threshold
158 0 : if((TParameter<float>*) thresholds->GetThreshold(iparam)){
159 0 : fCFDErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
160 0 : }
161 : iparam = 74; //LED threshold
162 0 : if((TParameter<float>*) thresholds->GetThreshold(iparam)){
163 0 : fLEDErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
164 0 : }
165 : iparam = 75; //QTC threshold
166 0 : if((TParameter<float>*) thresholds->GetThreshold(iparam)){
167 0 : fQTCErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
168 0 : }
169 :
170 : iparam = 82; //Error level threshold on CFD efficiency/LED efficiency ratio
171 0 : if((TParameter<float>*) thresholds->GetThreshold(iparam)){
172 0 : fRatioCFDEffLEDEffErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
173 0 : }
174 : // Super-basic check on the QA histograms on the input list:
175 : // look whether they are empty!
176 :
177 : iparam = 83; //Error level threshold on QTC efficiency
178 0 : if((TParameter<float>*) thresholds->GetThreshold(iparam)){
179 0 : fQTCEfficiencyErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
180 0 : }
181 :
182 : iparam = 84;
183 0 : if((TParameter<int>*) thresholds->GetThreshold(iparam)){
184 0 : fBCIDPeriodParam = ((TParameter<int>*) thresholds->GetThreshold(iparam))->GetVal();
185 0 : }
186 :
187 : iparam = 85;
188 0 : if((TParameter<int>*) thresholds->GetThreshold(iparam)){
189 0 : fBCIDOffsetParam = ((TParameter<int>*) thresholds->GetThreshold(iparam))->GetVal();
190 0 : }
191 :
192 : iparam = 86;
193 0 : if((TParameter<int>*) thresholds->GetThreshold(iparam)){
194 0 : fBCIDBandWidthParam = ((TParameter<int>*) thresholds->GetThreshold(iparam))->GetVal();
195 0 : }
196 :
197 : iparam = 87;
198 0 : if((TParameter<float>*) thresholds->GetThreshold(iparam)){
199 0 : fTZeroAPlusCErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
200 0 : }
201 :
202 : iparam = 88;
203 0 : if((TParameter<float>*) thresholds->GetThreshold(iparam)){
204 0 : fTZeroAMinusCErrorThreshold = ((TParameter<float>*) thresholds->GetThreshold(iparam))->GetVal();
205 0 : }
206 :
207 :
208 0 : char * detOCDBDir = Form("T0/%s/%s", AliQAv1::GetRefOCDBDirName(), AliQAv1::GetRefDataDirName()) ;
209 :
210 0 : AliCDBEntry *QARefRec = AliQAManager::QAManager()->Get(detOCDBDir);
211 : // QARefRec->Dump();
212 0 : if( !QARefRec){
213 0 : AliInfo("QA reference data NOT retrieved for Reconstruction check. No T0 reference distribution");
214 0 : }
215 :
216 :
217 0 : for(Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++){
218 0 : test[specie] = 1.0; //FK// initiate qa flag for the whole set of histograms as good
219 : }
220 :
221 :
222 0 : for(Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
223 0 : if(!(AliQAv1::Instance()->IsEventSpecieSet(specie) && list[specie]) || list[specie]->GetEntries() == 0) {
224 : continue;
225 : }
226 :
227 0 : if(index == AliQAv1::kRAW){
228 :
229 : //if(AliRecoParam::ConvertIndex(specie) == AliRecoParam::kCalib){// if (index == AliQAv1::kRAW )
230 : //check laser data efficiencies
231 : // Double_t qaFlag = CheckLaser(list[specie]);
232 : // if(qaFlag < test[specie]) test[specie] = qaFlag;
233 : //}
234 :
235 : //if(//AliRecoParam::ConvertIndex(specie) == AliRecoParam::kCalib ||
236 : // AliRecoParam::ConvertIndex(specie) == AliRecoParam::kHighMult ||
237 : // AliRecoParam::ConvertIndex(specie) == AliRecoParam::kLowMult){
238 : //AliRecoParam::ConvertIndex(specie) == AliRecoParam::kDefault ||
239 :
240 : //check BCID
241 : // Double_t qaFlag = CheckBCID(list[specie]);
242 : // if(qaFlag < test[specie]) test[specie] = qaFlag;
243 : //}
244 :
245 0 : if(AliRecoParam::ConvertIndex(specie) == AliRecoParam::kHighMult ||
246 0 : AliRecoParam::ConvertIndex(specie) == AliRecoParam::kLowMult){
247 : //AliRecoParam::ConvertIndex(specie) == AliRecoParam::kDefault ||
248 : //check physics
249 0 : Double_t qaFlag = CheckRaw(list[specie]);
250 0 : if(qaFlag < test[specie]) test[specie] = qaFlag;
251 0 : }
252 : }
253 :
254 0 : if(index == AliQAv1::kESD && AliRecoParam::Convert(specie) != AliRecoParam::kCalib){
255 0 : test[specie] = CheckESD(list[specie]);
256 0 : }
257 : }
258 9 : }
259 :
260 : //--------------------------------------------------------------------------
261 : //Double_t AliT0QAChecker::CheckLaser(TObjArray *listrec) const {
262 : //
263 : // return 1.0;
264 : //}
265 :
266 : //--------------------------------------------------------------------------
267 : Double_t AliT0QAChecker::CheckRaw(TObjArray *listrec) const {
268 :
269 : //Fk Set drawing options for LED and CFD efficiencies from the raw data
270 0 : TH1F *hCFDEffData = (TH1F*) listrec->UncheckedAt(207);//hRawTrigger
271 0 : TH1F *hLEDEffData = (TH1F*) listrec->UncheckedAt(208);//hRawTrigger
272 :
273 : //clean objects added at previous checks
274 0 : EraseOldMessages((TH1*) hCFDEffData);
275 0 : hCFDEffData->GetListOfFunctions()->Add((TH1D*) hLEDEffData->Clone());
276 :
277 0 : TLegend leg(0.12,0.76,0.9,0.92," ","brNDC");
278 0 : leg.SetFillStyle(0); leg.SetBorderSize(0); leg.SetTextSize(0.04); leg.SetNColumns(2);
279 0 : leg.AddEntry((TH1D*) hCFDEffData,"CFD","p");
280 0 : leg.AddEntry((TH1D*) hLEDEffData,"LED","p");
281 0 : hCFDEffData->GetListOfFunctions()->Add((TLegend*) leg.Clone());
282 :
283 :
284 : //Fk Draw CFD-mean for each PMT
285 0 : TH2F* fhCFD = (TH2F*) listrec->UncheckedAt(210);
286 0 : TH1F* fhCFDSubtrMean = (TH1F*) listrec->UncheckedAt(231);
287 :
288 0 : EraseOldMessages((TH1*) fhCFDSubtrMean);
289 0 : for(int ipmt=0; ipmt<24;ipmt++){
290 0 : TH1F* hProjDummy = (TH1F*) fhCFD->ProjectionY("dummy",ipmt+1,ipmt+1);
291 0 : Float_t mean=0.0, rms=0.0;
292 0 : GetMeanAndRmsAroundMainMaximum(mean, rms, hProjDummy,0);
293 :
294 0 : Float_t deviation = mean - fMeanCFDFromGoodRunParam[ipmt];
295 :
296 0 : fhCFDSubtrMean->SetBinContent(ipmt+1,deviation);
297 0 : fhCFDSubtrMean->SetBinError(ipmt+1,rms);
298 :
299 0 : delete hProjDummy;
300 0 : }
301 0 : TLine linelowredCFD(0, fCFDErrorThreshold, 24, fCFDErrorThreshold);
302 0 : linelowredCFD.SetLineColor(2);
303 0 : linelowredCFD.SetLineStyle(3);
304 0 : linelowredCFD.SetLineWidth(4);
305 0 : TLine linehighredCFD(0, -fCFDErrorThreshold, 24, -fCFDErrorThreshold);
306 0 : linehighredCFD.SetLineColor(2);
307 0 : linehighredCFD.SetLineStyle(3);
308 0 : linehighredCFD.SetLineWidth(4);
309 0 : fhCFDSubtrMean->GetListOfFunctions()->Add((TLine*) linelowredCFD.Clone());
310 0 : fhCFDSubtrMean->GetListOfFunctions()->Add((TLine*) linehighredCFD.Clone());
311 :
312 :
313 :
314 : //Fk Draw LED-mean for each PMT
315 0 : TH2F* fhLED = (TH2F*) listrec->UncheckedAt(211);
316 0 : TH1F* fhLEDSubtrMean = (TH1F*) listrec->UncheckedAt(232);
317 :
318 0 : EraseOldMessages((TH1*) fhLEDSubtrMean);
319 0 : for(int ipmt=0; ipmt<24;ipmt++){
320 0 : TH1F* hProjDummy = (TH1F*) fhLED->ProjectionY("dummy",ipmt+1,ipmt+1);
321 0 : Float_t mean=0.0, rms=0.0;
322 0 : GetMeanAndRmsAroundMainMaximum(mean, rms, hProjDummy,1);
323 0 : Float_t deviation = mean - fMeanLEDFromGoodRunParam[ipmt];
324 :
325 0 : fhLEDSubtrMean->SetBinContent(ipmt+1,deviation);
326 0 : fhLEDSubtrMean->SetBinError(ipmt+1,rms);
327 :
328 0 : delete hProjDummy;
329 0 : }
330 0 : TLine linelowredLED(0, fLEDErrorThreshold, 24, fLEDErrorThreshold);
331 0 : linelowredLED.SetLineColor(2);
332 0 : linelowredLED.SetLineStyle(3);
333 0 : linelowredLED.SetLineWidth(4);
334 0 : TLine linehighredLED(0, -fLEDErrorThreshold, 24, -fLEDErrorThreshold);
335 0 : linehighredLED.SetLineColor(2);
336 0 : linehighredLED.SetLineStyle(3);
337 0 : linehighredLED.SetLineWidth(4);
338 0 : fhLEDSubtrMean->GetListOfFunctions()->Add((TLine*) linelowredLED.Clone());
339 0 : fhLEDSubtrMean->GetListOfFunctions()->Add((TLine*) linehighredLED.Clone());
340 :
341 :
342 : //Fk Draw QTC-mean for each PMT
343 0 : TH2F* fhQTC = (TH2F*) listrec->UncheckedAt(212);
344 0 : TH1F* fhQTCSubtrMean = (TH1F*) listrec->UncheckedAt(233);
345 :
346 0 : EraseOldMessages((TH1*) fhQTCSubtrMean);
347 0 : for(int ipmt=0; ipmt<24;ipmt++){
348 0 : TH1F* hProjDummy = (TH1F*) fhQTC->ProjectionY("dummy",ipmt+1,ipmt+1);
349 0 : Float_t mean=0.0, rms=0.0;
350 0 : GetMeanAndRmsAroundMainMaximum(mean, rms, hProjDummy,2);
351 0 : Float_t deviation = mean - fMeanQTCFromGoodRunParam[ipmt];
352 :
353 0 : fhQTCSubtrMean->SetBinContent(ipmt+1,deviation);
354 0 : fhQTCSubtrMean->SetBinError(ipmt+1,rms);
355 :
356 0 : delete hProjDummy;
357 0 : }
358 0 : TLine linelowredQTC(0, fQTCErrorThreshold, 24, fQTCErrorThreshold);
359 0 : linelowredQTC.SetLineColor(2);
360 0 : linelowredQTC.SetLineStyle(3);
361 0 : linelowredQTC.SetLineWidth(4);
362 0 : TLine linehighredQTC(0, -fQTCErrorThreshold, 24, -fQTCErrorThreshold);
363 0 : linehighredQTC.SetLineColor(2);
364 0 : linehighredQTC.SetLineStyle(3);
365 0 : linehighredQTC.SetLineWidth(4);
366 0 : fhQTCSubtrMean->GetListOfFunctions()->Add((TLine*) linelowredQTC.Clone());
367 0 : fhQTCSubtrMean->GetListOfFunctions()->Add((TLine*) linehighredQTC.Clone());
368 :
369 : //CFD and LED efficiency in range ~2000- ~3000
370 0 : TH1F* hCFDeffSubRange = (TH1F*) listrec->UncheckedAt(237);
371 0 : TH1F* hEffLEDSubRange = (TH1F*) listrec->UncheckedAt(238);
372 : // ratio CDF eff /LEF eff in subragne
373 0 : TH1F* hRatioCFDLEDeff = (TH1F*) listrec->UncheckedAt(239);//FK
374 0 : EraseOldMessages((TH1*) hRatioCFDLEDeff);
375 0 : int npmt = hRatioCFDLEDeff->GetNbinsX();
376 0 : for(int ipmt=1;ipmt<=npmt;ipmt++){
377 0 : Float_t c0 = hCFDeffSubRange->GetBinContent(ipmt);
378 0 : Float_t c1 = hEffLEDSubRange->GetBinContent(ipmt);
379 0 : if(c1){
380 0 : hRatioCFDLEDeff->SetBinContent(ipmt,c0/c1);
381 : }else{
382 0 : hRatioCFDLEDeff->SetBinContent(ipmt,0);
383 : }
384 : }
385 :
386 0 : TLine linelowredRatioCFDLEDeff(0, 1+fRatioCFDEffLEDEffErrorThreshold, 24, 1+fRatioCFDEffLEDEffErrorThreshold);
387 0 : linelowredRatioCFDLEDeff.SetLineColor(2);
388 0 : linelowredRatioCFDLEDeff.SetLineStyle(3);
389 0 : linelowredRatioCFDLEDeff.SetLineWidth(4);
390 0 : TLine linehighredRatioCFDLEDeff(0, 1-fRatioCFDEffLEDEffErrorThreshold, 24, 1-fRatioCFDEffLEDEffErrorThreshold);
391 0 : linehighredRatioCFDLEDeff.SetLineColor(2);
392 0 : linehighredRatioCFDLEDeff.SetLineStyle(3);
393 0 : linehighredRatioCFDLEDeff.SetLineWidth(4);
394 0 : hRatioCFDLEDeff->GetListOfFunctions()->Add((TLine*) linelowredRatioCFDLEDeff.Clone());
395 0 : hRatioCFDLEDeff->GetListOfFunctions()->Add((TLine*) linehighredRatioCFDLEDeff.Clone());
396 :
397 : // PERFROM CHECKS on HISTOGRAMS
398 :
399 : //-------- triggers -----------
400 : Int_t qualityFlagTrigger = kT0Info; //init quality flag for a given histogram;
401 :
402 0 : TH1F *hTrigger = (TH1F*) listrec->UncheckedAt(169);//hRawTrigger
403 :
404 : // clean objects added at previous checks
405 0 : EraseOldMessages((TH1*) hTrigger);
406 :
407 0 : if(hTrigger->Integral()>0){
408 : //trigger plot does have some counts in it
409 : //are Mean, ORA and ORC not empty?
410 0 : if(/* hTrigger->GetBinContent(1)<0.001 ||*/ hTrigger->GetBinContent(3)<0.001 || hTrigger->GetBinContent(4)<0.001){
411 : qualityFlagTrigger = kT0Error; //no entries on diagonal
412 0 : AliDebug(AliQAv1::GetQADebugLevel(), Form("T0: too little ORA and ORC in %s", hTrigger->GetName() ));
413 :
414 0 : TPaveText text(0.20,0.50,0.99,0.99,"NDC");
415 0 : text.AddText(Form("Check ORA and ORC"));
416 0 : text.AddText(Form("Report problem to the T0 on-call expert"));
417 0 : text.SetBorderSize(0);
418 0 : text.SetFillStyle(0);
419 0 : hTrigger->GetListOfFunctions()->Add((TPaveText*)text.Clone());
420 0 : }
421 :
422 : }else{ //Trigger histo empty
423 :
424 : qualityFlagTrigger = kT0Error;
425 0 : AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hTrigger->GetName() ));
426 :
427 0 : TPaveText text(0.20,0.50,0.99,0.99,"NDC");
428 0 : text.AddText(Form("NO ENTRIES!!!"));
429 0 : text.AddText(Form("If T0 is READY report"));
430 0 : text.AddText(Form("readout problem to the T0 on-call expert"));
431 0 : text.SetBorderSize(0);
432 0 : text.SetFillStyle(0);
433 0 : hTrigger->GetListOfFunctions()->Add((TPaveText*)text.Clone());
434 :
435 0 : }
436 : //---------- CFD eff/LED eff within subrange -----------
437 : Int_t qualityFlagRatioCFDeffLEDeff = kT0Info; //init quality flag for a given histogram;
438 0 : int nPMTs = hRatioCFDLEDeff->GetNbinsX();
439 :
440 0 : for(int ipmt=1; ipmt<=nPMTs; ipmt++){
441 0 : if(TMath::Abs( hRatioCFDLEDeff->GetBinContent(ipmt) -1) > fRatioCFDEffLEDEffErrorThreshold){ //mean is expected to be around 1
442 : qualityFlagRatioCFDeffLEDeff = kT0Error;
443 0 : }
444 : }
445 0 : if(qualityFlagRatioCFDeffLEDeff == kT0Error){
446 0 : TPaveText text(0.20,0.50,0.99,0.99,"NDC");
447 0 : text.AddText(Form("Problem with efficiency ratio CFD/LED !!!"));
448 0 : text.AddText(Form("If T0 is READY and beam is on report"));
449 0 : text.AddText(Form("the problem to the T0 on-call expert"));
450 0 : text.SetBorderSize(0);
451 0 : text.SetFillStyle(0);
452 0 : hRatioCFDLEDeff->GetListOfFunctions()->Add((TPaveText*)text.Clone());
453 0 : }
454 :
455 :
456 : //---------- CFD - mean CFD -----------
457 : Int_t qualityFlagCFDSubtr = kT0Info; //init quality flag for a given histogram;
458 0 : nPMTs = fhCFDSubtrMean->GetNbinsX();
459 :
460 0 : for(int ipmt=1; ipmt<=nPMTs; ipmt++){
461 0 : if(TMath::Abs( fhCFDSubtrMean->GetBinContent(ipmt)) > fCFDErrorThreshold){
462 : qualityFlagCFDSubtr = kT0Error;
463 :
464 0 : }
465 : }
466 0 : if(qualityFlagCFDSubtr == kT0Error){
467 0 : TPaveText text(0.20,0.50,0.99,0.99,"NDC");
468 0 : text.AddText(Form("Problem with CFD timing !!!"));
469 0 : text.AddText(Form("If T0 is READY and beam is on report"));
470 0 : text.AddText(Form("the problem to the T0 on-call expert"));
471 0 : text.SetBorderSize(0);
472 0 : text.SetFillStyle(0);
473 0 : fhCFDSubtrMean->GetListOfFunctions()->Add((TPaveText*)text.Clone());
474 0 : }
475 : //--------- QTC efficiency ---------------
476 :
477 : Int_t qualityFlagEffQTC = kT0Info; //init quality flag for a given histogram;
478 0 : TH1F *hEffQTC = (TH1F*) listrec->UncheckedAt(209);//hRawTrigger
479 :
480 0 : EraseOldMessages((TH1*) hEffQTC); // clean objects added at previous checks
481 :
482 0 : nPMTs = hEffQTC->GetNbinsX();
483 0 : for(int ipmt=1; ipmt<=nPMTs; ipmt++){
484 0 : if(TMath::Abs( hEffQTC->GetBinContent(ipmt)) < fQTCEfficiencyErrorThreshold){
485 : qualityFlagEffQTC = kT0Error;
486 0 : }
487 : }
488 0 : if( qualityFlagEffQTC == kT0Error){
489 0 : TPaveText text(0.20,0.50,0.99,0.99,"NDC");
490 0 : text.AddText(Form("Problem with QTC efficiency !!!"));
491 0 : text.AddText(Form("If T0 is READY and beam is on report"));
492 0 : text.AddText(Form("the problem to the T0 on-call expert"));
493 0 : text.SetBorderSize(0);
494 0 : text.SetFillStyle(0);
495 0 : hEffQTC->GetListOfFunctions()->Add((TPaveText*)text.Clone());
496 0 : }
497 0 : TLine linehighredQTCeff(0, fQTCEfficiencyErrorThreshold, 24, fQTCEfficiencyErrorThreshold);
498 0 : linehighredQTCeff.SetLineColor(2);
499 0 : linehighredQTCeff.SetLineStyle(3);
500 0 : linehighredQTCeff.SetLineWidth(4);
501 0 : hEffQTC->GetListOfFunctions()->Add((TLine*) linehighredQTCeff.Clone());
502 :
503 : //---------- BCID --------------------
504 : Int_t qualityFlagBCID = kT0Info; //init quality flag for a given histogram;
505 0 : TH2F *hBCID = (TH2F*) listrec->UncheckedAt(236); //BCID versus TRM BCID
506 :
507 : // clean objects added at previous checks
508 0 : EraseOldMessages((TH1*)hBCID);
509 :
510 0 : if(hBCID->Integral()>0){
511 : //BCID does have some counts in it
512 :
513 0 : Int_t nbinsX = hBCID->GetNbinsX();
514 0 : Int_t startX = hBCID->GetXaxis()->FindBin(100); //skip region close to orbit period
515 0 : Int_t nbinsY = hBCID->GetNbinsY();
516 0 : Int_t binWidthX = (Int_t) hBCID->GetXaxis()->GetBinWidth(1);
517 0 : Int_t binWidthY = (Int_t) hBCID->GetYaxis()->GetBinWidth(1);
518 : double entriesOnDiagonal = 0; //count diagonal and off diagonal entries
519 : double entriesOffDiagonal = 0;
520 :
521 0 : for(Int_t itrm=startX; itrm<=nbinsX; itrm++){ //BCID TRM
522 0 : for(Int_t ibcid=1; ibcid<=nbinsY; ibcid++){ //BCID
523 0 : if(TMath::Abs( (itrm*binWidthX - fBCIDOffsetParam) % fBCIDPeriodParam - binWidthY*ibcid) < fBCIDBandWidthParam ){
524 0 : entriesOnDiagonal += hBCID->GetBinContent(itrm,ibcid); //On Diagonal
525 : //hBCID->Fill(itrm*binWidthX,ibcid*binWidthY,0.001); // visualize the diagonal belt
526 0 : }else{
527 0 : entriesOffDiagonal += hBCID->GetBinContent(itrm,ibcid); //Off Diagonal
528 : }
529 : }
530 : }
531 0 : if(entriesOnDiagonal<1 || entriesOffDiagonal>20){
532 : qualityFlagBCID = kT0Error; //no entries on diagonal
533 0 : AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 %s is not diagonal", hBCID->GetName() ));
534 :
535 0 : TPaveText text(0.20,0.50,0.99,0.99,"NDC");
536 0 : text.AddText(Form("Check if entries are on diagonal"));
537 0 : text.AddText(Form("If NOT - report readout problem to the T0 on-call expert"));
538 0 : text.SetBorderSize(0);
539 0 : text.SetFillStyle(0);
540 0 : hBCID->GetListOfFunctions()->Add((TPaveText*)text.Clone());
541 0 : }
542 0 : }else{ //BCID empty
543 :
544 : qualityFlagBCID = kT0Error;
545 0 : AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 : %s has NO entries", hBCID->GetName() ));
546 :
547 0 : TPaveText text(0.20,0.50,0.99,0.99,"NDC");
548 0 : text.AddText(Form("NO ENTRIES!!!"));
549 0 : text.AddText(Form("If T0 is READY report"));
550 0 : text.AddText(Form("readout problem to the T0 on-call expert"));
551 0 : text.SetBorderSize(0);
552 0 : text.SetFillStyle(0);
553 0 : hBCID->GetListOfFunctions()->Add((TPaveText*)text.Clone());
554 0 : }
555 :
556 : //--------- mean versus vertex 1st ---------
557 : Int_t qualityFlagMeanVersusVertex1st = kT0Info; //init quality flag for a given histogram;
558 0 : TH2F *hMeanVersusVertex1st = (TH2F*) listrec->UncheckedAt(220); //fhMeanBest time
559 0 : EraseOldMessages((TH1*) hMeanVersusVertex1st);
560 :
561 0 : if(hMeanVersusVertex1st->Integral()<1){
562 : qualityFlagMeanVersusVertex1st = kT0Error;
563 0 : AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hMeanVersusVertex1st->GetName() ));
564 :
565 0 : TPaveText text(0.20,0.50,0.99,0.99,"NDC");
566 0 : text.AddText(Form("NO ENTRIES!!!"));
567 0 : text.AddText(Form("If T0 is READY and beam is on report"));
568 0 : text.AddText(Form("the problem to the T0 on-call expert"));
569 0 : text.SetBorderSize(0);
570 0 : text.SetFillStyle(0);
571 0 : hMeanVersusVertex1st->GetListOfFunctions()->Add((TPaveText*)text.Clone());
572 0 : }
573 :
574 :
575 : //--------- vertex TVDC on ---------
576 : Int_t qualityFlagVertex1stTVDCon = kT0Info; //init quality flag for a given histogram;
577 0 : TH1F *hVertex1stTVDCon = (TH1F*) listrec->UncheckedAt(223); //fhMeanBest time
578 0 : EraseOldMessages((TH1*) hVertex1stTVDCon);
579 :
580 0 : if(hVertex1stTVDCon->Integral()<1){
581 : qualityFlagVertex1stTVDCon = kT0Error;
582 0 : AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hVertex1stTVDCon->GetName() ));
583 :
584 0 : TPaveText text(0.20,0.50,0.99,0.99,"NDC");
585 0 : text.AddText(Form("NO ENTRIES!!!"));
586 0 : text.AddText(Form("If T0 is READY and beam is on report"));
587 0 : text.AddText(Form("the problem to the T0 on-call expert"));
588 0 : text.SetBorderSize(0);
589 0 : text.SetFillStyle(0);
590 0 : hVertex1stTVDCon->GetListOfFunctions()->Add((TPaveText*)text.Clone());
591 0 : }else{
592 0 : if(TMath::Abs(hVertex1stTVDCon->GetMean()) > fTZeroAMinusCErrorThreshold){
593 : qualityFlagVertex1stTVDCon = kT0Error;
594 :
595 0 : TPaveText text(0.20,0.50,0.99,0.99,"NDC");
596 0 : text.AddText(Form("Displaced vertex"));
597 0 : text.AddText(Form("If T0 is READY and beam is on report"));
598 0 : text.AddText(Form("the problem to the T0 on-call expert"));
599 0 : text.SetBorderSize(0);
600 0 : text.SetFillStyle(0);
601 0 : hVertex1stTVDCon->GetListOfFunctions()->Add((TPaveText*)text.Clone());
602 0 : }
603 : }
604 :
605 : //--------- vertex TVDC off ---------
606 : Int_t qualityFlagVertex1stTVDCoff = kT0Info; //init quality flag for a given histogram;
607 0 : TH1F *hVertex1stTVDCoff = (TH1F*) listrec->UncheckedAt(225); //fhMeanBest time
608 0 : EraseOldMessages((TH1*) hVertex1stTVDCoff);
609 :
610 0 : if(hVertex1stTVDCoff->Integral()<1){
611 : qualityFlagVertex1stTVDCoff = kT0Warning;
612 0 : AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hVertex1stTVDCoff->GetName() ));
613 :
614 0 : TPaveText text(0.20,0.50,0.99,0.99,"NDC");
615 0 : text.AddText(Form("Warning: NO ENTRIES"));
616 0 : text.SetBorderSize(0);
617 0 : text.SetFillStyle(0);
618 0 : hVertex1stTVDCoff->GetListOfFunctions()->Add((TPaveText*)text.Clone());
619 0 : }
620 :
621 :
622 :
623 : //----------- time TVDC on ---------
624 :
625 : Int_t qualityFlagMean1stTVDCon = kT0Info; //init quality flag for a given histogram;
626 0 : TH1F *hMean1stTVDCon = (TH1F*) listrec->UncheckedAt(226); //fhMeanBest time
627 0 : EraseOldMessages((TH1*) hMean1stTVDCon);
628 :
629 0 : if(hMean1stTVDCon->Integral()<1){
630 : qualityFlagMean1stTVDCon = kT0Error;
631 0 : AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hMean1stTVDCon->GetName() ));
632 :
633 0 : TPaveText text(0.20,0.50,0.99,0.99,"NDC");
634 0 : text.AddText(Form("NO ENTRIES!!!"));
635 0 : text.AddText(Form("If T0 is READY and beam is on report"));
636 0 : text.AddText(Form("the problem to the T0 on-call expert"));
637 0 : text.SetBorderSize(0);
638 0 : text.SetFillStyle(0);
639 0 : hMean1stTVDCon->GetListOfFunctions()->Add((TPaveText*)text.Clone());
640 0 : }else{
641 : //cout<<"Mean: "<<TMath::Abs(hMean1stTVDCon->GetMean())<<" threshold "<<fTZeroAPlusCErrorThreshold<<endl;
642 0 : if(TMath::Abs(hMean1stTVDCon->GetMean()) > fTZeroAPlusCErrorThreshold){
643 : qualityFlagMean1stTVDCon = kT0Error;
644 :
645 0 : TPaveText text(0.20,0.50,0.99,0.99,"NDC");
646 0 : text.AddText(Form("Shift of mean time"));
647 0 : text.AddText(Form("If T0 is READY and beam is on report"));
648 0 : text.AddText(Form("the problem to the T0 on-call expert"));
649 0 : text.SetBorderSize(0);
650 0 : text.SetFillStyle(0);
651 0 : hMean1stTVDCon->GetListOfFunctions()->Add((TPaveText*)text.Clone());
652 0 : }
653 : }
654 :
655 : //----------- time TVDC off ---------
656 :
657 : Int_t qualityFlagMean1stTVDCoff = kT0Info; //init quality flag for a given histogram;
658 0 : TH1F *hMean1stTVDCoff = (TH1F*) listrec->UncheckedAt(227); //fhMeanBest time
659 0 : EraseOldMessages((TH1*) hMean1stTVDCoff);
660 :
661 0 : if(hMean1stTVDCoff->Integral()<1){
662 : qualityFlagMean1stTVDCoff = kT0Warning;
663 0 : AliDebug(AliQAv1::GetQADebugLevel(), Form("T0 histogram %s has NO entries", hMean1stTVDCoff->GetName() ));
664 :
665 0 : TPaveText text(0.20,0.50,0.99,0.99,"NDC");
666 0 : text.AddText(Form("Warning: NO ENTRIES"));
667 0 : text.SetBorderSize(0);
668 0 : text.SetFillStyle(0);
669 0 : hMean1stTVDCoff->GetListOfFunctions()->Add((TPaveText*)text.Clone());
670 0 : }
671 :
672 :
673 :
674 : //----------------------- executive summary ---------------------
675 : int lowestQualityFlag = (int) qualityFlagTrigger;
676 0 : if(qualityFlagRatioCFDeffLEDeff < lowestQualityFlag) lowestQualityFlag = qualityFlagRatioCFDeffLEDeff;
677 0 : if(qualityFlagCFDSubtr < lowestQualityFlag) lowestQualityFlag = qualityFlagCFDSubtr;
678 0 : if(qualityFlagEffQTC < lowestQualityFlag) lowestQualityFlag = qualityFlagEffQTC;
679 0 : if(qualityFlagMeanVersusVertex1st < lowestQualityFlag) lowestQualityFlag = qualityFlagMeanVersusVertex1st;
680 0 : if(qualityFlagBCID < lowestQualityFlag) lowestQualityFlag = qualityFlagBCID;
681 0 : if(qualityFlagVertex1stTVDCon < lowestQualityFlag) lowestQualityFlag = qualityFlagVertex1stTVDCon;
682 0 : if(qualityFlagVertex1stTVDCoff < lowestQualityFlag) lowestQualityFlag = qualityFlagVertex1stTVDCoff;
683 0 : if(qualityFlagMean1stTVDCon < lowestQualityFlag) lowestQualityFlag = qualityFlagMean1stTVDCon;
684 0 : if(qualityFlagMean1stTVDCoff < lowestQualityFlag) lowestQualityFlag = qualityFlagMean1stTVDCoff;
685 :
686 :
687 0 : return ConvertQualityFlagToDouble(lowestQualityFlag);
688 :
689 0 : }
690 :
691 : //--------------------------------------------------------------------------
692 : Double_t AliT0QAChecker::CheckESD(TObjArray *listrec ) const
693 : {
694 : Float_t checkr = 0;
695 : TH1 *fhESD;
696 :
697 0 : fhESD = (TH1*) listrec->UncheckedAt(2);
698 0 : if(fhESD){
699 0 : AliDebug(AliQAv1::GetQADebugLevel(), Form("count %s ", fhESD->GetName()) );
700 0 : TF1 *f1 = new TF1("f1","gaus",-1,1);
701 0 : fhESD->Fit("f1","R","Q", -1,1);
702 0 : Double_t par[3];
703 0 : f1->GetParameters(&par[0]);
704 :
705 0 : TPaveText text(0.30,0.50,0.99,0.99,"NDC");
706 :
707 0 : text.AddText(Form("T0 RUN %d ",AliCDBManager::Instance()->GetRun()));
708 :
709 0 : AliDebug(AliQAv1::GetQADebugLevel(), Form("numentries %d mean %f #sigma %f", (int)fhESD->GetEntries(),par[1], par[2]));
710 :
711 :
712 0 : if (par[2] > 0.07 && par[2] < 1.) {
713 : checkr=0.5;
714 0 : text.AddText(Form("not good resolution :\n %f ns\n", par[2] ));
715 0 : text.SetFillColor(5);
716 0 : printf("T0 detector resolution is not good enouph: %f ns\n",par[2] );
717 : }
718 0 : if(TMath::Abs(par[1])>0.05) {
719 : checkr = 0.5;
720 0 : text.AddText(Form(" Check clock shift on %f ns", par[1]));
721 0 : text.SetFillColor(5);
722 : }
723 0 : if (par[2] > 1. || TMath::Abs(par[1])>0.1) {
724 : checkr = 0.25;
725 0 : text.AddText(Form(" Bad resolution:\n mean %f ns sigma %f ns", par[1], par[2]));
726 0 : text.SetFillColor(2);
727 : { // RS Clean previous additions
728 0 : TList* lstF = fhESD->GetListOfFunctions();
729 0 : if (lstF) {
730 0 : TObject *stats = lstF->FindObject("stats");
731 0 : lstF->Remove(stats);
732 : TObject *obj;
733 0 : while ((obj = lstF->First())) {
734 0 : while(lstF->Remove(obj)) { }
735 0 : delete obj;
736 : }
737 0 : if (stats) lstF->Add(stats);
738 0 : }
739 : }
740 0 : fhESD->GetListOfFunctions()->Add((TPaveText*)text.Clone());
741 0 : AliDebug(AliQAv1::GetQADebugLevel(),
742 : Form("Please, check calibration: shift= %f resolution %f test=%f\n",
743 : par[1], par[2], checkr) ) ;
744 : }
745 0 : }
746 : else
747 : {
748 0 : AliDebug(AliQAv1::GetQADebugLevel(),
749 : Form("No ESD QA histogram found, nothing to check"));
750 : checkr=0;
751 : }
752 :
753 :
754 0 : return checkr;
755 0 : }
756 :
757 :
758 : //--------------------------------------------------------------------------
759 : void AliT0QAChecker::EraseOldMessages(TH1* h) const
760 : {
761 : //erase the old captions
762 0 : TList* lstF = h->GetListOfFunctions();
763 0 : if(lstF){
764 0 : TObject *stats = lstF->FindObject("stats");
765 0 : lstF->Remove(stats);
766 : TObject *obj;
767 0 : while ((obj = lstF->First())) {
768 0 : while(lstF->Remove(obj)) { }
769 0 : delete obj;
770 : }
771 0 : if (stats) lstF->Add(stats);
772 0 : }
773 0 : }
774 : //--------------------------------------------------------------------------
775 : Double_t AliT0QAChecker::ConvertQualityFlagToDouble(int qualityFlag) const
776 : {
777 : //covert quality flag to double
778 : Double_t checkr=1.0;
779 :
780 0 : switch ( qualityFlag ){
781 : case kT0Info:
782 0 : checkr = 1.0; break;
783 : case kT0Warning:
784 0 : checkr = 0.75; break;
785 : case kT0Error:
786 0 : checkr = 0.25; break;
787 : case kT0Fatal:
788 0 : checkr = -1.0; break;
789 : default:
790 0 : AliError("Invalid ecc value. FIXME !");
791 0 : checkr = 0.25; break;
792 : };
793 :
794 0 : return checkr;
795 : }
796 :
797 : //--------------------------------------------------------------------------
798 : Float_t AliT0QAChecker::GetMeanAboveThreshold(TH1F* hV, Float_t thr) const{
799 : //caculate mean value of histo bins above threshold
800 0 : Int_t nBins = hV->GetNbinsX();
801 : Int_t nBinsAboveThr = 0;
802 : Float_t sum = 0;
803 :
804 0 : for(Int_t ib=1;ib<=nBins;ib++){
805 0 : Float_t val = hV->GetBinContent(ib);
806 0 : if(val<thr){
807 0 : sum+=val;
808 0 : nBinsAboveThr++;
809 0 : }
810 : }
811 :
812 0 : if(nBinsAboveThr>0) return sum/nBinsAboveThr;
813 0 : else return hV->GetMean();
814 0 : }
815 :
816 : //--------------------------------------------------------------------------
817 : void AliT0QAChecker::GetMeanAndRmsAroundMainMaximum(Float_t &meanHisto,Float_t &rmsHisto, TH1F *histo, int type) const{
818 :
819 0 : if(!histo){
820 0 : meanHisto=0.0;
821 0 : rmsHisto=0.0;
822 0 : return;
823 : }
824 0 : if(histo->Integral()<0.00001){
825 0 : meanHisto=0.0;
826 0 : rmsHisto=0.0;
827 0 : return;
828 : }
829 :
830 : double nSigma = 3.0; //n sigma window around mean and main maximum
831 : double expectedRMS = 13.0; // expected rms of the main peak in case of CFD
832 0 : if(type == 1) expectedRMS = 34.0; //LED
833 0 : if(type == 2) expectedRMS = 34.0; //QTC
834 :
835 : //0) approx of mean is global maximum
836 0 : Int_t nb = histo->GetNbinsX();
837 0 : Int_t bmax = histo->GetMaximumBin();
838 0 : Float_t xmax = histo->GetBinCenter(bmax);
839 :
840 0 : double window = expectedRMS * nSigma;
841 : //1) estimate a mean in the nSigma window around main max
842 0 : int nlow = histo->FindBin( xmax - window);
843 0 : int nhigh = histo->FindBin( xmax + window);
844 0 : if(nlow<1) nlow = 1;
845 0 : if(nhigh>nb) nhigh = nb;
846 :
847 : Float_t sum=0.0, sumWeight=0.0, sumWeightSqr=0.0;
848 0 : for(int ii=nlow;ii<=nhigh;ii++){
849 0 : sum += histo->GetBinContent(ii);
850 0 : sumWeight += histo->GetBinContent(ii)*histo->GetBinCenter(ii);
851 : }
852 0 : if(sum>0.0){
853 0 : meanHisto = sumWeight/sum; //mean in 1st itteration
854 : }else{
855 0 : meanHisto = 0.0;
856 0 : rmsHisto=0.0;
857 0 : return;
858 : }
859 :
860 : //2) recalculte mean and rms in the nSigma window around mean 1)
861 0 : nlow = histo->FindBin( meanHisto - window);
862 0 : nhigh = histo->FindBin( meanHisto + window);
863 0 : if(nlow<1) nlow = 1;
864 0 : if(nhigh>nb) nhigh = nb;
865 :
866 : sum=0.0; sumWeight=0.0; sumWeightSqr=0.0;
867 0 : for(int ii=nlow;ii<=nhigh;ii++){
868 0 : sum += histo->GetBinContent(ii);
869 0 : sumWeight += histo->GetBinContent(ii)*histo->GetBinCenter(ii);
870 0 : sumWeightSqr += histo->GetBinContent(ii)*histo->GetBinCenter(ii)*histo->GetBinCenter(ii);
871 : }
872 0 : if(sum>0.0){
873 0 : meanHisto = sumWeight/sum; //mean in 2nd itteration
874 0 : rmsHisto = sumWeightSqr/sum - meanHisto*meanHisto;//rms square
875 0 : if(rmsHisto > 0.0) rmsHisto = sqrt(rmsHisto); //rms
876 0 : else rmsHisto = 0.0;
877 0 : return;
878 : }else{
879 0 : meanHisto = 0.0;
880 0 : rmsHisto = 0.0;
881 0 : return;
882 : }
883 0 : }
|