Full Hough->deconvolution->fit chain implemented (C.Cheshkov)
[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::operator =(const AliMonitorHisto& histo)
84 {
85 // assignment operator
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
111 //_____________________________________________________________________________
112 AliMonitorHisto::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 //_____________________________________________________________________________
137 AliMonitorHisto::~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 //_____________________________________________________________________________
150 void 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 //_____________________________________________________________________________
163 void 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 //_____________________________________________________________________________
174 void AliMonitorHisto::Fill(Axis_t x)
175 {
176 // fill the monitor histogram
177
178   fHisto->Fill(x);
179 }
180
181 //_____________________________________________________________________________
182 void AliMonitorHisto::Fill(Axis_t x, Axis_t y)
183 {
184 // fill the monitor histogram
185
186   fHisto->Fill(x, y);
187 }
188
189 //_____________________________________________________________________________
190 void 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 //_____________________________________________________________________________
205 void 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 //_____________________________________________________________________________
223 void AliMonitorHisto::Update()
224 {
225 // update the normalized data histogram
226
227   Update(fHisto);
228   fHisto->Reset();
229 }
230
231 //_____________________________________________________________________________
232 void 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 //_____________________________________________________________________________
251 void 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 //_____________________________________________________________________________
276 void 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 //_____________________________________________________________________________
292 void AliMonitorHisto::ResetList()
293 {
294 // reset the the list of monitor histograms
295
296   fHistoList.Delete();
297   fNHistos = 0;
298 }
299
300
301 //_____________________________________________________________________________
302 void 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 //_____________________________________________________________________________
319 Bool_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 //_____________________________________________________________________________
363 Bool_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 //_____________________________________________________________________________
394 Bool_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 //_____________________________________________________________________________
429 Bool_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 //_____________________________________________________________________________
448 void 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 }