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 ///////////////////////////////////////////////////////////////////////////////
33 #include <TVirtualPad.h>
37 #include "AliMonitorHisto.h"
40 ClassImp(AliMonitorHisto)
43 Int_t AliMonitorHisto::fgNHistosMax = 10;
46 //_____________________________________________________________________________
47 AliMonitorHisto::AliMonitorHisto() :
62 //_____________________________________________________________________________
63 AliMonitorHisto::AliMonitorHisto(const AliMonitorHisto& histo) :
64 AliMonitorPlot(histo),
67 fNHistos(histo.fNHistos),
76 Bool_t addStatus = TH1::AddDirectoryStatus();
77 TH1::AddDirectory(kFALSE);
78 if (histo.fHisto) fHisto = (TH1*) histo.fHisto->Clone();
79 TObjLink* link = histo.fHistoList.FirstLink();
80 for (Int_t i = 0; i < fNHistos; i++) {
81 fHistoList.Add(link->GetObject()->Clone());
84 if (histo.fHistoRun) fHistoRun = (TH1*) histo.fHistoRun->Clone();
85 if (histo.fHistoRef) fHistoRef = (TH1*) histo.fHistoRef->Clone();
86 TH1::AddDirectory(addStatus);
89 //_____________________________________________________________________________
90 AliMonitorHisto& AliMonitorHisto::operator =(const AliMonitorHisto& histo)
92 // assignment operator
94 AliMonitorPlot::operator =(histo);
96 Bool_t addStatus = TH1::AddDirectoryStatus();
97 TH1::AddDirectory(kFALSE);
99 if (histo.fHisto) fHisto = (TH1*) histo.fHisto->Clone();
100 fNHistos = histo.fNHistos;
101 TObjLink* link = histo.fHistoList.FirstLink();
102 for (Int_t i = 0; i < fNHistos; i++) {
103 fHistoList.Add(link->GetObject()->Clone());
107 if (histo.fHistoRun) fHistoRun = (TH1*) histo.fHistoRun->Clone();
110 if (histo.fHistoRef) fHistoRef = (TH1*) histo.fHistoRef->Clone();
111 fHistoCompare = NULL;
113 TH1::AddDirectory(addStatus);
118 //_____________________________________________________________________________
119 AliMonitorHisto::AliMonitorHisto(TH1* histo, ENorm norm) :
120 AliMonitorPlot(histo->GetName(), histo->GetTitle()),
130 // create a monitor histogram from the given histogram
132 if (histo->GetDimension() > 2) {
133 AliFatal("3 dimensional histograms are not supported");
136 histo->SetDirectory(NULL);
139 Bool_t addStatus = TH1::AddDirectoryStatus();
140 TH1::AddDirectory(kFALSE);
141 fHistoRun = (TH1*) histo->Clone();
142 TH1::AddDirectory(addStatus);
145 //_____________________________________________________________________________
146 AliMonitorHisto::~AliMonitorHisto()
148 // delete all histograms
150 if (fHisto) delete fHisto;
152 if (fHistoRun) delete fHistoRun;
153 if (fHistoDraw) delete fHistoDraw;
154 if (fHistoCompare) delete fHistoCompare;
158 //_____________________________________________________________________________
159 void AliMonitorHisto::SetReference(TH1* ref)
161 // set the reference histogram for comparison
163 if (fHistoRef) delete fHistoRef;
164 Bool_t addStatus = TH1::AddDirectoryStatus();
165 TH1::AddDirectory(kFALSE);
166 TH1::AddDirectory(addStatus);
167 fHistoRef = (TH1*) ref->Clone();
168 if (fHistoCompare) fHistoCompare->Reset();
171 //_____________________________________________________________________________
172 void AliMonitorHisto::SetReference(AliMonitorPlot* ref)
174 // set the reference histogram for comparison
176 if (!ref->InheritsFrom(AliMonitorHisto::Class())) return;
177 ((AliMonitorHisto*)ref)->GetRun();
178 SetReference(((AliMonitorHisto*)ref)->fHistoDraw);
182 //_____________________________________________________________________________
183 void AliMonitorHisto::Fill(Axis_t x)
185 // fill the monitor histogram
190 //_____________________________________________________________________________
191 void AliMonitorHisto::Fill(Axis_t x, Axis_t y)
193 // fill the monitor histogram
198 //_____________________________________________________________________________
199 void AliMonitorHisto::Fill(Axis_t x, Axis_t y, Stat_t w)
201 // fill the monitor histogram
203 if (fHisto->InheritsFrom(TH2::Class())) {
204 ((TH2*)fHisto)->Fill(x, y, w);
205 } else if (fHisto->InheritsFrom(TProfile::Class())) {
206 ((TProfile*)fHisto)->Fill(x, y, w);
208 AliError("trying to fill x and y of a 1 dimensinal histogram");
213 //_____________________________________________________________________________
214 void AliMonitorHisto::ScaleErrorBy(Double_t factor)
216 // multiply the error of each bin by the given factor
219 if (fHisto->GetDimension() > 1)
220 yMax = fHisto->GetYaxis()->GetNbins();
221 Int_t xMax = fHisto->GetXaxis()->GetNbins();
222 for (Int_t iY = 1; iY <= yMax; iY++) {
223 for (Int_t iX = 1; iX <= xMax; iX++) {
224 Int_t iBin = fHisto->GetBin(iX, iY);
225 fHisto->SetBinError(iBin, factor * fHisto->GetBinError(iBin));
231 //_____________________________________________________________________________
232 void AliMonitorHisto::Update()
234 // update the normalized data histogram
240 //_____________________________________________________________________________
241 void AliMonitorHisto::Update(TH1* histo)
243 // update the normalized data histogram using the given histo instead of fHisto
246 while (fNHistos >= fgNHistosMax) {
247 fHistoList.Remove(fHistoList.LastLink());
250 Bool_t addStatus = TH1::AddDirectoryStatus();
251 TH1::AddDirectory(kFALSE);
252 fHistoList.AddFirst(histo->Clone());
253 TH1::AddDirectory(addStatus);
255 fHistoRun->Add(histo);
259 //_____________________________________________________________________________
260 void AliMonitorHisto::Add(AliMonitorPlot* plot)
262 // merge the given histo to this one
264 if (!plot->InheritsFrom(AliMonitorHisto::Class())) return;
265 AliMonitorHisto* histo = (AliMonitorHisto*) plot;
267 fNumberOfEvents += histo->fNumberOfEvents;
268 Bool_t addStatus = TH1::AddDirectoryStatus();
269 TH1::AddDirectory(kFALSE);
270 TObjLink* link = histo->fHistoList.LastLink();
272 fHistoList.AddFirst(link->GetObject()->Clone());
275 TH1::AddDirectory(addStatus);
276 fNHistos += histo->fNHistos;
277 while (fNHistos > fgNHistosMax) {
278 fHistoList.Remove(fHistoList.LastLink());
281 fHistoRun->Add(histo->fHistoRun);
284 //_____________________________________________________________________________
285 void AliMonitorHisto::Reset()
287 // reset the monitor histogram for a new run
293 if (fHistoDraw) delete fHistoDraw;
295 if (fHistoCompare) delete fHistoCompare;
296 fHistoCompare = NULL;
300 //_____________________________________________________________________________
301 void AliMonitorHisto::ResetList()
303 // reset the the list of monitor histograms
310 //_____________________________________________________________________________
311 void AliMonitorHisto::Scale(Int_t nEvents)
313 // scale the histogram to the correct normalization
317 case kNormNone : scale = 1.; break;
318 case kNormEvents : scale = 1./nEvents; break;
319 case kNormEntries : scale = ((fHistoDraw->GetEntries() > 0) ?
320 1./fHistoDraw->GetEntries() : 1.); break;
321 case kNormIntegral: scale = ((fHistoDraw->Integral() > 0) ?
322 1./fHistoDraw->Integral() : 1.); break;
324 fHistoDraw->Scale(scale);
327 //_____________________________________________________________________________
328 Bool_t AliMonitorHisto::ComparePlot()
330 // compare the data histogram to the reference histogram
331 // if they deviate by more than fgThreshold standard deviations in a bin,
332 // this bin is set in fHistoCompare and kFALSE is returned
334 if (!fHistoRef) return kTRUE;
335 if (fgThreshold <= 0) return kTRUE;
337 AliWarning("no data histogram available for comparison\ncall DrawEvent, DrawSum or DrawRaw before calling Compare");
340 if (fHistoCompare) delete fHistoCompare;
341 Bool_t addStatus = TH1::AddDirectoryStatus();
342 TH1::AddDirectory(kFALSE);
343 fHistoCompare = (TH1*) fHistoDraw->Clone();
344 TH1::AddDirectory(addStatus);
345 fHistoCompare->Reset();
346 Bool_t result = kTRUE;
349 if (fHistoDraw->GetDimension() > 1)
350 yMax = fHistoDraw->GetYaxis()->GetNbins();
351 Int_t xMax = fHistoDraw->GetXaxis()->GetNbins();
352 for (Int_t iY = 1; iY <= yMax; iY++) {
353 for (Int_t iX = 1; iX <= xMax; iX++) {
354 Int_t iBin = fHistoDraw->GetBin(iX, iY);
355 Double_t delta = TMath::Abs(fHistoDraw->GetBinContent(iBin) -
356 fHistoRef->GetBinContent(iBin));
357 Double_t errorData = fHistoDraw->GetBinError(iBin);
358 Double_t errorRef = fHistoRef->GetBinError(iBin);
359 Double_t sigma = TMath::Sqrt(errorData*errorData + errorRef*errorRef);
360 if (delta > fgThreshold*sigma) {
361 fHistoCompare->SetBinContent(iBin, fHistoDraw->GetBinContent(iBin));
362 fHistoCompare->SetBinError(iBin, errorData);
371 //_____________________________________________________________________________
372 Bool_t AliMonitorHisto::GetEvent(Int_t number)
374 // get the normalized monitor histogram for the "number"th last event
377 AliWarning("there are no histograms for single events available");
380 if (number > fNHistos) {
381 AliError(Form("requested event number (%d) exceeds range of available events (%d)",
385 if (number <= 0) return kFALSE;
387 if (fHistoDraw) delete fHistoDraw;
388 if (fHistoCompare) delete fHistoCompare;
389 fHistoCompare = NULL;
391 TObjLink* link = fHistoList.FirstLink();
392 for (Int_t i = 1; i < number; i++) link = link->Next();
393 Bool_t addStatus = TH1::AddDirectoryStatus();
394 TH1::AddDirectory(kFALSE);
395 fHistoDraw = (TH1*) link->GetObject()->Clone();
396 TH1::AddDirectory(addStatus);
402 //_____________________________________________________________________________
403 Bool_t AliMonitorHisto::GetSum(Int_t number)
405 // get the normalized monitor histogram for the sum of the last
409 AliWarning("there are no histograms for single events available");
412 if (number > fNHistos) {
413 AliError(Form("requested number of events (%d) exceeds range of available events (%d)\nusing last %d event(s)",
414 number, fNHistos, fNHistos));
417 if (number <= 0) return kFALSE;
419 if (fHistoDraw) delete fHistoDraw;
420 if (fHistoCompare) delete fHistoCompare;
421 fHistoCompare = NULL;
423 TObjLink* link = fHistoList.FirstLink();
424 Bool_t addStatus = TH1::AddDirectoryStatus();
425 TH1::AddDirectory(kFALSE);
426 fHistoDraw = (TH1*) link->GetObject()->Clone();
427 TH1::AddDirectory(addStatus);
428 for (Int_t i = 1; i < number; i++) {
430 fHistoDraw->Add((TH1*) link->GetObject());
437 //_____________________________________________________________________________
438 Bool_t AliMonitorHisto::GetRun()
440 // get the normalized monitor histogram for all monitored events
441 // of the current run
443 if (fHistoDraw) delete fHistoDraw;
444 if (fHistoCompare) delete fHistoCompare;
445 fHistoCompare = NULL;
447 Bool_t addStatus = TH1::AddDirectoryStatus();
448 TH1::AddDirectory(kFALSE);
449 fHistoDraw = (TH1*) fHistoRun->Clone();
450 TH1::AddDirectory(addStatus);
452 Scale(fNumberOfEvents);
456 //_____________________________________________________________________________
457 void AliMonitorHisto::DrawPlot()
459 // draw the histograms
461 fHistoDraw->SetMarkerColor(fgColorData);
462 fHistoDraw->SetLineColor(fgColorData);
463 fHistoDraw->SetFillColor(fgColorData);
464 fHistoDraw->DrawCopy();
466 if (fHistoRef && fgDrawRef) {
468 sprintf(option, "%sSAME", fHistoDraw->GetOption());
470 if (fHistoRef->GetMaximum() > fHistoDraw->GetMaximum()) {
471 fHistoDraw->SetMaximum(fHistoRef->GetMaximum() * 1.1);
474 fHistoRef->SetMarkerColor(fgColorRef);
475 fHistoRef->SetLineColor(fgColorRef);
476 fHistoRef->SetFillColor(fgColorRef);
477 fHistoRef->DrawCopy(option);
479 fHistoDraw->DrawCopy(option);
481 if (fHistoCompare && (fgThreshold > 0)) {
482 fHistoCompare->SetMarkerColor(fgColorCompare);
483 fHistoCompare->SetLineColor(fgColorCompare);
484 fHistoCompare->SetFillColor(fgColorCompare);
485 fHistoCompare->DrawCopy(option);