1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
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. //
27 ///////////////////////////////////////////////////////////////////////////////
30 #include "AliMonitorTrend.h"
32 #include <TVirtualPad.h>
36 ClassImp(AliMonitorTrend)
39 Int_t AliMonitorTrend::fgIncSize = 10;
42 //_____________________________________________________________________________
43 AliMonitorTrend::AliMonitorTrend()
54 //_____________________________________________________________________________
55 AliMonitorTrend::AliMonitorTrend(const AliMonitorTrend& trend) :
60 fLabel = trend.fLabel;
63 trend.fData.Copy(fData);
66 fRefMean = trend.fRefMean;
67 fRefSigma = trend.fRefSigma;
71 //_____________________________________________________________________________
72 AliMonitorTrend& AliMonitorTrend::operator =(const AliMonitorTrend& trend)
74 // assignment operator
76 AliMonitorPlot::operator =(trend);
78 fLabel = trend.fLabel;
81 trend.fData.Copy(fData);
84 fRefMean = trend.fRefMean;
85 fRefSigma = trend.fRefSigma;
91 //_____________________________________________________________________________
92 AliMonitorTrend::AliMonitorTrend(const char* name, const char* title,
93 const char* label, Double_t min, Double_t max) :
94 AliMonitorPlot(name, title)
96 // create a monitor trend
103 fRefMean = fRefSigma = 0;
104 fHistoCompare = NULL;
107 //_____________________________________________________________________________
108 AliMonitorTrend::~AliMonitorTrend()
110 // delete all histograms
112 if (fHistoDraw) delete fHistoDraw;
113 if (fHistoCompare) delete fHistoCompare;
117 //_____________________________________________________________________________
118 void AliMonitorTrend::SetReference(TH1* ref)
120 // set the reference trend for comparison
122 Int_t n = ref->GetXaxis()->GetNbins();
127 for (Int_t i = 1; i <= n; i++) {
128 sum += ref->GetBinContent(i);
129 sum2 += ref->GetBinContent(i) * ref->GetBinContent(i);
133 fRefSigma = TMath::Sqrt(sum2 - sum*sum/n) / n;
136 //_____________________________________________________________________________
137 void AliMonitorTrend::SetReference(AliMonitorPlot* ref)
139 // set the reference trendgram for comparison
141 if (!ref->InheritsFrom(AliMonitorTrend::Class())) return;
142 fRefMean = ((AliMonitorTrend*)ref)->GetMean();
143 fRefSigma = ((AliMonitorTrend*)ref)->GetSigma();
147 //_____________________________________________________________________________
148 void AliMonitorTrend::Fill(Double_t x)
150 // add a value to the monitor trend
152 if (fNumberOfEvents >= fData.GetSize()) {
153 fData.Set(fNumberOfEvents + fgIncSize);
155 fData[fNumberOfEvents] = x;
159 //_____________________________________________________________________________
160 void AliMonitorTrend::Update()
167 //_____________________________________________________________________________
168 void AliMonitorTrend::Add(AliMonitorPlot* plot)
170 // merge the given trend to this one
172 if (!plot->InheritsFrom(AliMonitorTrend::Class())) return;
173 AliMonitorTrend* trend = (AliMonitorTrend*) plot;
175 Int_t numberOfEvents = fNumberOfEvents + trend->fNumberOfEvents;
176 if (numberOfEvents >= fData.GetSize()) {
177 fData.Set(numberOfEvents + fgIncSize);
179 for (Int_t i = 0; i < trend->fNumberOfEvents; i++) {
180 fData[fNumberOfEvents + i] = trend->fData[i];
182 fNumberOfEvents = numberOfEvents;
185 //_____________________________________________________________________________
186 void AliMonitorTrend::Reset()
188 // reset the monitor trend for a new run
190 fData.Set(fgIncSize);
191 if (fHistoDraw) delete fHistoDraw;
193 if (fHistoCompare) delete fHistoCompare;
194 fHistoCompare = NULL;
198 //_____________________________________________________________________________
199 void AliMonitorTrend::ResetList()
201 // reset the the list of monitor histograms
202 // (not applicable for trend)
207 //_____________________________________________________________________________
208 Bool_t AliMonitorTrend::ComparePlot()
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
214 if (fRefSigma < 0) return kTRUE;
215 if (fgThreshold <= 0) return kTRUE;
217 Info("Compare", "no data trend available for comparison\ncall DrawSum or DrawRaw before calling Compare");
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;
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));
241 //_____________________________________________________________________________
242 Bool_t AliMonitorTrend::GetEvent(Int_t)
244 // there is no single event trend
246 // Info("GetEvent", "there is no trend for single events available");
250 //_____________________________________________________________________________
251 Bool_t AliMonitorTrend::GetSum(Int_t number)
253 // get the monitor trend for the last "number" events
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;
260 if (number <= 0) return kFALSE;
262 if (fHistoDraw) delete fHistoDraw;
263 if (fHistoCompare) delete fHistoCompare;
264 fHistoCompare = NULL;
266 fHistoDraw = CreateHisto(number);
270 //_____________________________________________________________________________
271 Bool_t AliMonitorTrend::GetRun()
273 // get the monitor trend for all monitored events of the current run
275 if (fHistoDraw) delete fHistoDraw;
276 if (fHistoCompare) delete fHistoCompare;
277 fHistoCompare = NULL;
278 if (fNumberOfEvents <= 0) return kFALSE;
280 fHistoDraw = CreateHisto(fNumberOfEvents);
284 //_____________________________________________________________________________
285 void AliMonitorTrend::DrawPlot()
287 // draw the trendgrams
289 fHistoDraw->SetMarkerColor(fgColorData);
290 fHistoDraw->SetLineColor(fgColorData);
291 fHistoDraw->SetLineWidth(2);
292 fHistoDraw->DrawCopy();
294 if ((fRefSigma > 0) && fgDrawRef) {
295 if ((fRefMean+fRefSigma > fHistoDraw->GetMaximum()) && !(fMax > fMin)) {
296 fHistoDraw->SetMaximum(fRefMean+fRefSigma * 1.1);
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);
305 TLine* high = new TLine(xMin, fRefMean+fRefSigma,
306 xMax, fRefMean+fRefSigma);
307 high->SetLineColor(fgColorRef);
308 high->SetLineWidth(2);
309 high->SetLineStyle(2);
311 TLine* low = new TLine(xMin, fRefMean-fRefSigma,
312 xMax, fRefMean-fRefSigma);
313 low->SetLineColor(fgColorRef);
314 low->SetLineWidth(2);
315 low->SetLineStyle(2);
319 // sprintf(option, "%sSAME", fHistoDraw->GetOption());
320 // fHistoDraw->DrawCopy(option);
322 if (fHistoCompare && (fgThreshold > 0)) {
324 sprintf(option, "%sSAME", fHistoCompare->GetOption());
325 fHistoCompare->SetMarkerColor(fgColorCompare);
326 fHistoCompare->SetLineColor(fgColorCompare);
327 fHistoCompare->SetLineWidth(2);
328 fHistoCompare->DrawCopy(option);
336 //_____________________________________________________________________________
337 TH1* AliMonitorTrend::CreateHisto(Int_t nBins)
339 // create a histogram for a trend plot with the last nBin entries
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());
345 result->SetMinimum(fMin);
346 result->SetMaximum(fMax);
348 result->SetOption("L");
352 for (Int_t i = 0; i < nBins; i++) {
353 Double_t data = fData[fNumberOfEvents-1-i];
356 result->SetBinContent(nBins-i, data);
360 stats[1] = nBins * nBins;
363 result->PutStats(stats);
368 //_____________________________________________________________________________
369 Double_t AliMonitorTrend::GetMean() const
371 // get the mean value
373 if (fNumberOfEvents <= 0) return 0;
376 for (Int_t i = 0; i < fNumberOfEvents; i++) {
379 return sum / fNumberOfEvents;
382 //_____________________________________________________________________________
383 Double_t AliMonitorTrend::GetSigma() const
387 if (fNumberOfEvents <= 0) return 0;
391 for (Int_t i = 0; i < fNumberOfEvents; i++) {
393 sum2 += fData[i] * fData[i];
395 return TMath::Sqrt(sum2 - sum*sum/fNumberOfEvents) / fNumberOfEvents;