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 ///////////////////////////////////////////////////////////////////////////////
30 #include "AliMonitorHisto.h"
33 #include <TVirtualPad.h>
36 ClassImp(AliMonitorHisto)
39 Int_t AliMonitorHisto::fgNHistosMax = 10;
42 //_____________________________________________________________________________
43 AliMonitorHisto::AliMonitorHisto()
56 //_____________________________________________________________________________
57 AliMonitorHisto::AliMonitorHisto(const AliMonitorHisto& histo) :
62 Bool_t addStatus = TH1::AddDirectoryStatus();
63 TH1::AddDirectory(kFALSE);
65 if (histo.fHisto) fHisto = (TH1*) histo.fHisto->Clone();
66 fNHistos = histo.fNHistos;
67 TObjLink* link = histo.fHistoList.FirstLink();
68 for (Int_t i = 0; i < fNHistos; i++) {
69 fHistoList.Add(link->GetObject()->Clone());
73 if (histo.fHistoRun) fHistoRun = (TH1*) histo.fHistoRun->Clone();
76 if (histo.fHistoRef) fHistoRef = (TH1*) histo.fHistoRef->Clone();
79 TH1::AddDirectory(addStatus);
82 //_____________________________________________________________________________
83 AliMonitorHisto& AliMonitorHisto::operator =(const AliMonitorHisto& histo)
85 // assignment operator
87 AliMonitorPlot::operator =(histo);
89 Bool_t addStatus = TH1::AddDirectoryStatus();
90 TH1::AddDirectory(kFALSE);
92 if (histo.fHisto) fHisto = (TH1*) histo.fHisto->Clone();
93 fNHistos = histo.fNHistos;
94 TObjLink* link = histo.fHistoList.FirstLink();
95 for (Int_t i = 0; i < fNHistos; i++) {
96 fHistoList.Add(link->GetObject()->Clone());
100 if (histo.fHistoRun) fHistoRun = (TH1*) histo.fHistoRun->Clone();
103 if (histo.fHistoRef) fHistoRef = (TH1*) histo.fHistoRef->Clone();
104 fHistoCompare = NULL;
106 TH1::AddDirectory(addStatus);
111 //_____________________________________________________________________________
112 AliMonitorHisto::AliMonitorHisto(TH1* histo, ENorm norm) :
113 AliMonitorPlot(histo->GetName(), histo->GetTitle())
115 // create a monitor histogram from the given histogram
117 if (histo->GetDimension() > 2) {
118 Fatal("AliMonitorHisto", "3 dimensional histograms are not supported");
121 histo->SetDirectory(NULL);
126 Bool_t addStatus = TH1::AddDirectoryStatus();
127 TH1::AddDirectory(kFALSE);
128 fHistoRun = (TH1*) histo->Clone();
129 TH1::AddDirectory(addStatus);
132 fHistoCompare = NULL;
136 //_____________________________________________________________________________
137 AliMonitorHisto::~AliMonitorHisto()
139 // delete all histograms
141 if (fHisto) delete fHisto;
143 if (fHistoRun) delete fHistoRun;
144 if (fHistoDraw) delete fHistoDraw;
145 if (fHistoCompare) delete fHistoCompare;
149 //_____________________________________________________________________________
150 void AliMonitorHisto::SetReference(TH1* ref)
152 // set the reference histogram for comparison
154 if (fHistoRef) delete fHistoRef;
155 Bool_t addStatus = TH1::AddDirectoryStatus();
156 TH1::AddDirectory(kFALSE);
157 TH1::AddDirectory(addStatus);
158 fHistoRef = (TH1*) ref->Clone();
159 if (fHistoCompare) fHistoCompare->Reset();
162 //_____________________________________________________________________________
163 void AliMonitorHisto::SetReference(AliMonitorPlot* ref)
165 // set the reference histogram for comparison
167 if (!ref->InheritsFrom(AliMonitorHisto::Class())) return;
168 ((AliMonitorHisto*)ref)->GetRun();
169 SetReference(((AliMonitorHisto*)ref)->fHistoDraw);
173 //_____________________________________________________________________________
174 void AliMonitorHisto::Fill(Axis_t x)
176 // fill the monitor histogram
181 //_____________________________________________________________________________
182 void AliMonitorHisto::Fill(Axis_t x, Axis_t y)
184 // fill the monitor histogram
189 //_____________________________________________________________________________
190 void AliMonitorHisto::Fill(Axis_t x, Axis_t y, Stat_t w)
192 // fill the monitor histogram
194 if (fHisto->InheritsFrom(TH2::Class())) {
195 ((TH2*)fHisto)->Fill(x, y, w);
196 } else if (fHisto->InheritsFrom(TProfile::Class())) {
197 ((TProfile*)fHisto)->Fill(x, y, w);
199 Error("Fill", "trying to fill x and y of a 1 dimensinal histogram");
204 //_____________________________________________________________________________
205 void AliMonitorHisto::ScaleErrorBy(Double_t factor)
207 // multiply the error of each bin by the given factor
210 if (fHisto->GetDimension() > 1)
211 yMax = fHisto->GetYaxis()->GetNbins();
212 Int_t xMax = fHisto->GetXaxis()->GetNbins();
213 for (Int_t iY = 1; iY <= yMax; iY++) {
214 for (Int_t iX = 1; iX <= xMax; iX++) {
215 Int_t iBin = fHisto->GetBin(iX, iY);
216 fHisto->SetBinError(iBin, factor * fHisto->GetBinError(iBin));
222 //_____________________________________________________________________________
223 void AliMonitorHisto::Update()
225 // update the normalized data histogram
231 //_____________________________________________________________________________
232 void AliMonitorHisto::Update(TH1* histo)
234 // update the normalized data histogram using the given histo instead of fHisto
237 while (fNHistos >= fgNHistosMax) {
238 fHistoList.Remove(fHistoList.LastLink());
241 Bool_t addStatus = TH1::AddDirectoryStatus();
242 TH1::AddDirectory(kFALSE);
243 fHistoList.AddFirst(histo->Clone());
244 TH1::AddDirectory(addStatus);
246 fHistoRun->Add(histo);
250 //_____________________________________________________________________________
251 void AliMonitorHisto::Add(AliMonitorPlot* plot)
253 // merge the given histo to this one
255 if (!plot->InheritsFrom(AliMonitorHisto::Class())) return;
256 AliMonitorHisto* histo = (AliMonitorHisto*) plot;
258 fNumberOfEvents += histo->fNumberOfEvents;
259 Bool_t addStatus = TH1::AddDirectoryStatus();
260 TH1::AddDirectory(kFALSE);
261 TObjLink* link = histo->fHistoList.LastLink();
263 fHistoList.AddFirst(link->GetObject()->Clone());
266 TH1::AddDirectory(addStatus);
267 fNHistos += histo->fNHistos;
268 while (fNHistos > fgNHistosMax) {
269 fHistoList.Remove(fHistoList.LastLink());
272 fHistoRun->Add(histo->fHistoRun);
275 //_____________________________________________________________________________
276 void AliMonitorHisto::Reset()
278 // reset the monitor histogram for a new run
284 if (fHistoDraw) delete fHistoDraw;
286 if (fHistoCompare) delete fHistoCompare;
287 fHistoCompare = NULL;
291 //_____________________________________________________________________________
292 void AliMonitorHisto::ResetList()
294 // reset the the list of monitor histograms
301 //_____________________________________________________________________________
302 void AliMonitorHisto::Scale(Int_t nEvents)
304 // scale the histogram to the correct normalization
308 case kNormNone : scale = 1.; break;
309 case kNormEvents : scale = 1./nEvents; break;
310 case kNormEntries : scale = ((fHistoDraw->GetEntries() > 0) ?
311 1./fHistoDraw->GetEntries() : 1.); break;
312 case kNormIntegral: scale = ((fHistoDraw->Integral() > 0) ?
313 1./fHistoDraw->Integral() : 1.); break;
315 fHistoDraw->Scale(scale);
318 //_____________________________________________________________________________
319 Bool_t AliMonitorHisto::ComparePlot()
321 // compare the data histogram to the reference histogram
322 // if they deviate by more than fgThreshold standard deviations in a bin,
323 // this bin is set in fHistoCompare and kFALSE is returned
325 if (!fHistoRef) return kTRUE;
326 if (fgThreshold <= 0) return kTRUE;
328 Info("Compare", "no data histogram available for comparison\ncall DrawEvent, DrawSum or DrawRaw before calling Compare");
331 if (fHistoCompare) delete fHistoCompare;
332 Bool_t addStatus = TH1::AddDirectoryStatus();
333 TH1::AddDirectory(kFALSE);
334 fHistoCompare = (TH1*) fHistoDraw->Clone();
335 TH1::AddDirectory(addStatus);
336 fHistoCompare->Reset();
337 Bool_t result = kTRUE;
340 if (fHistoDraw->GetDimension() > 1)
341 yMax = fHistoDraw->GetYaxis()->GetNbins();
342 Int_t xMax = fHistoDraw->GetXaxis()->GetNbins();
343 for (Int_t iY = 1; iY <= yMax; iY++) {
344 for (Int_t iX = 1; iX <= xMax; iX++) {
345 Int_t iBin = fHistoDraw->GetBin(iX, iY);
346 Double_t delta = TMath::Abs(fHistoDraw->GetBinContent(iBin) -
347 fHistoRef->GetBinContent(iBin));
348 Double_t errorData = fHistoDraw->GetBinError(iBin);
349 Double_t errorRef = fHistoRef->GetBinError(iBin);
350 Double_t sigma = TMath::Sqrt(errorData*errorData + errorRef*errorRef);
351 if (delta > fgThreshold*sigma) {
352 fHistoCompare->SetBinContent(iBin, fHistoDraw->GetBinContent(iBin));
353 fHistoCompare->SetBinError(iBin, errorData);
362 //_____________________________________________________________________________
363 Bool_t AliMonitorHisto::GetEvent(Int_t number)
365 // get the normalized monitor histogram for the "number"th last event
368 Info("GetEvent", "there are no histograms for single events available");
371 if (number > fNHistos) {
372 Error("GetEvent", "requested event number (%d) exceeds range of available events (%d)\n",
376 if (number <= 0) return kFALSE;
378 if (fHistoDraw) delete fHistoDraw;
379 if (fHistoCompare) delete fHistoCompare;
380 fHistoCompare = NULL;
382 TObjLink* link = fHistoList.FirstLink();
383 for (Int_t i = 1; i < number; i++) link = link->Next();
384 Bool_t addStatus = TH1::AddDirectoryStatus();
385 TH1::AddDirectory(kFALSE);
386 fHistoDraw = (TH1*) link->GetObject()->Clone();
387 TH1::AddDirectory(addStatus);
393 //_____________________________________________________________________________
394 Bool_t AliMonitorHisto::GetSum(Int_t number)
396 // get the normalized monitor histogram for the sum of the last
400 Info("GetSum", "there are no histograms for single events available");
403 if (number > fNHistos) {
404 Info("GetSum", "requested number of events (%d) exceeds range of available events (%d)\nusing last %d event(s)",
405 number, fNHistos, fNHistos);
408 if (number <= 0) return kFALSE;
410 if (fHistoDraw) delete fHistoDraw;
411 if (fHistoCompare) delete fHistoCompare;
412 fHistoCompare = NULL;
414 TObjLink* link = fHistoList.FirstLink();
415 Bool_t addStatus = TH1::AddDirectoryStatus();
416 TH1::AddDirectory(kFALSE);
417 fHistoDraw = (TH1*) link->GetObject()->Clone();
418 TH1::AddDirectory(addStatus);
419 for (Int_t i = 1; i < number; i++) {
421 fHistoDraw->Add((TH1*) link->GetObject());
428 //_____________________________________________________________________________
429 Bool_t AliMonitorHisto::GetRun()
431 // get the normalized monitor histogram for all monitored events
432 // of the current run
434 if (fHistoDraw) delete fHistoDraw;
435 if (fHistoCompare) delete fHistoCompare;
436 fHistoCompare = NULL;
438 Bool_t addStatus = TH1::AddDirectoryStatus();
439 TH1::AddDirectory(kFALSE);
440 fHistoDraw = (TH1*) fHistoRun->Clone();
441 TH1::AddDirectory(addStatus);
443 Scale(fNumberOfEvents);
447 //_____________________________________________________________________________
448 void AliMonitorHisto::DrawPlot()
450 // draw the histograms
452 fHistoDraw->SetMarkerColor(fgColorData);
453 fHistoDraw->SetLineColor(fgColorData);
454 fHistoDraw->SetFillColor(fgColorData);
455 fHistoDraw->DrawCopy();
457 if (fHistoRef && fgDrawRef) {
459 sprintf(option, "%sSAME", fHistoDraw->GetOption());
461 if (fHistoRef->GetMaximum() > fHistoDraw->GetMaximum()) {
462 fHistoDraw->SetMaximum(fHistoRef->GetMaximum() * 1.1);
465 fHistoRef->SetMarkerColor(fgColorRef);
466 fHistoRef->SetLineColor(fgColorRef);
467 fHistoRef->SetFillColor(fgColorRef);
468 fHistoRef->DrawCopy(option);
470 fHistoDraw->DrawCopy(option);
472 if (fHistoCompare && (fgThreshold > 0)) {
473 fHistoCompare->SetMarkerColor(fgColorCompare);
474 fHistoCompare->SetLineColor(fgColorCompare);
475 fHistoCompare->SetFillColor(fgColorCompare);
476 fHistoCompare->DrawCopy(option);