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() :
61 //_____________________________________________________________________________
62 AliMonitorHisto::AliMonitorHisto(const AliMonitorHisto& histo) :
63 AliMonitorPlot(histo),
66 fNHistos(histo.fNHistos),
75 Bool_t addStatus = TH1::AddDirectoryStatus();
76 TH1::AddDirectory(kFALSE);
77 if (histo.fHisto) fHisto = (TH1*) histo.fHisto->Clone();
78 TObjLink* link = histo.fHistoList.FirstLink();
79 for (Int_t i = 0; i < fNHistos; i++) {
80 fHistoList.Add(link->GetObject()->Clone());
83 if (histo.fHistoRun) fHistoRun = (TH1*) histo.fHistoRun->Clone();
84 if (histo.fHistoRef) fHistoRef = (TH1*) histo.fHistoRef->Clone();
85 TH1::AddDirectory(addStatus);
88 //_____________________________________________________________________________
89 AliMonitorHisto& AliMonitorHisto::operator =(const AliMonitorHisto& histo)
91 // assignment operator
93 AliMonitorPlot::operator =(histo);
95 Bool_t addStatus = TH1::AddDirectoryStatus();
96 TH1::AddDirectory(kFALSE);
98 if (histo.fHisto) fHisto = (TH1*) histo.fHisto->Clone();
99 fNHistos = histo.fNHistos;
100 TObjLink* link = histo.fHistoList.FirstLink();
101 for (Int_t i = 0; i < fNHistos; i++) {
102 fHistoList.Add(link->GetObject()->Clone());
106 if (histo.fHistoRun) fHistoRun = (TH1*) histo.fHistoRun->Clone();
109 if (histo.fHistoRef) fHistoRef = (TH1*) histo.fHistoRef->Clone();
110 fHistoCompare = NULL;
112 TH1::AddDirectory(addStatus);
117 //_____________________________________________________________________________
118 AliMonitorHisto::AliMonitorHisto(TH1* histo, ENorm norm) :
119 AliMonitorPlot(histo->GetName(), histo->GetTitle()),
129 // create a monitor histogram from the given histogram
131 if (histo->GetDimension() > 2) {
132 AliFatal("3 dimensional histograms are not supported");
135 histo->SetDirectory(NULL);
138 Bool_t addStatus = TH1::AddDirectoryStatus();
139 TH1::AddDirectory(kFALSE);
140 fHistoRun = (TH1*) histo->Clone();
141 TH1::AddDirectory(addStatus);
144 //_____________________________________________________________________________
145 AliMonitorHisto::~AliMonitorHisto()
147 // delete all histograms
149 if (fHisto) delete fHisto;
151 if (fHistoRun) delete fHistoRun;
152 if (fHistoDraw) delete fHistoDraw;
153 if (fHistoCompare) delete fHistoCompare;
157 //_____________________________________________________________________________
158 void AliMonitorHisto::SetReference(TH1* ref)
160 // set the reference histogram for comparison
162 if (fHistoRef) delete fHistoRef;
163 Bool_t addStatus = TH1::AddDirectoryStatus();
164 TH1::AddDirectory(kFALSE);
165 TH1::AddDirectory(addStatus);
166 fHistoRef = (TH1*) ref->Clone();
167 if (fHistoCompare) fHistoCompare->Reset();
170 //_____________________________________________________________________________
171 void AliMonitorHisto::SetReference(AliMonitorPlot* ref)
173 // set the reference histogram for comparison
175 if (!ref->InheritsFrom(AliMonitorHisto::Class())) return;
176 ((AliMonitorHisto*)ref)->GetRun();
177 SetReference(((AliMonitorHisto*)ref)->fHistoDraw);
181 //_____________________________________________________________________________
182 void AliMonitorHisto::Fill(Axis_t x)
184 // fill the monitor histogram
189 //_____________________________________________________________________________
190 void AliMonitorHisto::Fill(Axis_t x, Axis_t y)
192 // fill the monitor histogram
197 //_____________________________________________________________________________
198 void AliMonitorHisto::Fill(Axis_t x, Axis_t y, Stat_t w)
200 // fill the monitor histogram
202 if (fHisto->InheritsFrom(TH2::Class())) {
203 ((TH2*)fHisto)->Fill(x, y, w);
204 } else if (fHisto->InheritsFrom(TProfile::Class())) {
205 ((TProfile*)fHisto)->Fill(x, y, w);
207 AliError("trying to fill x and y of a 1 dimensinal histogram");
212 //_____________________________________________________________________________
213 void AliMonitorHisto::ScaleErrorBy(Double_t factor)
215 // multiply the error of each bin by the given factor
218 if (fHisto->GetDimension() > 1)
219 yMax = fHisto->GetYaxis()->GetNbins();
220 Int_t xMax = fHisto->GetXaxis()->GetNbins();
221 for (Int_t iY = 1; iY <= yMax; iY++) {
222 for (Int_t iX = 1; iX <= xMax; iX++) {
223 Int_t iBin = fHisto->GetBin(iX, iY);
224 fHisto->SetBinError(iBin, factor * fHisto->GetBinError(iBin));
230 //_____________________________________________________________________________
231 void AliMonitorHisto::Update()
233 // update the normalized data histogram
239 //_____________________________________________________________________________
240 void AliMonitorHisto::Update(TH1* histo)
242 // update the normalized data histogram using the given histo instead of fHisto
245 while (fNHistos >= fgNHistosMax) {
246 fHistoList.Remove(fHistoList.LastLink());
249 Bool_t addStatus = TH1::AddDirectoryStatus();
250 TH1::AddDirectory(kFALSE);
251 fHistoList.AddFirst(histo->Clone());
252 TH1::AddDirectory(addStatus);
254 fHistoRun->Add(histo);
258 //_____________________________________________________________________________
259 void AliMonitorHisto::Add(AliMonitorPlot* plot)
261 // merge the given histo to this one
263 if (!plot->InheritsFrom(AliMonitorHisto::Class())) return;
264 AliMonitorHisto* histo = (AliMonitorHisto*) plot;
266 fNumberOfEvents += histo->fNumberOfEvents;
267 Bool_t addStatus = TH1::AddDirectoryStatus();
268 TH1::AddDirectory(kFALSE);
269 TObjLink* link = histo->fHistoList.LastLink();
271 fHistoList.AddFirst(link->GetObject()->Clone());
274 TH1::AddDirectory(addStatus);
275 fNHistos += histo->fNHistos;
276 while (fNHistos > fgNHistosMax) {
277 fHistoList.Remove(fHistoList.LastLink());
280 fHistoRun->Add(histo->fHistoRun);
283 //_____________________________________________________________________________
284 void AliMonitorHisto::Reset()
286 // reset the monitor histogram for a new run
292 if (fHistoDraw) delete fHistoDraw;
294 if (fHistoCompare) delete fHistoCompare;
295 fHistoCompare = NULL;
299 //_____________________________________________________________________________
300 void AliMonitorHisto::ResetList()
302 // reset the the list of monitor histograms
309 //_____________________________________________________________________________
310 void AliMonitorHisto::Scale(Int_t nEvents)
312 // scale the histogram to the correct normalization
316 case kNormNone : scale = 1.; break;
317 case kNormEvents : scale = 1./nEvents; break;
318 case kNormEntries : scale = ((fHistoDraw->GetEntries() > 0) ?
319 1./fHistoDraw->GetEntries() : 1.); break;
320 case kNormIntegral: scale = ((fHistoDraw->Integral() > 0) ?
321 1./fHistoDraw->Integral() : 1.); break;
323 fHistoDraw->Scale(scale);
326 //_____________________________________________________________________________
327 Bool_t AliMonitorHisto::ComparePlot()
329 // compare the data histogram to the reference histogram
330 // if they deviate by more than fgThreshold standard deviations in a bin,
331 // this bin is set in fHistoCompare and kFALSE is returned
333 if (!fHistoRef) return kTRUE;
334 if (fgThreshold <= 0) return kTRUE;
336 AliWarning("no data histogram available for comparison\ncall DrawEvent, DrawSum or DrawRaw before calling Compare");
339 if (fHistoCompare) delete fHistoCompare;
340 Bool_t addStatus = TH1::AddDirectoryStatus();
341 TH1::AddDirectory(kFALSE);
342 fHistoCompare = (TH1*) fHistoDraw->Clone();
343 TH1::AddDirectory(addStatus);
344 fHistoCompare->Reset();
345 Bool_t result = kTRUE;
348 if (fHistoDraw->GetDimension() > 1)
349 yMax = fHistoDraw->GetYaxis()->GetNbins();
350 Int_t xMax = fHistoDraw->GetXaxis()->GetNbins();
351 for (Int_t iY = 1; iY <= yMax; iY++) {
352 for (Int_t iX = 1; iX <= xMax; iX++) {
353 Int_t iBin = fHistoDraw->GetBin(iX, iY);
354 Double_t delta = TMath::Abs(fHistoDraw->GetBinContent(iBin) -
355 fHistoRef->GetBinContent(iBin));
356 Double_t errorData = fHistoDraw->GetBinError(iBin);
357 Double_t errorRef = fHistoRef->GetBinError(iBin);
358 Double_t sigma = TMath::Sqrt(errorData*errorData + errorRef*errorRef);
359 if (delta > fgThreshold*sigma) {
360 fHistoCompare->SetBinContent(iBin, fHistoDraw->GetBinContent(iBin));
361 fHistoCompare->SetBinError(iBin, errorData);
370 //_____________________________________________________________________________
371 Bool_t AliMonitorHisto::GetEvent(Int_t number)
373 // get the normalized monitor histogram for the "number"th last event
376 AliWarning("there are no histograms for single events available");
379 if (number > fNHistos) {
380 AliError(Form("requested event number (%d) exceeds range of available events (%d)",
384 if (number <= 0) return kFALSE;
386 if (fHistoDraw) delete fHistoDraw;
387 if (fHistoCompare) delete fHistoCompare;
388 fHistoCompare = NULL;
390 TObjLink* link = fHistoList.FirstLink();
391 for (Int_t i = 1; i < number; i++) link = link->Next();
392 Bool_t addStatus = TH1::AddDirectoryStatus();
393 TH1::AddDirectory(kFALSE);
394 fHistoDraw = (TH1*) link->GetObject()->Clone();
395 TH1::AddDirectory(addStatus);
401 //_____________________________________________________________________________
402 Bool_t AliMonitorHisto::GetSum(Int_t number)
404 // get the normalized monitor histogram for the sum of the last
408 AliWarning("there are no histograms for single events available");
411 if (number > fNHistos) {
412 AliError(Form("requested number of events (%d) exceeds range of available events (%d)\nusing last %d event(s)",
413 number, fNHistos, fNHistos));
416 if (number <= 0) return kFALSE;
418 if (fHistoDraw) delete fHistoDraw;
419 if (fHistoCompare) delete fHistoCompare;
420 fHistoCompare = NULL;
422 TObjLink* link = fHistoList.FirstLink();
423 Bool_t addStatus = TH1::AddDirectoryStatus();
424 TH1::AddDirectory(kFALSE);
425 fHistoDraw = (TH1*) link->GetObject()->Clone();
426 TH1::AddDirectory(addStatus);
427 for (Int_t i = 1; i < number; i++) {
429 fHistoDraw->Add((TH1*) link->GetObject());
436 //_____________________________________________________________________________
437 Bool_t AliMonitorHisto::GetRun()
439 // get the normalized monitor histogram for all monitored events
440 // of the current run
442 if (fHistoDraw) delete fHistoDraw;
443 if (fHistoCompare) delete fHistoCompare;
444 fHistoCompare = NULL;
446 Bool_t addStatus = TH1::AddDirectoryStatus();
447 TH1::AddDirectory(kFALSE);
448 fHistoDraw = (TH1*) fHistoRun->Clone();
449 TH1::AddDirectory(addStatus);
451 Scale(fNumberOfEvents);
455 //_____________________________________________________________________________
456 void AliMonitorHisto::DrawPlot()
458 // draw the histograms
460 fHistoDraw->SetMarkerColor(fgColorData);
461 fHistoDraw->SetLineColor(fgColorData);
462 fHistoDraw->SetFillColor(fgColorData);
463 fHistoDraw->DrawCopy();
465 if (fHistoRef && fgDrawRef) {
467 sprintf(option, "%sSAME", fHistoDraw->GetOption());
469 if (fHistoRef->GetMaximum() > fHistoDraw->GetMaximum()) {
470 fHistoDraw->SetMaximum(fHistoRef->GetMaximum() * 1.1);
473 fHistoRef->SetMarkerColor(fgColorRef);
474 fHistoRef->SetLineColor(fgColorRef);
475 fHistoRef->SetFillColor(fgColorRef);
476 fHistoRef->DrawCopy(option);
478 fHistoDraw->DrawCopy(option);
480 if (fHistoCompare && (fgThreshold > 0)) {
481 fHistoCompare->SetMarkerColor(fgColorCompare);
482 fHistoCompare->SetLineColor(fgColorCompare);
483 fHistoCompare->SetFillColor(fgColorCompare);
484 fHistoCompare->DrawCopy(option);