corrections to obey coding conventions
[u/mrichter/AliRoot.git] / MONITOR / AliMonitorHisto.cxx
CommitLineData
04fa961a 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/* $Id$ */
17
18///////////////////////////////////////////////////////////////////////////////
19// //
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. //
26// //
27///////////////////////////////////////////////////////////////////////////////
28
29
30#include "AliMonitorHisto.h"
31#include <TProfile.h>
32#include <TH2.h>
33#include <TVirtualPad.h>
34
35
36ClassImp(AliMonitorHisto)
37
38
39Int_t AliMonitorHisto::fgNHistosMax = 10;
40
41
42//_____________________________________________________________________________
43AliMonitorHisto::AliMonitorHisto()
44{
45// default contructor
46
47 fHisto = NULL;
48 fNHistos = 0;
49 fHistoRun = NULL;
50 fHistoDraw = NULL;
51 fHistoRef = NULL;
52 fHistoCompare = NULL;
53 fNorm = kNormNone;
54}
55
56//_____________________________________________________________________________
57AliMonitorHisto::AliMonitorHisto(const AliMonitorHisto& histo) :
58 AliMonitorPlot(histo)
59{
60// copy constructor
61
62 Bool_t addStatus = TH1::AddDirectoryStatus();
63 TH1::AddDirectory(kFALSE);
64 fHisto = NULL;
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());
70 link = link->Next();
71 }
72 fHistoRun = NULL;
73 if (histo.fHistoRun) fHistoRun = (TH1*) histo.fHistoRun->Clone();
74 fHistoDraw = NULL;
75 fHistoRef = NULL;
76 if (histo.fHistoRef) fHistoRef = (TH1*) histo.fHistoRef->Clone();
77 fHistoCompare = NULL;
78 fNorm = histo.fNorm;
79 TH1::AddDirectory(addStatus);
80}
81
c4bd737c 82//_____________________________________________________________________________
83AliMonitorHisto& AliMonitorHisto::operator =(const AliMonitorHisto& histo)
84{
85// assignment operatore
86
87 AliMonitorPlot::operator =(histo);
88
89 Bool_t addStatus = TH1::AddDirectoryStatus();
90 TH1::AddDirectory(kFALSE);
91 fHisto = NULL;
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());
97 link = link->Next();
98 }
99 fHistoRun = NULL;
100 if (histo.fHistoRun) fHistoRun = (TH1*) histo.fHistoRun->Clone();
101 fHistoDraw = NULL;
102 fHistoRef = NULL;
103 if (histo.fHistoRef) fHistoRef = (TH1*) histo.fHistoRef->Clone();
104 fHistoCompare = NULL;
105 fNorm = histo.fNorm;
106 TH1::AddDirectory(addStatus);
107
108 return *this;
109}
110
04fa961a 111//_____________________________________________________________________________
112AliMonitorHisto::AliMonitorHisto(TH1* histo, ENorm norm) :
113 AliMonitorPlot(histo->GetName(), histo->GetTitle())
114{
115// create a monitor histogram from the given histogram
116
117 if (histo->GetDimension() > 2) {
118 Fatal("AliMonitorHisto", "3 dimensional histograms are not supported");
119 }
120
121 histo->SetDirectory(NULL);
122 histo->Reset();
123 fHisto = histo;
124 fHisto->Sumw2();
125 fNHistos = 0;
126 Bool_t addStatus = TH1::AddDirectoryStatus();
127 TH1::AddDirectory(kFALSE);
128 fHistoRun = (TH1*) histo->Clone();
129 TH1::AddDirectory(addStatus);
130 fHistoDraw = NULL;
131 fHistoRef = NULL;
132 fHistoCompare = NULL;
133 fNorm = norm;
134}
135
136//_____________________________________________________________________________
137AliMonitorHisto::~AliMonitorHisto()
138{
139// delete all histograms
140
141 if (fHisto) delete fHisto;
142 fHistoList.Delete();
143 if (fHistoRun) delete fHistoRun;
144 if (fHistoDraw) delete fHistoDraw;
145 if (fHistoCompare) delete fHistoCompare;
146}
147
148
149//_____________________________________________________________________________
150void AliMonitorHisto::SetReference(TH1* ref)
151{
152// set the reference histogram for comparison
153
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();
160}
161
162//_____________________________________________________________________________
163void AliMonitorHisto::SetReference(AliMonitorPlot* ref)
164{
165// set the reference histogram for comparison
166
167 if (!ref->InheritsFrom(AliMonitorHisto::Class())) return;
168 ((AliMonitorHisto*)ref)->GetRun();
169 SetReference(((AliMonitorHisto*)ref)->fHistoDraw);
170}
171
172
173//_____________________________________________________________________________
174void AliMonitorHisto::Fill(Axis_t x)
175{
176// fill the monitor histogram
177
178 fHisto->Fill(x);
179}
180
181//_____________________________________________________________________________
182void AliMonitorHisto::Fill(Axis_t x, Axis_t y)
183{
184// fill the monitor histogram
185
186 fHisto->Fill(x, y);
187}
188
189//_____________________________________________________________________________
190void AliMonitorHisto::Fill(Axis_t x, Axis_t y, Stat_t w)
191{
192// fill the monitor histogram
193
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);
198 } else {
199 Error("Fill", "trying to fill x and y of a 1 dimensinal histogram");
200 return;
201 }
202}
203
204//_____________________________________________________________________________
205void AliMonitorHisto::ScaleErrorBy(Double_t factor)
206{
207// multiply the error of each bin by the given factor
208
209 Int_t yMax = 1;
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));
217 }
218 }
219}
220
221
222//_____________________________________________________________________________
223void AliMonitorHisto::Update()
224{
225// update the normalized data histogram
226
227 Update(fHisto);
228 fHisto->Reset();
229}
230
231//_____________________________________________________________________________
232void AliMonitorHisto::Update(TH1* histo)
233{
234// update the normalized data histogram using the given histo instead of fHisto
235
236 fNumberOfEvents++;
237 while (fNHistos >= fgNHistosMax) {
238 fHistoList.Remove(fHistoList.LastLink());
239 fNHistos--;
240 }
241 Bool_t addStatus = TH1::AddDirectoryStatus();
242 TH1::AddDirectory(kFALSE);
243 fHistoList.AddFirst(histo->Clone());
244 TH1::AddDirectory(addStatus);
245 fNHistos++;
246 fHistoRun->Add(histo);
247 fHisto->Reset();
248}
249
250//_____________________________________________________________________________
251void AliMonitorHisto::Add(AliMonitorPlot* plot)
252{
253// merge the given histo to this one
254
255 if (!plot->InheritsFrom(AliMonitorHisto::Class())) return;
256 AliMonitorHisto* histo = (AliMonitorHisto*) plot;
257
258 fNumberOfEvents += histo->fNumberOfEvents;
259 Bool_t addStatus = TH1::AddDirectoryStatus();
260 TH1::AddDirectory(kFALSE);
261 TObjLink* link = histo->fHistoList.LastLink();
262 while (link) {
263 fHistoList.AddFirst(link->GetObject()->Clone());
264 link = link->Prev();
265 }
266 TH1::AddDirectory(addStatus);
267 fNHistos += histo->fNHistos;
268 while (fNHistos > fgNHistosMax) {
269 fHistoList.Remove(fHistoList.LastLink());
270 fNHistos--;
271 }
272 fHistoRun->Add(histo->fHistoRun);
273}
274
275//_____________________________________________________________________________
276void AliMonitorHisto::Reset()
277{
278// reset the monitor histogram for a new run
279
280 fHisto->Reset();
281 fHistoList.Delete();
282 fNHistos = 0;
283 fHistoRun->Reset();
284 if (fHistoDraw) delete fHistoDraw;
285 fHistoDraw = NULL;
286 if (fHistoCompare) delete fHistoCompare;
287 fHistoCompare = NULL;
288 fNumberOfEvents = 0;
289}
290
291//_____________________________________________________________________________
292void AliMonitorHisto::ResetList()
293{
294// reset the the list of monitor histograms
295
296 fHistoList.Delete();
297 fNHistos = 0;
298}
299
300
301//_____________________________________________________________________________
302void AliMonitorHisto::Scale(Int_t nEvents)
303{
304// scale the histogram to the correct normalization
305
306 Double_t scale = 1.;
307 switch (fNorm) {
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;
314 }
315 fHistoDraw->Scale(scale);
316}
317
318//_____________________________________________________________________________
319Bool_t AliMonitorHisto::ComparePlot()
320{
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
324
325 if (!fHistoRef) return kTRUE;
326 if (fgThreshold <= 0) return kTRUE;
327 if (!fHistoDraw) {
328 Info("Compare", "no data histogram available for comparison\ncall DrawEvent, DrawSum or DrawRaw before calling Compare");
329 return kTRUE;
330 }
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;
338
339 Int_t yMax = 1;
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);
354 result = kFALSE;
355 }
356 }
357 }
358
359 return result;
360}
361
362//_____________________________________________________________________________
363Bool_t AliMonitorHisto::GetEvent(Int_t number)
364{
365// get the normalized monitor histogram for the "number"th last event
366
367 if (fNHistos == 0) {
368 Info("GetEvent", "there are no histograms for single events available");
369 return kFALSE;
370 }
371 if (number > fNHistos) {
372 Error("GetEvent", "requested event number (%d) exceeds range of available events (%d)\n",
373 number, fNHistos);
374 return kFALSE;
375 }
376 if (number <= 0) return kFALSE;
377
378 if (fHistoDraw) delete fHistoDraw;
379 if (fHistoCompare) delete fHistoCompare;
380 fHistoCompare = NULL;
381
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);
388
389 Scale(1);
390 return kTRUE;
391}
392
393//_____________________________________________________________________________
394Bool_t AliMonitorHisto::GetSum(Int_t number)
395{
396// get the normalized monitor histogram for the sum of the last
397// "number" events
398
399 if (fNHistos == 0) {
400 Info("GetSum", "there are no histograms for single events available");
401 return kFALSE;
402 }
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);
406 number = fNHistos;
407 }
408 if (number <= 0) return kFALSE;
409
410 if (fHistoDraw) delete fHistoDraw;
411 if (fHistoCompare) delete fHistoCompare;
412 fHistoCompare = NULL;
413
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++) {
420 link = link->Next();
421 fHistoDraw->Add((TH1*) link->GetObject());
422 }
423
424 Scale(number);
425 return kTRUE;
426}
427
428//_____________________________________________________________________________
429Bool_t AliMonitorHisto::GetRun()
430{
431// get the normalized monitor histogram for all monitored events
432// of the current run
433
434 if (fHistoDraw) delete fHistoDraw;
435 if (fHistoCompare) delete fHistoCompare;
436 fHistoCompare = NULL;
437
438 Bool_t addStatus = TH1::AddDirectoryStatus();
439 TH1::AddDirectory(kFALSE);
440 fHistoDraw = (TH1*) fHistoRun->Clone();
441 TH1::AddDirectory(addStatus);
442
443 Scale(fNumberOfEvents);
444 return kTRUE;
445}
446
447//_____________________________________________________________________________
448void AliMonitorHisto::DrawPlot()
449{
450// draw the histograms
451
452 fHistoDraw->SetMarkerColor(fgColorData);
453 fHistoDraw->SetLineColor(fgColorData);
454 fHistoDraw->SetFillColor(fgColorData);
455 fHistoDraw->DrawCopy();
456
457 if (fHistoRef && fgDrawRef) {
458 char option[256];
459 sprintf(option, "%sSAME", fHistoDraw->GetOption());
460
461 if (fHistoRef->GetMaximum() > fHistoDraw->GetMaximum()) {
462 fHistoDraw->SetMaximum(fHistoRef->GetMaximum() * 1.1);
463 }
464
465 fHistoRef->SetMarkerColor(fgColorRef);
466 fHistoRef->SetLineColor(fgColorRef);
467 fHistoRef->SetFillColor(fgColorRef);
468 fHistoRef->DrawCopy(option);
469
470 fHistoDraw->DrawCopy(option);
471
472 if (fHistoCompare && (fgThreshold > 0)) {
473 fHistoCompare->SetMarkerColor(fgColorCompare);
474 fHistoCompare->SetLineColor(fgColorCompare);
475 fHistoCompare->SetFillColor(fgColorCompare);
476 fHistoCompare->DrawCopy(option);
477 }
478 }
479
480 gPad->Update();
481}