Small fix (Mikolaj)
[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
04fa961a 30#include <TH2.h>
9edefa04 31#include <TMath.h>
32#include <TProfile.h>
04fa961a 33#include <TVirtualPad.h>
34
7ba8900c 35#include "AliLog.h"
36
37#include "AliMonitorHisto.h"
38
04fa961a 39
40ClassImp(AliMonitorHisto)
41
42
43Int_t AliMonitorHisto::fgNHistosMax = 10;
44
45
46//_____________________________________________________________________________
17c3cc9e 47AliMonitorHisto::AliMonitorHisto() :
48 AliMonitorPlot(),
49 fHisto(NULL),
50 fHistoList(),
51 fNHistos(0),
52 fHistoRun(NULL),
53 fHistoDraw(NULL),
54 fHistoRef(NULL),
55 fHistoCompare(NULL),
56 fNorm(kNormNone)
04fa961a 57{
58// default contructor
59
04fa961a 60}
61
62//_____________________________________________________________________________
63AliMonitorHisto::AliMonitorHisto(const AliMonitorHisto& histo) :
17c3cc9e 64 AliMonitorPlot(histo),
65 fHisto(NULL),
66 fHistoList(),
67 fNHistos(histo.fNHistos),
68 fHistoRun(NULL),
69 fHistoDraw(NULL),
70 fHistoRef(NULL),
71 fHistoCompare(NULL),
72 fNorm(histo.fNorm)
04fa961a 73{
74// copy constructor
75
76 Bool_t addStatus = TH1::AddDirectoryStatus();
77 TH1::AddDirectory(kFALSE);
04fa961a 78 if (histo.fHisto) fHisto = (TH1*) histo.fHisto->Clone();
04fa961a 79 TObjLink* link = histo.fHistoList.FirstLink();
80 for (Int_t i = 0; i < fNHistos; i++) {
81 fHistoList.Add(link->GetObject()->Clone());
82 link = link->Next();
83 }
04fa961a 84 if (histo.fHistoRun) fHistoRun = (TH1*) histo.fHistoRun->Clone();
04fa961a 85 if (histo.fHistoRef) fHistoRef = (TH1*) histo.fHistoRef->Clone();
04fa961a 86 TH1::AddDirectory(addStatus);
87}
88
89//_____________________________________________________________________________
c4bd737c 90AliMonitorHisto& AliMonitorHisto::operator =(const AliMonitorHisto& histo)
91{
c6ba6205 92// assignment operator
c4bd737c 93
94 AliMonitorPlot::operator =(histo);
95
96 Bool_t addStatus = TH1::AddDirectoryStatus();
97 TH1::AddDirectory(kFALSE);
98 fHisto = NULL;
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());
104 link = link->Next();
105 }
106 fHistoRun = NULL;
107 if (histo.fHistoRun) fHistoRun = (TH1*) histo.fHistoRun->Clone();
108 fHistoDraw = NULL;
109 fHistoRef = NULL;
110 if (histo.fHistoRef) fHistoRef = (TH1*) histo.fHistoRef->Clone();
111 fHistoCompare = NULL;
112 fNorm = histo.fNorm;
113 TH1::AddDirectory(addStatus);
114
115 return *this;
116}
117
118//_____________________________________________________________________________
04fa961a 119AliMonitorHisto::AliMonitorHisto(TH1* histo, ENorm norm) :
17c3cc9e 120 AliMonitorPlot(histo->GetName(), histo->GetTitle()),
121 fHisto(histo),
122 fHistoList(),
123 fNHistos(0),
124 fHistoRun(NULL),
125 fHistoDraw(NULL),
126 fHistoRef(NULL),
127 fHistoCompare(NULL),
128 fNorm(norm)
04fa961a 129{
130// create a monitor histogram from the given histogram
131
132 if (histo->GetDimension() > 2) {
7ba8900c 133 AliFatal("3 dimensional histograms are not supported");
04fa961a 134 }
135
136 histo->SetDirectory(NULL);
137 histo->Reset();
04fa961a 138 fHisto->Sumw2();
04fa961a 139 Bool_t addStatus = TH1::AddDirectoryStatus();
140 TH1::AddDirectory(kFALSE);
141 fHistoRun = (TH1*) histo->Clone();
142 TH1::AddDirectory(addStatus);
04fa961a 143}
144
145//_____________________________________________________________________________
146AliMonitorHisto::~AliMonitorHisto()
147{
148// delete all histograms
149
150 if (fHisto) delete fHisto;
151 fHistoList.Delete();
152 if (fHistoRun) delete fHistoRun;
153 if (fHistoDraw) delete fHistoDraw;
154 if (fHistoCompare) delete fHistoCompare;
155}
156
157
158//_____________________________________________________________________________
159void AliMonitorHisto::SetReference(TH1* ref)
160{
161// set the reference histogram for comparison
162
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();
169}
170
171//_____________________________________________________________________________
172void AliMonitorHisto::SetReference(AliMonitorPlot* ref)
173{
174// set the reference histogram for comparison
175
176 if (!ref->InheritsFrom(AliMonitorHisto::Class())) return;
177 ((AliMonitorHisto*)ref)->GetRun();
178 SetReference(((AliMonitorHisto*)ref)->fHistoDraw);
179}
180
181
182//_____________________________________________________________________________
183void AliMonitorHisto::Fill(Axis_t x)
184{
185// fill the monitor histogram
186
187 fHisto->Fill(x);
188}
189
190//_____________________________________________________________________________
191void AliMonitorHisto::Fill(Axis_t x, Axis_t y)
192{
193// fill the monitor histogram
194
195 fHisto->Fill(x, y);
196}
197
198//_____________________________________________________________________________
199void AliMonitorHisto::Fill(Axis_t x, Axis_t y, Stat_t w)
200{
201// fill the monitor histogram
202
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);
207 } else {
7ba8900c 208 AliError("trying to fill x and y of a 1 dimensinal histogram");
04fa961a 209 return;
210 }
211}
212
213//_____________________________________________________________________________
214void AliMonitorHisto::ScaleErrorBy(Double_t factor)
215{
216// multiply the error of each bin by the given factor
217
218 Int_t yMax = 1;
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));
226 }
227 }
228}
229
230
231//_____________________________________________________________________________
232void AliMonitorHisto::Update()
233{
234// update the normalized data histogram
235
236 Update(fHisto);
237 fHisto->Reset();
238}
239
240//_____________________________________________________________________________
241void AliMonitorHisto::Update(TH1* histo)
242{
243// update the normalized data histogram using the given histo instead of fHisto
244
245 fNumberOfEvents++;
246 while (fNHistos >= fgNHistosMax) {
247 fHistoList.Remove(fHistoList.LastLink());
248 fNHistos--;
249 }
250 Bool_t addStatus = TH1::AddDirectoryStatus();
251 TH1::AddDirectory(kFALSE);
252 fHistoList.AddFirst(histo->Clone());
253 TH1::AddDirectory(addStatus);
254 fNHistos++;
255 fHistoRun->Add(histo);
256 fHisto->Reset();
257}
258
259//_____________________________________________________________________________
260void AliMonitorHisto::Add(AliMonitorPlot* plot)
261{
262// merge the given histo to this one
263
264 if (!plot->InheritsFrom(AliMonitorHisto::Class())) return;
265 AliMonitorHisto* histo = (AliMonitorHisto*) plot;
266
267 fNumberOfEvents += histo->fNumberOfEvents;
268 Bool_t addStatus = TH1::AddDirectoryStatus();
269 TH1::AddDirectory(kFALSE);
270 TObjLink* link = histo->fHistoList.LastLink();
271 while (link) {
272 fHistoList.AddFirst(link->GetObject()->Clone());
273 link = link->Prev();
274 }
275 TH1::AddDirectory(addStatus);
276 fNHistos += histo->fNHistos;
277 while (fNHistos > fgNHistosMax) {
278 fHistoList.Remove(fHistoList.LastLink());
279 fNHistos--;
280 }
281 fHistoRun->Add(histo->fHistoRun);
282}
283
284//_____________________________________________________________________________
285void AliMonitorHisto::Reset()
286{
287// reset the monitor histogram for a new run
288
289 fHisto->Reset();
290 fHistoList.Delete();
291 fNHistos = 0;
292 fHistoRun->Reset();
293 if (fHistoDraw) delete fHistoDraw;
294 fHistoDraw = NULL;
295 if (fHistoCompare) delete fHistoCompare;
296 fHistoCompare = NULL;
297 fNumberOfEvents = 0;
298}
299
300//_____________________________________________________________________________
301void AliMonitorHisto::ResetList()
302{
303// reset the the list of monitor histograms
304
305 fHistoList.Delete();
306 fNHistos = 0;
307}
308
309
310//_____________________________________________________________________________
311void AliMonitorHisto::Scale(Int_t nEvents)
312{
313// scale the histogram to the correct normalization
314
315 Double_t scale = 1.;
316 switch (fNorm) {
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;
323 }
324 fHistoDraw->Scale(scale);
325}
326
327//_____________________________________________________________________________
328Bool_t AliMonitorHisto::ComparePlot()
329{
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
333
334 if (!fHistoRef) return kTRUE;
335 if (fgThreshold <= 0) return kTRUE;
336 if (!fHistoDraw) {
7ba8900c 337 AliWarning("no data histogram available for comparison\ncall DrawEvent, DrawSum or DrawRaw before calling Compare");
04fa961a 338 return kTRUE;
339 }
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;
347
348 Int_t yMax = 1;
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);
363 result = kFALSE;
364 }
365 }
366 }
367
368 return result;
369}
370
371//_____________________________________________________________________________
372Bool_t AliMonitorHisto::GetEvent(Int_t number)
373{
374// get the normalized monitor histogram for the "number"th last event
375
376 if (fNHistos == 0) {
7ba8900c 377 AliWarning("there are no histograms for single events available");
04fa961a 378 return kFALSE;
379 }
380 if (number > fNHistos) {
7ba8900c 381 AliError(Form("requested event number (%d) exceeds range of available events (%d)",
382 number, fNHistos));
04fa961a 383 return kFALSE;
384 }
385 if (number <= 0) return kFALSE;
386
387 if (fHistoDraw) delete fHistoDraw;
388 if (fHistoCompare) delete fHistoCompare;
389 fHistoCompare = NULL;
390
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);
397
398 Scale(1);
399 return kTRUE;
400}
401
402//_____________________________________________________________________________
403Bool_t AliMonitorHisto::GetSum(Int_t number)
404{
405// get the normalized monitor histogram for the sum of the last
406// "number" events
407
408 if (fNHistos == 0) {
7ba8900c 409 AliWarning("there are no histograms for single events available");
04fa961a 410 return kFALSE;
411 }
412 if (number > fNHistos) {
7ba8900c 413 AliError(Form("requested number of events (%d) exceeds range of available events (%d)\nusing last %d event(s)",
414 number, fNHistos, fNHistos));
04fa961a 415 number = fNHistos;
416 }
417 if (number <= 0) return kFALSE;
418
419 if (fHistoDraw) delete fHistoDraw;
420 if (fHistoCompare) delete fHistoCompare;
421 fHistoCompare = NULL;
422
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++) {
429 link = link->Next();
430 fHistoDraw->Add((TH1*) link->GetObject());
431 }
432
433 Scale(number);
434 return kTRUE;
435}
436
437//_____________________________________________________________________________
438Bool_t AliMonitorHisto::GetRun()
439{
440// get the normalized monitor histogram for all monitored events
441// of the current run
442
443 if (fHistoDraw) delete fHistoDraw;
444 if (fHistoCompare) delete fHistoCompare;
445 fHistoCompare = NULL;
446
447 Bool_t addStatus = TH1::AddDirectoryStatus();
448 TH1::AddDirectory(kFALSE);
449 fHistoDraw = (TH1*) fHistoRun->Clone();
450 TH1::AddDirectory(addStatus);
451
452 Scale(fNumberOfEvents);
453 return kTRUE;
454}
455
456//_____________________________________________________________________________
457void AliMonitorHisto::DrawPlot()
458{
459// draw the histograms
460
461 fHistoDraw->SetMarkerColor(fgColorData);
462 fHistoDraw->SetLineColor(fgColorData);
463 fHistoDraw->SetFillColor(fgColorData);
464 fHistoDraw->DrawCopy();
465
466 if (fHistoRef && fgDrawRef) {
467 char option[256];
468 sprintf(option, "%sSAME", fHistoDraw->GetOption());
469
470 if (fHistoRef->GetMaximum() > fHistoDraw->GetMaximum()) {
471 fHistoDraw->SetMaximum(fHistoRef->GetMaximum() * 1.1);
472 }
473
474 fHistoRef->SetMarkerColor(fgColorRef);
475 fHistoRef->SetLineColor(fgColorRef);
476 fHistoRef->SetFillColor(fgColorRef);
477 fHistoRef->DrawCopy(option);
478
479 fHistoDraw->DrawCopy(option);
480
481 if (fHistoCompare && (fgThreshold > 0)) {
482 fHistoCompare->SetMarkerColor(fgColorCompare);
483 fHistoCompare->SetLineColor(fgColorCompare);
484 fHistoCompare->SetFillColor(fgColorCompare);
485 fHistoCompare->DrawCopy(option);
486 }
487 }
488
489 gPad->Update();
490}