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