1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 // This class maintains a histogram that is used to monitor the quality //
21 // of the recorded data. //
22 // The histogram is created and filled by a sub class of AliMonitor. //
23 // It can be compared to a reference histogram. For the comparison a //
24 // maximal deviation (in standard deviations) can be specified. //
25 // The bins where the maximal deviation is exceeded are drawn in red. //
27 ///////////////////////////////////////////////////////////////////////////////
32 #include <TVirtualPad.h>
36 #include "AliMonitorHisto.h"
39 ClassImp(AliMonitorHisto)
42 Int_t AliMonitorHisto::fgNHistosMax = 10;
45 //_____________________________________________________________________________
46 AliMonitorHisto::AliMonitorHisto()
59 //_____________________________________________________________________________
60 AliMonitorHisto::AliMonitorHisto(const AliMonitorHisto& histo) :
65 Bool_t addStatus = TH1::AddDirectoryStatus();
66 TH1::AddDirectory(kFALSE);
68 if (histo.fHisto) fHisto = (TH1*) histo.fHisto->Clone();
69 fNHistos = histo.fNHistos;
70 TObjLink* link = histo.fHistoList.FirstLink();
71 for (Int_t i = 0; i < fNHistos; i++) {
72 fHistoList.Add(link->GetObject()->Clone());
76 if (histo.fHistoRun) fHistoRun = (TH1*) histo.fHistoRun->Clone();
79 if (histo.fHistoRef) fHistoRef = (TH1*) histo.fHistoRef->Clone();
82 TH1::AddDirectory(addStatus);
85 //_____________________________________________________________________________
86 AliMonitorHisto& AliMonitorHisto::operator =(const AliMonitorHisto& histo)
88 // assignment operator
90 AliMonitorPlot::operator =(histo);
92 Bool_t addStatus = TH1::AddDirectoryStatus();
93 TH1::AddDirectory(kFALSE);
95 if (histo.fHisto) fHisto = (TH1*) histo.fHisto->Clone();
96 fNHistos = histo.fNHistos;
97 TObjLink* link = histo.fHistoList.FirstLink();
98 for (Int_t i = 0; i < fNHistos; i++) {
99 fHistoList.Add(link->GetObject()->Clone());
103 if (histo.fHistoRun) fHistoRun = (TH1*) histo.fHistoRun->Clone();
106 if (histo.fHistoRef) fHistoRef = (TH1*) histo.fHistoRef->Clone();
107 fHistoCompare = NULL;
109 TH1::AddDirectory(addStatus);
114 //_____________________________________________________________________________
115 AliMonitorHisto::AliMonitorHisto(TH1* histo, ENorm norm) :
116 AliMonitorPlot(histo->GetName(), histo->GetTitle())
118 // create a monitor histogram from the given histogram
120 if (histo->GetDimension() > 2) {
121 AliFatal("3 dimensional histograms are not supported");
124 histo->SetDirectory(NULL);
129 Bool_t addStatus = TH1::AddDirectoryStatus();
130 TH1::AddDirectory(kFALSE);
131 fHistoRun = (TH1*) histo->Clone();
132 TH1::AddDirectory(addStatus);
135 fHistoCompare = NULL;
139 //_____________________________________________________________________________
140 AliMonitorHisto::~AliMonitorHisto()
142 // delete all histograms
144 if (fHisto) delete fHisto;
146 if (fHistoRun) delete fHistoRun;
147 if (fHistoDraw) delete fHistoDraw;
148 if (fHistoCompare) delete fHistoCompare;
152 //_____________________________________________________________________________
153 void AliMonitorHisto::SetReference(TH1* ref)
155 // set the reference histogram for comparison
157 if (fHistoRef) delete fHistoRef;
158 Bool_t addStatus = TH1::AddDirectoryStatus();
159 TH1::AddDirectory(kFALSE);
160 TH1::AddDirectory(addStatus);
161 fHistoRef = (TH1*) ref->Clone();
162 if (fHistoCompare) fHistoCompare->Reset();
165 //_____________________________________________________________________________
166 void AliMonitorHisto::SetReference(AliMonitorPlot* ref)
168 // set the reference histogram for comparison
170 if (!ref->InheritsFrom(AliMonitorHisto::Class())) return;
171 ((AliMonitorHisto*)ref)->GetRun();
172 SetReference(((AliMonitorHisto*)ref)->fHistoDraw);
176 //_____________________________________________________________________________
177 void AliMonitorHisto::Fill(Axis_t x)
179 // fill the monitor histogram
184 //_____________________________________________________________________________
185 void AliMonitorHisto::Fill(Axis_t x, Axis_t y)
187 // fill the monitor histogram
192 //_____________________________________________________________________________
193 void AliMonitorHisto::Fill(Axis_t x, Axis_t y, Stat_t w)
195 // fill the monitor histogram
197 if (fHisto->InheritsFrom(TH2::Class())) {
198 ((TH2*)fHisto)->Fill(x, y, w);
199 } else if (fHisto->InheritsFrom(TProfile::Class())) {
200 ((TProfile*)fHisto)->Fill(x, y, w);
202 AliError("trying to fill x and y of a 1 dimensinal histogram");
207 //_____________________________________________________________________________
208 void AliMonitorHisto::ScaleErrorBy(Double_t factor)
210 // multiply the error of each bin by the given factor
213 if (fHisto->GetDimension() > 1)
214 yMax = fHisto->GetYaxis()->GetNbins();
215 Int_t xMax = fHisto->GetXaxis()->GetNbins();
216 for (Int_t iY = 1; iY <= yMax; iY++) {
217 for (Int_t iX = 1; iX <= xMax; iX++) {
218 Int_t iBin = fHisto->GetBin(iX, iY);
219 fHisto->SetBinError(iBin, factor * fHisto->GetBinError(iBin));
225 //_____________________________________________________________________________
226 void AliMonitorHisto::Update()
228 // update the normalized data histogram
234 //_____________________________________________________________________________
235 void AliMonitorHisto::Update(TH1* histo)
237 // update the normalized data histogram using the given histo instead of fHisto
240 while (fNHistos >= fgNHistosMax) {
241 fHistoList.Remove(fHistoList.LastLink());
244 Bool_t addStatus = TH1::AddDirectoryStatus();
245 TH1::AddDirectory(kFALSE);
246 fHistoList.AddFirst(histo->Clone());
247 TH1::AddDirectory(addStatus);
249 fHistoRun->Add(histo);
253 //_____________________________________________________________________________
254 void AliMonitorHisto::Add(AliMonitorPlot* plot)
256 // merge the given histo to this one
258 if (!plot->InheritsFrom(AliMonitorHisto::Class())) return;
259 AliMonitorHisto* histo = (AliMonitorHisto*) plot;
261 fNumberOfEvents += histo->fNumberOfEvents;
262 Bool_t addStatus = TH1::AddDirectoryStatus();
263 TH1::AddDirectory(kFALSE);
264 TObjLink* link = histo->fHistoList.LastLink();
266 fHistoList.AddFirst(link->GetObject()->Clone());
269 TH1::AddDirectory(addStatus);
270 fNHistos += histo->fNHistos;
271 while (fNHistos > fgNHistosMax) {
272 fHistoList.Remove(fHistoList.LastLink());
275 fHistoRun->Add(histo->fHistoRun);
278 //_____________________________________________________________________________
279 void AliMonitorHisto::Reset()
281 // reset the monitor histogram for a new run
287 if (fHistoDraw) delete fHistoDraw;
289 if (fHistoCompare) delete fHistoCompare;
290 fHistoCompare = NULL;
294 //_____________________________________________________________________________
295 void AliMonitorHisto::ResetList()
297 // reset the the list of monitor histograms
304 //_____________________________________________________________________________
305 void AliMonitorHisto::Scale(Int_t nEvents)
307 // scale the histogram to the correct normalization
311 case kNormNone : scale = 1.; break;
312 case kNormEvents : scale = 1./nEvents; break;
313 case kNormEntries : scale = ((fHistoDraw->GetEntries() > 0) ?
314 1./fHistoDraw->GetEntries() : 1.); break;
315 case kNormIntegral: scale = ((fHistoDraw->Integral() > 0) ?
316 1./fHistoDraw->Integral() : 1.); break;
318 fHistoDraw->Scale(scale);
321 //_____________________________________________________________________________
322 Bool_t AliMonitorHisto::ComparePlot()
324 // compare the data histogram to the reference histogram
325 // if they deviate by more than fgThreshold standard deviations in a bin,
326 // this bin is set in fHistoCompare and kFALSE is returned
328 if (!fHistoRef) return kTRUE;
329 if (fgThreshold <= 0) return kTRUE;
331 AliWarning("no data histogram available for comparison\ncall DrawEvent, DrawSum or DrawRaw before calling Compare");
334 if (fHistoCompare) delete fHistoCompare;
335 Bool_t addStatus = TH1::AddDirectoryStatus();
336 TH1::AddDirectory(kFALSE);
337 fHistoCompare = (TH1*) fHistoDraw->Clone();
338 TH1::AddDirectory(addStatus);
339 fHistoCompare->Reset();
340 Bool_t result = kTRUE;
343 if (fHistoDraw->GetDimension() > 1)
344 yMax = fHistoDraw->GetYaxis()->GetNbins();
345 Int_t xMax = fHistoDraw->GetXaxis()->GetNbins();
346 for (Int_t iY = 1; iY <= yMax; iY++) {
347 for (Int_t iX = 1; iX <= xMax; iX++) {
348 Int_t iBin = fHistoDraw->GetBin(iX, iY);
349 Double_t delta = TMath::Abs(fHistoDraw->GetBinContent(iBin) -
350 fHistoRef->GetBinContent(iBin));
351 Double_t errorData = fHistoDraw->GetBinError(iBin);
352 Double_t errorRef = fHistoRef->GetBinError(iBin);
353 Double_t sigma = TMath::Sqrt(errorData*errorData + errorRef*errorRef);
354 if (delta > fgThreshold*sigma) {
355 fHistoCompare->SetBinContent(iBin, fHistoDraw->GetBinContent(iBin));
356 fHistoCompare->SetBinError(iBin, errorData);
365 //_____________________________________________________________________________
366 Bool_t AliMonitorHisto::GetEvent(Int_t number)
368 // get the normalized monitor histogram for the "number"th last event
371 AliWarning("there are no histograms for single events available");
374 if (number > fNHistos) {
375 AliError(Form("requested event number (%d) exceeds range of available events (%d)",
379 if (number <= 0) return kFALSE;
381 if (fHistoDraw) delete fHistoDraw;
382 if (fHistoCompare) delete fHistoCompare;
383 fHistoCompare = NULL;
385 TObjLink* link = fHistoList.FirstLink();
386 for (Int_t i = 1; i < number; i++) link = link->Next();
387 Bool_t addStatus = TH1::AddDirectoryStatus();
388 TH1::AddDirectory(kFALSE);
389 fHistoDraw = (TH1*) link->GetObject()->Clone();
390 TH1::AddDirectory(addStatus);
396 //_____________________________________________________________________________
397 Bool_t AliMonitorHisto::GetSum(Int_t number)
399 // get the normalized monitor histogram for the sum of the last
403 AliWarning("there are no histograms for single events available");
406 if (number > fNHistos) {
407 AliError(Form("requested number of events (%d) exceeds range of available events (%d)\nusing last %d event(s)",
408 number, fNHistos, fNHistos));
411 if (number <= 0) return kFALSE;
413 if (fHistoDraw) delete fHistoDraw;
414 if (fHistoCompare) delete fHistoCompare;
415 fHistoCompare = NULL;
417 TObjLink* link = fHistoList.FirstLink();
418 Bool_t addStatus = TH1::AddDirectoryStatus();
419 TH1::AddDirectory(kFALSE);
420 fHistoDraw = (TH1*) link->GetObject()->Clone();
421 TH1::AddDirectory(addStatus);
422 for (Int_t i = 1; i < number; i++) {
424 fHistoDraw->Add((TH1*) link->GetObject());
431 //_____________________________________________________________________________
432 Bool_t AliMonitorHisto::GetRun()
434 // get the normalized monitor histogram for all monitored events
435 // of the current run
437 if (fHistoDraw) delete fHistoDraw;
438 if (fHistoCompare) delete fHistoCompare;
439 fHistoCompare = NULL;
441 Bool_t addStatus = TH1::AddDirectoryStatus();
442 TH1::AddDirectory(kFALSE);
443 fHistoDraw = (TH1*) fHistoRun->Clone();
444 TH1::AddDirectory(addStatus);
446 Scale(fNumberOfEvents);
450 //_____________________________________________________________________________
451 void AliMonitorHisto::DrawPlot()
453 // draw the histograms
455 fHistoDraw->SetMarkerColor(fgColorData);
456 fHistoDraw->SetLineColor(fgColorData);
457 fHistoDraw->SetFillColor(fgColorData);
458 fHistoDraw->DrawCopy();
460 if (fHistoRef && fgDrawRef) {
462 sprintf(option, "%sSAME", fHistoDraw->GetOption());
464 if (fHistoRef->GetMaximum() > fHistoDraw->GetMaximum()) {
465 fHistoDraw->SetMaximum(fHistoRef->GetMaximum() * 1.1);
468 fHistoRef->SetMarkerColor(fgColorRef);
469 fHistoRef->SetLineColor(fgColorRef);
470 fHistoRef->SetFillColor(fgColorRef);
471 fHistoRef->DrawCopy(option);
473 fHistoDraw->DrawCopy(option);
475 if (fHistoCompare && (fgThreshold > 0)) {
476 fHistoCompare->SetMarkerColor(fgColorCompare);
477 fHistoCompare->SetLineColor(fgColorCompare);
478 fHistoCompare->SetFillColor(fgColorCompare);
479 fHistoCompare->DrawCopy(option);