]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MONITOR/AliMonitorTrend.cxx
aa514b5303a01e4a9e3f2fd4fb001826ed7305ef
[u/mrichter/AliRoot.git] / MONITOR / AliMonitorTrend.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 plot for the evolution of a value that is used    //
21 //  tomonitor the quality of the recorded data.                              //
22 //  The trendgram is created and filled by a sub class of AliMonitor.        //
23 //  It can be compared to a reference trendgram. 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 <TH1.h>
31 #include <TVirtualPad.h>
32 #include <TLine.h>
33
34 #include "AliLog.h"
35
36 #include "AliMonitorTrend.h"
37
38
39 ClassImp(AliMonitorTrend) 
40
41
42 Int_t AliMonitorTrend::fgIncSize = 10;
43
44
45 //_____________________________________________________________________________
46 AliMonitorTrend::AliMonitorTrend():
47   AliMonitorPlot(),
48   fLabel(),
49   fMin(0),
50   fMax(0),
51   fData(),
52   fHistoDraw(NULL),
53   fRefMean(0),
54   fRefSigma(-1),
55   fHistoCompare(NULL)
56 {
57 // default contructor
58
59 }
60
61 //_____________________________________________________________________________
62 AliMonitorTrend::AliMonitorTrend(const AliMonitorTrend& trend) :
63   AliMonitorPlot(trend),
64   fLabel(trend.fLabel),
65   fMin(trend.fMin),
66   fMax(trend.fMax),
67   fData(trend.fData),
68   fHistoDraw(NULL),
69   fRefMean(trend.fRefMean),
70   fRefSigma(trend.fRefSigma),
71   fHistoCompare(NULL)
72 {
73 // copy constructor
74
75 }
76
77 //_____________________________________________________________________________
78 AliMonitorTrend& AliMonitorTrend::operator =(const AliMonitorTrend& trend)
79 {
80 // assignment operator
81
82   AliMonitorPlot::operator =(trend);
83
84   fLabel = trend.fLabel;
85   fMin = trend.fMin;
86   fMax = trend.fMax;
87   trend.fData.Copy(fData);
88
89   fHistoDraw = NULL;
90   fRefMean = trend.fRefMean;
91   fRefSigma = trend.fRefSigma;
92   fHistoCompare = NULL;
93
94   return *this;
95 }
96
97 //_____________________________________________________________________________
98 AliMonitorTrend::AliMonitorTrend(const char* name, const char* title,
99                   const char* label, Double_t min, Double_t max) :
100   AliMonitorPlot(name, title),
101   fLabel(label),
102   fMin(min),
103   fMax(max),
104   fData(),
105   fHistoDraw(NULL),
106   fRefMean(0),
107   fRefSigma(0),
108   fHistoCompare(NULL)
109 {
110 // create a monitor trend
111
112 }
113
114 //_____________________________________________________________________________
115 AliMonitorTrend::~AliMonitorTrend()
116 {
117 // delete all histograms
118
119   if (fHistoDraw) delete fHistoDraw;
120   if (fHistoCompare) delete fHistoCompare;
121 }
122
123
124 //_____________________________________________________________________________
125 void AliMonitorTrend::SetReference(TH1* ref)
126 {
127 // set the reference trend for comparison
128
129   Int_t n = ref->GetXaxis()->GetNbins();
130   if (n <= 0) return;
131
132   Double_t sum = 0;
133   Double_t sum2 = 0;
134   for (Int_t i = 1; i <= n; i++) {
135     sum += ref->GetBinContent(i);
136     sum2 += ref->GetBinContent(i) * ref->GetBinContent(i);
137   }
138
139   fRefMean = sum / n;
140   fRefSigma = TMath::Sqrt(sum2 - sum*sum/n) / n;
141 }
142
143 //_____________________________________________________________________________
144 void AliMonitorTrend::SetReference(AliMonitorPlot* ref)
145 {
146 // set the reference trendgram for comparison
147
148   if (!ref->InheritsFrom(AliMonitorTrend::Class())) return;
149   fRefMean = ((AliMonitorTrend*)ref)->GetMean();
150   fRefSigma = ((AliMonitorTrend*)ref)->GetSigma();
151 }
152
153
154 //_____________________________________________________________________________
155 void AliMonitorTrend::Fill(Double_t x)
156 {
157 // add a value to the monitor trend
158
159   if (fNumberOfEvents >= fData.GetSize()) {
160     fData.Set(fNumberOfEvents + fgIncSize);
161   }
162   fData[fNumberOfEvents] = x;
163 }
164
165
166 //_____________________________________________________________________________
167 void AliMonitorTrend::Update()
168 {
169 // update
170
171   fNumberOfEvents++;
172 }
173
174 //_____________________________________________________________________________
175 void AliMonitorTrend::Add(AliMonitorPlot* plot)
176 {
177 // merge the given trend to this one
178
179   if (!plot->InheritsFrom(AliMonitorTrend::Class())) return;
180   AliMonitorTrend* trend = (AliMonitorTrend*) plot;
181
182   Int_t numberOfEvents = fNumberOfEvents + trend->fNumberOfEvents;
183   if (numberOfEvents >=  fData.GetSize()) {
184     fData.Set(numberOfEvents + fgIncSize);
185   }
186   for (Int_t i = 0; i < trend->fNumberOfEvents; i++) {
187     fData[fNumberOfEvents + i] = trend->fData[i];
188   }
189   fNumberOfEvents = numberOfEvents;
190 }
191
192 //_____________________________________________________________________________
193 void AliMonitorTrend::Reset()
194 {
195 // reset the monitor trend for a new run
196
197   fData.Set(fgIncSize);
198   if (fHistoDraw) delete fHistoDraw;
199   fHistoDraw = NULL;
200   if (fHistoCompare) delete fHistoCompare;
201   fHistoCompare = NULL;
202   fNumberOfEvents = 0;
203 }
204
205 //_____________________________________________________________________________
206 void AliMonitorTrend::ResetList()
207 {
208 // reset the the list of monitor histograms
209 // (not applicable for trend)
210
211 }
212
213
214 //_____________________________________________________________________________
215 Bool_t AliMonitorTrend::ComparePlot()
216 {
217 // compare the data trend to the reference
218 // if they deviate by more than fgThreshold standard deviations in a bin,
219 // this bin is set in fHistoCompare and kFALSE is returned
220   
221   if (fRefSigma < 0) return kTRUE;
222   if (fgThreshold <= 0) return kTRUE;
223   if (!fHistoDraw) {
224     AliWarning("no data trend available for comparison\ncall DrawSum or DrawRaw before calling Compare");
225     return kTRUE;
226   }
227
228   Int_t nBins = fHistoDraw->GetXaxis()->GetNbins();
229   if (fHistoCompare) delete fHistoCompare;
230   fHistoCompare = CreateHisto(nBins);
231   fHistoCompare->Reset();
232   fHistoCompare->SetOption("P");
233   fHistoCompare->SetMarkerStyle(kFullCircle);
234   fHistoCompare->SetFillStyle(0);
235   Bool_t result = kTRUE;
236
237   for (Int_t iBin = 1; iBin <= nBins; iBin++) {
238     Double_t delta = TMath::Abs(fHistoDraw->GetBinContent(iBin) - fRefMean);
239     if (delta > fgThreshold*fRefSigma) {
240       fHistoCompare->SetBinContent(iBin, fHistoDraw->GetBinContent(iBin));
241       result = kFALSE;
242     }
243   }
244
245   return result;
246 }
247
248 //_____________________________________________________________________________
249 Bool_t AliMonitorTrend::GetEvent(Int_t)
250 {
251 // there is no single event trend
252
253 //  Info("GetEvent", "there is no trend for single events available");
254   return kFALSE;
255 }
256
257 //_____________________________________________________________________________
258 Bool_t AliMonitorTrend::GetSum(Int_t number)
259 {
260 // get the monitor trend for the last  "number" events
261
262   if (number > fNumberOfEvents) {
263     AliError(Form("requested number of events (%d) exceeds range of available events (%d)\nusing last %d event(s)", 
264           number, fNumberOfEvents, fNumberOfEvents));
265     number = fNumberOfEvents;
266   }
267   if (number <= 0) return kFALSE;
268
269   if (fHistoDraw) delete fHistoDraw;
270   if (fHistoCompare) delete fHistoCompare;
271   fHistoCompare = NULL;
272
273   fHistoDraw = CreateHisto(number);
274   return kTRUE;
275 }
276
277 //_____________________________________________________________________________
278 Bool_t AliMonitorTrend::GetRun()
279 {
280 // get the monitor trend for all monitored events of the current run
281
282   if (fHistoDraw) delete fHistoDraw;
283   if (fHistoCompare) delete fHistoCompare;
284   fHistoCompare = NULL;
285   if (fNumberOfEvents <= 0) return kFALSE;
286
287   fHistoDraw = CreateHisto(fNumberOfEvents);
288   return kTRUE;
289 }
290
291 //_____________________________________________________________________________
292 void AliMonitorTrend::DrawPlot()
293 {
294 // draw the trendgrams
295
296   fHistoDraw->SetMarkerColor(fgColorData);
297   fHistoDraw->SetLineColor(fgColorData);
298   fHistoDraw->SetLineWidth(2);
299   fHistoDraw->DrawCopy();
300
301   if ((fRefSigma > 0) && fgDrawRef) {
302     if ((fRefMean+fRefSigma > fHistoDraw->GetMaximum()) && !(fMax > fMin)) {
303       fHistoDraw->SetMaximum(fRefMean+fRefSigma * 1.1);
304     }
305
306     Double_t xMin = fHistoDraw->GetXaxis()->GetXmin();
307     Double_t xMax = fHistoDraw->GetXaxis()->GetXmax();
308     TLine* mean = new TLine(xMin, fRefMean, xMax, fRefMean);
309     mean->SetLineColor(fgColorRef);
310     mean->SetLineWidth(2);
311     mean->Draw();
312     TLine* high = new TLine(xMin, fRefMean+fRefSigma, 
313                             xMax, fRefMean+fRefSigma);
314     high->SetLineColor(fgColorRef);
315     high->SetLineWidth(2);
316     high->SetLineStyle(2);
317     high->Draw();
318     TLine* low = new TLine(xMin, fRefMean-fRefSigma, 
319                            xMax, fRefMean-fRefSigma);
320     low->SetLineColor(fgColorRef);
321     low->SetLineWidth(2);
322     low->SetLineStyle(2);
323     low->Draw();
324
325 //    char option[256];
326 //    sprintf(option, "%sSAME", fHistoDraw->GetOption());
327 //    fHistoDraw->DrawCopy(option);
328
329     if (fHistoCompare && (fgThreshold > 0)) {
330       char option[256];
331       sprintf(option, "%sSAME", fHistoCompare->GetOption());
332       fHistoCompare->SetMarkerColor(fgColorCompare);
333       fHistoCompare->SetLineColor(fgColorCompare);
334       fHistoCompare->SetLineWidth(2);
335       fHistoCompare->DrawCopy(option);
336     }
337   }
338
339   gPad->Update();
340 }
341
342
343 //_____________________________________________________________________________
344 TH1* AliMonitorTrend::CreateHisto(Int_t nBins)
345 {
346 // create a histogram for a trend plot with the last nBin entries
347
348   TH1* result = new TH1D(GetName(), GetTitle(), nBins, -nBins-0.5, -0.5);
349   result->GetXaxis()->SetTitle("N_{event}");
350   result->GetYaxis()->SetTitle(fLabel.Data());
351   if (fMax > fMin) {
352     result->SetMinimum(fMin);
353     result->SetMaximum(fMax);
354   }
355   result->SetOption("L");
356
357   Double_t sum = 0;
358   Double_t sum2 = 0;
359   for (Int_t i = 0; i < nBins; i++) {
360     Double_t data = fData[fNumberOfEvents-1-i];
361     sum += data;
362     sum2 += data * data;
363     result->SetBinContent(nBins-i, data);
364   }
365   Stat_t stats[4];
366   stats[0] = nBins;
367   stats[1] = nBins * nBins;
368   stats[2] = sum;
369   stats[3] = sum2;
370   result->PutStats(stats);
371
372   return result;
373 }
374
375 //_____________________________________________________________________________
376 Double_t AliMonitorTrend::GetMean() const
377 {
378 // get the mean value
379
380   if (fNumberOfEvents <= 0) return 0;
381
382   Double_t sum = 0;
383   for (Int_t i = 0; i < fNumberOfEvents; i++) {
384     sum += fData[i];
385   }
386   return sum / fNumberOfEvents;
387 }
388
389 //_____________________________________________________________________________
390 Double_t AliMonitorTrend::GetSigma() const
391 {
392 // get the rms value
393
394   if (fNumberOfEvents <= 0) return 0;
395
396   Double_t sum = 0;
397   Double_t sum2 = 0;
398   for (Int_t i = 0; i < fNumberOfEvents; i++) {
399     sum += fData[i];
400     sum2 += fData[i] * fData[i];
401   }
402   return TMath::Sqrt(sum2 - sum*sum/fNumberOfEvents) / fNumberOfEvents;
403 }
404