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(TH1* histo, ENorm norm) :
84 AliMonitorPlot(histo->GetName(), histo->GetTitle())
86 // create a monitor histogram from the given histogram
88 if (histo->GetDimension() > 2) {
89 Fatal("AliMonitorHisto", "3 dimensional histograms are not supported");
92 histo->SetDirectory(NULL);
97 Bool_t addStatus = TH1::AddDirectoryStatus();
98 TH1::AddDirectory(kFALSE);
99 fHistoRun = (TH1*) histo->Clone();
100 TH1::AddDirectory(addStatus);
103 fHistoCompare = NULL;
107 //_____________________________________________________________________________
108 AliMonitorHisto::~AliMonitorHisto()
110 // delete all histograms
112 if (fHisto) delete fHisto;
114 if (fHistoRun) delete fHistoRun;
115 if (fHistoDraw) delete fHistoDraw;
116 if (fHistoCompare) delete fHistoCompare;
120 //_____________________________________________________________________________
121 void AliMonitorHisto::SetReference(TH1* ref)
123 // set the reference histogram for comparison
125 if (fHistoRef) delete fHistoRef;
126 Bool_t addStatus = TH1::AddDirectoryStatus();
127 TH1::AddDirectory(kFALSE);
128 TH1::AddDirectory(addStatus);
129 fHistoRef = (TH1*) ref->Clone();
130 if (fHistoCompare) fHistoCompare->Reset();
133 //_____________________________________________________________________________
134 void AliMonitorHisto::SetReference(AliMonitorPlot* ref)
136 // set the reference histogram for comparison
138 if (!ref->InheritsFrom(AliMonitorHisto::Class())) return;
139 ((AliMonitorHisto*)ref)->GetRun();
140 SetReference(((AliMonitorHisto*)ref)->fHistoDraw);
144 //_____________________________________________________________________________
145 void AliMonitorHisto::Fill(Axis_t x)
147 // fill the monitor histogram
152 //_____________________________________________________________________________
153 void AliMonitorHisto::Fill(Axis_t x, Axis_t y)
155 // fill the monitor histogram
160 //_____________________________________________________________________________
161 void AliMonitorHisto::Fill(Axis_t x, Axis_t y, Stat_t w)
163 // fill the monitor histogram
165 if (fHisto->InheritsFrom(TH2::Class())) {
166 ((TH2*)fHisto)->Fill(x, y, w);
167 } else if (fHisto->InheritsFrom(TProfile::Class())) {
168 ((TProfile*)fHisto)->Fill(x, y, w);
170 Error("Fill", "trying to fill x and y of a 1 dimensinal histogram");
175 //_____________________________________________________________________________
176 void AliMonitorHisto::ScaleErrorBy(Double_t factor)
178 // multiply the error of each bin by the given factor
181 if (fHisto->GetDimension() > 1)
182 yMax = fHisto->GetYaxis()->GetNbins();
183 Int_t xMax = fHisto->GetXaxis()->GetNbins();
184 for (Int_t iY = 1; iY <= yMax; iY++) {
185 for (Int_t iX = 1; iX <= xMax; iX++) {
186 Int_t iBin = fHisto->GetBin(iX, iY);
187 fHisto->SetBinError(iBin, factor * fHisto->GetBinError(iBin));
193 //_____________________________________________________________________________
194 void AliMonitorHisto::Update()
196 // update the normalized data histogram
202 //_____________________________________________________________________________
203 void AliMonitorHisto::Update(TH1* histo)
205 // update the normalized data histogram using the given histo instead of fHisto
208 while (fNHistos >= fgNHistosMax) {
209 fHistoList.Remove(fHistoList.LastLink());
212 Bool_t addStatus = TH1::AddDirectoryStatus();
213 TH1::AddDirectory(kFALSE);
214 fHistoList.AddFirst(histo->Clone());
215 TH1::AddDirectory(addStatus);
217 fHistoRun->Add(histo);
221 //_____________________________________________________________________________
222 void AliMonitorHisto::Add(AliMonitorPlot* plot)
224 // merge the given histo to this one
226 if (!plot->InheritsFrom(AliMonitorHisto::Class())) return;
227 AliMonitorHisto* histo = (AliMonitorHisto*) plot;
229 fNumberOfEvents += histo->fNumberOfEvents;
230 Bool_t addStatus = TH1::AddDirectoryStatus();
231 TH1::AddDirectory(kFALSE);
232 TObjLink* link = histo->fHistoList.LastLink();
234 fHistoList.AddFirst(link->GetObject()->Clone());
237 TH1::AddDirectory(addStatus);
238 fNHistos += histo->fNHistos;
239 while (fNHistos > fgNHistosMax) {
240 fHistoList.Remove(fHistoList.LastLink());
243 fHistoRun->Add(histo->fHistoRun);
246 //_____________________________________________________________________________
247 void AliMonitorHisto::Reset()
249 // reset the monitor histogram for a new run
255 if (fHistoDraw) delete fHistoDraw;
257 if (fHistoCompare) delete fHistoCompare;
258 fHistoCompare = NULL;
262 //_____________________________________________________________________________
263 void AliMonitorHisto::ResetList()
265 // reset the the list of monitor histograms
272 //_____________________________________________________________________________
273 void AliMonitorHisto::Scale(Int_t nEvents)
275 // scale the histogram to the correct normalization
279 case kNormNone : scale = 1.; break;
280 case kNormEvents : scale = 1./nEvents; break;
281 case kNormEntries : scale = ((fHistoDraw->GetEntries() > 0) ?
282 1./fHistoDraw->GetEntries() : 1.); break;
283 case kNormIntegral: scale = ((fHistoDraw->Integral() > 0) ?
284 1./fHistoDraw->Integral() : 1.); break;
286 fHistoDraw->Scale(scale);
289 //_____________________________________________________________________________
290 Bool_t AliMonitorHisto::ComparePlot()
292 // compare the data histogram to the reference histogram
293 // if they deviate by more than fgThreshold standard deviations in a bin,
294 // this bin is set in fHistoCompare and kFALSE is returned
296 if (!fHistoRef) return kTRUE;
297 if (fgThreshold <= 0) return kTRUE;
299 Info("Compare", "no data histogram available for comparison\ncall DrawEvent, DrawSum or DrawRaw before calling Compare");
302 if (fHistoCompare) delete fHistoCompare;
303 Bool_t addStatus = TH1::AddDirectoryStatus();
304 TH1::AddDirectory(kFALSE);
305 fHistoCompare = (TH1*) fHistoDraw->Clone();
306 TH1::AddDirectory(addStatus);
307 fHistoCompare->Reset();
308 Bool_t result = kTRUE;
311 if (fHistoDraw->GetDimension() > 1)
312 yMax = fHistoDraw->GetYaxis()->GetNbins();
313 Int_t xMax = fHistoDraw->GetXaxis()->GetNbins();
314 for (Int_t iY = 1; iY <= yMax; iY++) {
315 for (Int_t iX = 1; iX <= xMax; iX++) {
316 Int_t iBin = fHistoDraw->GetBin(iX, iY);
317 Double_t delta = TMath::Abs(fHistoDraw->GetBinContent(iBin) -
318 fHistoRef->GetBinContent(iBin));
319 Double_t errorData = fHistoDraw->GetBinError(iBin);
320 Double_t errorRef = fHistoRef->GetBinError(iBin);
321 Double_t sigma = TMath::Sqrt(errorData*errorData + errorRef*errorRef);
322 if (delta > fgThreshold*sigma) {
323 fHistoCompare->SetBinContent(iBin, fHistoDraw->GetBinContent(iBin));
324 fHistoCompare->SetBinError(iBin, errorData);
333 //_____________________________________________________________________________
334 Bool_t AliMonitorHisto::GetEvent(Int_t number)
336 // get the normalized monitor histogram for the "number"th last event
339 Info("GetEvent", "there are no histograms for single events available");
342 if (number > fNHistos) {
343 Error("GetEvent", "requested event number (%d) exceeds range of available events (%d)\n",
347 if (number <= 0) return kFALSE;
349 if (fHistoDraw) delete fHistoDraw;
350 if (fHistoCompare) delete fHistoCompare;
351 fHistoCompare = NULL;
353 TObjLink* link = fHistoList.FirstLink();
354 for (Int_t i = 1; i < number; i++) link = link->Next();
355 Bool_t addStatus = TH1::AddDirectoryStatus();
356 TH1::AddDirectory(kFALSE);
357 fHistoDraw = (TH1*) link->GetObject()->Clone();
358 TH1::AddDirectory(addStatus);
364 //_____________________________________________________________________________
365 Bool_t AliMonitorHisto::GetSum(Int_t number)
367 // get the normalized monitor histogram for the sum of the last
371 Info("GetSum", "there are no histograms for single events available");
374 if (number > fNHistos) {
375 Info("GetSum", "requested number of events (%d) exceeds range of available events (%d)\nusing last %d event(s)",
376 number, fNHistos, fNHistos);
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 Bool_t addStatus = TH1::AddDirectoryStatus();
387 TH1::AddDirectory(kFALSE);
388 fHistoDraw = (TH1*) link->GetObject()->Clone();
389 TH1::AddDirectory(addStatus);
390 for (Int_t i = 1; i < number; i++) {
392 fHistoDraw->Add((TH1*) link->GetObject());
399 //_____________________________________________________________________________
400 Bool_t AliMonitorHisto::GetRun()
402 // get the normalized monitor histogram for all monitored events
403 // of the current run
405 if (fHistoDraw) delete fHistoDraw;
406 if (fHistoCompare) delete fHistoCompare;
407 fHistoCompare = NULL;
409 Bool_t addStatus = TH1::AddDirectoryStatus();
410 TH1::AddDirectory(kFALSE);
411 fHistoDraw = (TH1*) fHistoRun->Clone();
412 TH1::AddDirectory(addStatus);
414 Scale(fNumberOfEvents);
418 //_____________________________________________________________________________
419 void AliMonitorHisto::DrawPlot()
421 // draw the histograms
423 fHistoDraw->SetMarkerColor(fgColorData);
424 fHistoDraw->SetLineColor(fgColorData);
425 fHistoDraw->SetFillColor(fgColorData);
426 fHistoDraw->DrawCopy();
428 if (fHistoRef && fgDrawRef) {
430 sprintf(option, "%sSAME", fHistoDraw->GetOption());
432 if (fHistoRef->GetMaximum() > fHistoDraw->GetMaximum()) {
433 fHistoDraw->SetMaximum(fHistoRef->GetMaximum() * 1.1);
436 fHistoRef->SetMarkerColor(fgColorRef);
437 fHistoRef->SetLineColor(fgColorRef);
438 fHistoRef->SetFillColor(fgColorRef);
439 fHistoRef->DrawCopy(option);
441 fHistoDraw->DrawCopy(option);
443 if (fHistoCompare && (fgThreshold > 0)) {
444 fHistoCompare->SetMarkerColor(fgColorCompare);
445 fHistoCompare->SetLineColor(fgColorCompare);
446 fHistoCompare->SetFillColor(fgColorCompare);
447 fHistoCompare->DrawCopy(option);