]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MONITOR/AliMonitorHisto.cxx
Classes for reading raw data moved to the RAW module. New on-line MONITORING module...
[u/mrichter/AliRoot.git] / MONITOR / AliMonitorHisto.cxx
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
36 ClassImp(AliMonitorHisto) 
37
38
39 Int_t   AliMonitorHisto::fgNHistosMax = 10;
40
41
42 //_____________________________________________________________________________
43 AliMonitorHisto::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 //_____________________________________________________________________________
57 AliMonitorHisto::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
82 //_____________________________________________________________________________
83 AliMonitorHisto::AliMonitorHisto(TH1* histo, ENorm norm) :
84   AliMonitorPlot(histo->GetName(), histo->GetTitle())
85 {
86 // create a monitor histogram from the given histogram
87
88   if (histo->GetDimension() > 2) {
89     Fatal("AliMonitorHisto", "3 dimensional histograms are not supported");
90   }
91
92   histo->SetDirectory(NULL);
93   histo->Reset();
94   fHisto = histo;
95   fHisto->Sumw2();
96   fNHistos = 0;
97   Bool_t addStatus = TH1::AddDirectoryStatus();
98   TH1::AddDirectory(kFALSE);
99   fHistoRun = (TH1*) histo->Clone();
100   TH1::AddDirectory(addStatus);
101   fHistoDraw = NULL;
102   fHistoRef = NULL;
103   fHistoCompare = NULL;
104   fNorm = norm;
105 }
106
107 //_____________________________________________________________________________
108 AliMonitorHisto::~AliMonitorHisto()
109 {
110 // delete all histograms
111
112   if (fHisto) delete fHisto;
113   fHistoList.Delete();
114   if (fHistoRun) delete fHistoRun;
115   if (fHistoDraw) delete fHistoDraw;
116   if (fHistoCompare) delete fHistoCompare;
117 }
118
119
120 //_____________________________________________________________________________
121 void AliMonitorHisto::SetReference(TH1* ref)
122 {
123 // set the reference histogram for comparison
124
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();
131 }
132
133 //_____________________________________________________________________________
134 void AliMonitorHisto::SetReference(AliMonitorPlot* ref)
135 {
136 // set the reference histogram for comparison
137
138   if (!ref->InheritsFrom(AliMonitorHisto::Class())) return;
139   ((AliMonitorHisto*)ref)->GetRun();
140   SetReference(((AliMonitorHisto*)ref)->fHistoDraw);
141 }
142
143
144 //_____________________________________________________________________________
145 void AliMonitorHisto::Fill(Axis_t x)
146 {
147 // fill the monitor histogram
148
149   fHisto->Fill(x);
150 }
151
152 //_____________________________________________________________________________
153 void AliMonitorHisto::Fill(Axis_t x, Axis_t y)
154 {
155 // fill the monitor histogram
156
157   fHisto->Fill(x, y);
158 }
159
160 //_____________________________________________________________________________
161 void AliMonitorHisto::Fill(Axis_t x, Axis_t y, Stat_t w)
162 {
163 // fill the monitor histogram
164
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);
169   } else {
170     Error("Fill", "trying to fill x and y of a 1 dimensinal histogram");
171     return;
172   }
173 }
174
175 //_____________________________________________________________________________
176 void AliMonitorHisto::ScaleErrorBy(Double_t factor)
177 {
178 // multiply the error of each bin by the given factor
179
180   Int_t yMax = 1; 
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));
188     }
189   }
190 }
191
192
193 //_____________________________________________________________________________
194 void AliMonitorHisto::Update()
195 {
196 // update the normalized data histogram
197
198   Update(fHisto);
199   fHisto->Reset();
200 }
201
202 //_____________________________________________________________________________
203 void AliMonitorHisto::Update(TH1* histo)
204 {
205 // update the normalized data histogram using the given histo instead of fHisto
206
207   fNumberOfEvents++;
208   while (fNHistos >= fgNHistosMax) {
209     fHistoList.Remove(fHistoList.LastLink());
210     fNHistos--;
211   }
212   Bool_t addStatus = TH1::AddDirectoryStatus();
213   TH1::AddDirectory(kFALSE);
214   fHistoList.AddFirst(histo->Clone());
215   TH1::AddDirectory(addStatus);
216   fNHistos++;
217   fHistoRun->Add(histo);
218   fHisto->Reset();
219 }
220
221 //_____________________________________________________________________________
222 void AliMonitorHisto::Add(AliMonitorPlot* plot)
223 {
224 // merge the given histo to this one
225
226   if (!plot->InheritsFrom(AliMonitorHisto::Class())) return;
227   AliMonitorHisto* histo = (AliMonitorHisto*) plot;
228
229   fNumberOfEvents += histo->fNumberOfEvents;
230   Bool_t addStatus = TH1::AddDirectoryStatus();
231   TH1::AddDirectory(kFALSE);
232   TObjLink* link = histo->fHistoList.LastLink();
233   while (link) {
234     fHistoList.AddFirst(link->GetObject()->Clone());
235     link = link->Prev();
236   }
237   TH1::AddDirectory(addStatus);
238   fNHistos += histo->fNHistos;
239   while (fNHistos > fgNHistosMax) {
240     fHistoList.Remove(fHistoList.LastLink());
241     fNHistos--;
242   }
243   fHistoRun->Add(histo->fHistoRun);
244 }
245
246 //_____________________________________________________________________________
247 void AliMonitorHisto::Reset()
248 {
249 // reset the monitor histogram for a new run
250
251   fHisto->Reset();
252   fHistoList.Delete();
253   fNHistos = 0;
254   fHistoRun->Reset();
255   if (fHistoDraw) delete fHistoDraw;
256   fHistoDraw = NULL;
257   if (fHistoCompare) delete fHistoCompare;
258   fHistoCompare = NULL;
259   fNumberOfEvents = 0;
260 }
261
262 //_____________________________________________________________________________
263 void AliMonitorHisto::ResetList()
264 {
265 // reset the the list of monitor histograms
266
267   fHistoList.Delete();
268   fNHistos = 0;
269 }
270
271
272 //_____________________________________________________________________________
273 void AliMonitorHisto::Scale(Int_t nEvents)
274 {
275 // scale the histogram to the correct normalization
276
277   Double_t scale = 1.;
278   switch (fNorm) {
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;
285   }
286   fHistoDraw->Scale(scale);
287 }
288
289 //_____________________________________________________________________________
290 Bool_t AliMonitorHisto::ComparePlot()
291 {
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
295   
296   if (!fHistoRef) return kTRUE;
297   if (fgThreshold <= 0) return kTRUE;
298   if (!fHistoDraw) {
299     Info("Compare", "no data histogram available for comparison\ncall DrawEvent, DrawSum or DrawRaw before calling Compare");
300     return kTRUE;
301   }
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;
309
310   Int_t yMax = 1; 
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);
325         result = kFALSE;
326       }
327     }
328   }
329
330   return result;
331 }
332
333 //_____________________________________________________________________________
334 Bool_t AliMonitorHisto::GetEvent(Int_t number)
335 {
336 // get the normalized monitor histogram for the "number"th last event
337
338   if (fNHistos == 0) {
339     Info("GetEvent", "there are no histograms for single events available");
340     return kFALSE;
341   }
342   if (number > fNHistos) {
343     Error("GetEvent", "requested event number (%d) exceeds range of available events (%d)\n", 
344           number, fNHistos);
345     return kFALSE;
346   }
347   if (number <= 0) return kFALSE;
348
349   if (fHistoDraw) delete fHistoDraw;
350   if (fHistoCompare) delete fHistoCompare;
351   fHistoCompare = NULL;
352
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);
359
360   Scale(1);
361   return kTRUE;
362 }
363
364 //_____________________________________________________________________________
365 Bool_t AliMonitorHisto::GetSum(Int_t number)
366 {
367 // get the normalized monitor histogram for the sum of the last 
368 // "number" events
369
370   if (fNHistos == 0) {
371     Info("GetSum", "there are no histograms for single events available");
372     return kFALSE;
373   }
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);
377     number = fNHistos;
378   }
379   if (number <= 0) return kFALSE;
380
381   if (fHistoDraw) delete fHistoDraw;
382   if (fHistoCompare) delete fHistoCompare;
383   fHistoCompare = NULL;
384
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++) {
391     link = link->Next();
392     fHistoDraw->Add((TH1*) link->GetObject());
393   }
394
395   Scale(number);
396   return kTRUE;
397 }
398
399 //_____________________________________________________________________________
400 Bool_t AliMonitorHisto::GetRun()
401 {
402 // get the normalized monitor histogram for all monitored events 
403 // of the current run
404
405   if (fHistoDraw) delete fHistoDraw;
406   if (fHistoCompare) delete fHistoCompare;
407   fHistoCompare = NULL;
408
409   Bool_t addStatus = TH1::AddDirectoryStatus();
410   TH1::AddDirectory(kFALSE);
411   fHistoDraw = (TH1*) fHistoRun->Clone();
412   TH1::AddDirectory(addStatus);
413
414   Scale(fNumberOfEvents);
415   return kTRUE;
416 }
417
418 //_____________________________________________________________________________
419 void AliMonitorHisto::DrawPlot()
420 {
421 // draw the histograms
422
423   fHistoDraw->SetMarkerColor(fgColorData);
424   fHistoDraw->SetLineColor(fgColorData);
425   fHistoDraw->SetFillColor(fgColorData);
426   fHistoDraw->DrawCopy();
427
428   if (fHistoRef && fgDrawRef) {
429     char option[256];
430     sprintf(option, "%sSAME", fHistoDraw->GetOption());
431
432     if (fHistoRef->GetMaximum() > fHistoDraw->GetMaximum()) {
433       fHistoDraw->SetMaximum(fHistoRef->GetMaximum() * 1.1);
434     }
435
436     fHistoRef->SetMarkerColor(fgColorRef);
437     fHistoRef->SetLineColor(fgColorRef);
438     fHistoRef->SetFillColor(fgColorRef);
439     fHistoRef->DrawCopy(option);
440
441     fHistoDraw->DrawCopy(option);
442
443     if (fHistoCompare && (fgThreshold > 0)) {
444       fHistoCompare->SetMarkerColor(fgColorCompare);
445       fHistoCompare->SetLineColor(fgColorCompare);
446       fHistoCompare->SetFillColor(fgColorCompare);
447       fHistoCompare->DrawCopy(option);
448     }
449   }
450
451   gPad->Update();
452 }