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