]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/FORWARD/analysis2/qa/QAPlotter.C
Sync from old structure
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / qa / QAPlotter.C
CommitLineData
2dbde04b 1/**
2 * @file QAPlotter.C
3 * @author Christian Holm Christensen <cholm@nbi.dk>
4 * @date Thu Nov 17 12:08:04 2011
5 *
6 * @brief Class to plot QA trends
7 *
8 * @ingroup pwg2_forward_qa_scripts
9 *
10 */
11#ifndef __CINT__
12# include "QABase.h"
13# include <TTree.h>
14# include <TGraph.h>
15# include <TGraphErrors.h>
16# include <TGraphAsymmErrors.h>
17# include <TMultiGraph.h>
18# include <TH1.h>
19# include <TLegend.h>
20# include <TCanvas.h>
21# include <TLine.h>
5e8eab11 22# include <TArrow.h>
2dbde04b 23# include <TArrayI.h>
5e8eab11 24# include <TMath.h>
bae153e5 25# include <TChain.h>
2dbde04b 26#else
27class QABase;
28class QARing;
29class TTree;
30class TGraphAsymmErrors;
31class TGraph;
32class TGraphErrors;
33class TMultiGraph;
34class RingQuantity;
35class TArrayI;
36class TH1;
37#endif
38
39
40/**
41 * Class to plot QA trends
42 *
43 * @ingroup pwg2_forward_qa_scripts
44 */
45struct QAPlotter : public QABase
46{
47 /*******************************************************************
48 * Ring class
49 */
50 struct Ring : public QARing
51 {
52 /**
53 * Constuctor
54 *
55 * @param d Detector
56 * @param r Ring
57 */
58 Ring(UShort_t d, Char_t r)
59 : QARing(d, r),
60 fGChi2(0),
61 fGC(0),
62 fGDelta(0),
63 fGXi(0),
64 fGSigma(0),
65 fGLow(0),
66 fGSingles(0),
67 fGLoss(0),
68 fGBeta(0),
69 fGOccupancy(0)
70 {
71 fGChi2 = new TGraphAsymmErrors;
72 fGC = new TGraphAsymmErrors;
73 fGDelta = new TGraphAsymmErrors;
74 fGXi = new TGraphAsymmErrors;
75 fGSigma = new TGraphAsymmErrors;
76 fGLow = new TGraph;
77 fGSingles = new TGraph;
78 fGLoss = new TGraph;
79 fGBeta = new TGraph;
80 fGOccupancy = new TGraphAsymmErrors;
81
82 SetAtt(fGChi2, "chi2", "#LT#chi^{2}/#nu#GT");
83 SetAtt(fGC, "c", "Constant");
84 SetAtt(fGDelta, "delta", "#LT#Delta_{p}#GT");
85 SetAtt(fGXi, "xi", "#LT#xi#GT");
86 SetAtt(fGSigma, "sigma", "#LT#sigma#GT");
87 SetAtt(fGLow, "low", "# of low statistics bins");
88 SetAtt(fGSingles, "singles", "Fraction of single hits");
89 SetAtt(fGLoss, "loss", "Data lossed due to cuts");
90 SetAtt(fGOccupancy, "occupancy","#LTOccupancy#GT");
91 SetAtt(fGBeta, "beta", "Correlation of methods");
92
93 }
94 /**
95 * Static member function to get the ring color
96 *
97 * @param d Detector number
98 * @param r Ring identifer
99 *
100 * @return Color
101 */
102 static Color_t RingColor(UShort_t d, Char_t r)
103 {
104 return ((d == 1 ? kRed : (d == 2 ? kGreen : kBlue))
105 + ((r == 'I' || r == 'i') ? 2 : -3));
106 }
107 /**
108 * Set graph attributes
109 *
110 * @param g Graph
111 * @param name Name of graph
112 * @param title Title (not used)
113 */
114 void SetAtt(TGraph* g, const char* name, const char* /*title=""*/)
115 {
116 Color_t c = RingColor(fD, fR);
117 g->SetName(Form("FMD%d%c_%s", fD, fR, name));
118 // g->SetTitle(Form("FMD%d%c %s", fD, fR,
119 // !title || title[0] == '\0' ? name : title));
5e8eab11 120 Int_t marker = 20+(fD-1) + (fR == 'I' ? 0 : 4);
2dbde04b 121 g->SetTitle(Form("FMD%d%c", fD, fR));
122 g->SetLineColor(c);
123 g->SetFillColor(c);
124 g->SetMarkerColor(c);
5e8eab11 125 g->SetMarkerStyle(marker);
2dbde04b 126 g->SetLineWidth(2);
5e8eab11 127 switch (marker) {
128 case 20: g->SetMarkerSize(1.2); break;
129 case 21: g->SetMarkerSize(1.2); break;
130 case 22: g->SetMarkerSize(1.3); break;
131 case 26: g->SetMarkerSize(1.1); break;
132 }
2dbde04b 133 }
134 /**
135 * Update a graph from a RingQuantity
136 *
137 * @param g Graph to update
138 * @param q Quantity
139 * @param runNo Run number
140 */
141 void UpdateGraph(TGraphAsymmErrors* g, RingQuantity& q,
142 UInt_t runNo, UInt_t /* n */)
143 {
144 Double_t y = q.mean;
145 Double_t el = y-q.min;
146 Double_t eh = q.max-y;
147 if (TMath::Abs(y) < 1e-6) return;
148 Int_t i = g->GetN();
149 g->SetPoint(i, runNo, y);
150 g->SetPointError(i, 0, 0, el, eh);
151 }
152 /**
153 * Update all graphs
154 *
155 * @param n Entry number (not used)
156 * @param runNo Run number
157 *
158 * @return true on success
159 */
160 Bool_t Update(UInt_t n, UInt_t runNo)
161 {
162 UpdateGraph(fGChi2, *fChi2, runNo, n);
163 UpdateGraph(fGC, *fC, runNo, n);
164 UpdateGraph(fGDelta, *fDelta, runNo, n);
165 UpdateGraph(fGXi, *fXi, runNo, n);
166 UpdateGraph(fGSigma, *fSigma, runNo, n);
167 UpdateGraph(fGOccupancy, *fOccupancy, runNo, n);
168
169 fGLow->SetPoint(n, runNo, fFitStatus->nLow);
170
171 if (fMerge->one > 1e-6)
172 fGSingles->SetPoint(fGSingles->GetN(), runNo, fMerge->one);
173 if (fCorrelation->beta > 1e-6)
174 fGBeta->SetPoint(fGBeta->GetN(), runNo, fCorrelation->beta);
175 if (-fDataLoss->full > 1e-6)
176 fGLoss->SetPoint(fGLoss->GetN(), runNo, -fDataLoss->full);
177 return true;
178 }
179 TGraphAsymmErrors* fGChi2; // Graph of ELoss reduced chi-square
180 TGraphAsymmErrors* fGC; // Graph of ELoss constant
181 TGraphAsymmErrors* fGDelta; // Graph of ELoss MPV
182 TGraphAsymmErrors* fGXi; // Graph of ELoss Landau width
183 TGraphAsymmErrors* fGSigma; // Graph of ELoss Gaus width
184 TGraph* fGLow; // Graph of bins with low statistics
185 TGraph* fGSingles; // Graph of fraction of singles
186 TGraph* fGLoss; // Graph of 'lost' data
187 TGraph* fGBeta; // Graph of Poisson vs ELoss correlation
188 TGraphAsymmErrors* fGOccupancy;// Graph of mean occupancy
189 };
190 /**
191 * Constructor
192 */
193 QAPlotter()
194 : QABase(),
195 fNAccepted(0),
196 fVz(0)
197 {
198 fFMD1i = new Ring(1, 'I');
199 fFMD2i = new Ring(2, 'I');
200 fFMD2o = new Ring(2, 'O');
201 fFMD3i = new Ring(3, 'I');
202 fFMD3o = new Ring(3, 'O');
203 fNAccepted = new TGraph;
204 fNAccepted->SetName("nAccepted");
205 fNAccepted->SetMarkerStyle(20);
206 fNAccepted->SetLineWidth(2);
207
208 fVz = new TGraphErrors;
209 fVz->SetName("vz");
210 fVz->SetMarkerStyle(20);
211 fVz->SetLineWidth(2);
212 }
bae153e5 213 /**
214 * Add a file to be processed
215 *
216 * @param filename Name of file
217 */
218 void AddFile(const char* filename)
219 {
220 fFiles.Add(new TObjString(filename));
221 }
222 Bool_t MakeTree(bool read)
223 {
224 if (fFiles.GetEntriesFast() <= 0) return QABase::MakeTree(read);
225
226 TChain* chain = new TChain("T", "T");
227 if (!chain->AddFileInfoList(&fFiles)) return false;
228
229 fTree = chain;
230 return true;
231 }
232
2dbde04b 233 /**
234 * Run the job
235 *
236 */
237 void Run()
238 {
239 Init(true);
240 if (!fTree) {
241 Error("Run", "No input tree");
242 return;
243 }
244
245 fFirst = 0xFFFFFFFF;
246 fLast = 0;
247
248 UInt_t nEntries = fTree->GetEntries();
249 UInt_t j = 0;
250 fRuns.Set(nEntries);
251 for (UInt_t i = 0; i < nEntries; i++) {
252 fTree->GetEntry(i);
253
254 UInt_t run = fGlobal->runNo;
255 UInt_t nev = fGlobal->nAccepted;
256
257 fFirst = TMath::Min(run, fFirst);
258 fLast = TMath::Max(run, fLast);
259 fRuns[i] = run;
260
261 Info("Run", "Got run %d with %d accepted events", run, nev);
262 fNAccepted->SetPoint(i, run, nev);
263 fVz->SetPoint(i, run, fGlobal->meanVz);
264 fVz->SetPointError(i, 0, fGlobal->sigmaVz);
265
266 if (nev <= 100) continue;
267 static_cast<Ring*>(fFMD1i)->Update(j, run);
268 static_cast<Ring*>(fFMD2i)->Update(j, run);
269 static_cast<Ring*>(fFMD2o)->Update(j, run);
270 static_cast<Ring*>(fFMD3i)->Update(j, run);
271 static_cast<Ring*>(fFMD3o)->Update(j, run);
272 j++;
273 }
274
275 Plot();
276 }
277 /**
278 * Plot results
279 *
280 */
281 void Plot()
282 {
283
284 fTeXName = Form("trend_%09d_%09d", fFirst, fLast);
285 MakeCanvas(Form("QA trends for runs %d --- %d", fFirst, fLast));
286
287 CanvasTitle("# of accepted events");
288 fNAccepted->Draw("apl");
5e8eab11 289 PutCanvasTitle("# of accepted events");
2dbde04b 290 AddRuns(fNAccepted->GetHistogram(), "# of accepted events");
291
292 TLine* l = new TLine(fFirst, 100, fLast, 100);
293 l->SetLineColor(kRed+2);
294 l->SetLineStyle(2);
295 l->Draw();
296 PrintCanvas("nAccepted");
297
298 CanvasTitle("#LTv_{z}#GT");
299 fVz->Draw("apl");
5e8eab11 300 PutCanvasTitle("Mean z coordinate of interaction point");
2dbde04b 301 AddRuns(fVz->GetHistogram(), "#LTv_{z}#GT");
302 PrintCanvas("vz");
303
304 TMultiGraph* chi2 = new TMultiGraph;
305 TMultiGraph* c = new TMultiGraph;
306 TMultiGraph* delta = new TMultiGraph;
307 TMultiGraph* xi = new TMultiGraph;
308 TMultiGraph* sigma = new TMultiGraph;
309 TMultiGraph* low = new TMultiGraph;
310 TMultiGraph* singles = new TMultiGraph;
311 TMultiGraph* loss = new TMultiGraph;
312 TMultiGraph* occ = new TMultiGraph;
313 TMultiGraph* beta = new TMultiGraph;
314 chi2 ->SetName("chi2");
315 c ->SetName("c");
316 delta ->SetName("delta");
317 xi ->SetName("xi");
318 sigma ->SetName("sigma");
319 low ->SetName("low");
320 singles ->SetName("singles");
321 loss ->SetName("loss");
322 beta ->SetName("beta");
323 occ ->SetName("occupancy");
324
325
326 AddToMulti(fFMD1i,chi2, c, delta, xi, sigma, low, singles, loss, beta, occ);
327 AddToMulti(fFMD2i,chi2, c, delta, xi, sigma, low, singles, loss, beta, occ);
328 AddToMulti(fFMD2o,chi2, c, delta, xi, sigma, low, singles, loss, beta, occ);
329 AddToMulti(fFMD3i,chi2, c, delta, xi, sigma, low, singles, loss, beta, occ);
330 AddToMulti(fFMD3o,chi2, c, delta, xi, sigma, low, singles, loss, beta, occ);
331
5e8eab11 332 PlotMulti(chi2, "#LT#chi^{2}/#nu#GT from #Delta fits", true);
2dbde04b 333 PlotMulti(c, "#LTc#GT from #Delta fits");
334 PlotMulti(delta, "#LT#Delta_{p}#GT from #Delta fits");
335 PlotMulti(xi, "#LT#xi#GT from #Delta fits");
336 PlotMulti(sigma, "#LT#sigma#GT from #Delta fits");
337 PlotMulti(low, "Bins with too low statistics");
338 PlotMulti(singles, "Fraction of single hits");
339 PlotMulti(loss, "% of hits 'lost' due to merging+cuts");
5e8eab11 340 PlotMulti(occ, "#LTOccupancy#GT [%]", true);
2dbde04b 341 PlotMulti(beta, "Correlation of methods");
342
343 fStore->cd();
344 fNAccepted->Write();
345 chi2->Write();
346 c->Write();
347 delta->Write();
348 sigma->Write();
349 low->Write();
350 singles->Write();
351 loss->Write();
352 occ->Write();
353 beta->Write();
354
355 Close(false); // Do not delete PNGs
356 }
357 /**
358 * Add graphs from a ring to the multi graphs
359 *
360 * @param qr Ring
361 * @param chi2 ELoss reduced chi-square
362 * @param c ELoss constant
363 * @param delta ELoss MPV
364 * @param xi ELoss Landau width
365 * @param sigma ELoss Gaus width
366 * @param low bins with low statistics
367 * @param singles fraction of singles
368 * @param loss 'lost' data
369 * @param beta Poisson vs ELoss correlation
370 * @param occupancy mean occupancy
371 */
372 void AddToMulti(QARing* qr,
373 TMultiGraph* chi2,
374 TMultiGraph* c,
375 TMultiGraph* delta,
376 TMultiGraph* xi,
377 TMultiGraph* sigma,
378 TMultiGraph* low,
379 TMultiGraph* singles,
380 TMultiGraph* loss,
381 TMultiGraph* beta,
382 TMultiGraph* occupancy)
383 {
384 Ring* r = static_cast<Ring*>(qr);
385 chi2 ->Add(r->fGChi2);
386 c ->Add(r->fGC);
387 delta ->Add(r->fGDelta);
388 xi ->Add(r->fGXi);
389 sigma ->Add(r->fGSigma);
390 low ->Add(r->fGLow);
391 singles ->Add(r->fGSingles);
392 loss ->Add(r->fGLoss);
393 occupancy ->Add(r->fGOccupancy);
394 beta ->Add(r->fGBeta);
395 }
396 /**
397 * Plot a multi-graph
398 *
399 * @param mg Multi graph
400 * @param title Title
401 */
5e8eab11 402 void PlotMulti(TMultiGraph* mg, const char* title, Bool_t logy=false)
2dbde04b 403 {
404 CanvasTitle(title);
405 // fCanvas->SetBottomMargin(.15);
406 fCanvas->SetLeftMargin(.08);
5e8eab11 407 fCanvas->SetTopMargin(.1);
408 fCanvas->SetLogy(logy);
409 // fCanvas->SetRightMargin(.2);
2dbde04b 410 mg->Draw("apl");
411
5e8eab11 412 TH1* h = mg->GetHistogram();
413 Double_t max = h->GetMaximum();
414 Double_t min = h->GetMinimum();
415 if (h->GetMinimum() == 0) {
2dbde04b 416 min = min - .1*(max-min);
5e8eab11 417 h->SetMinimum(min);
2dbde04b 418 }
5e8eab11 419 Int_t x1 = h->GetXaxis()->GetXmin();
420 Int_t x2 = h->GetXaxis()->GetXmax();
2dbde04b 421
5e8eab11 422 TLegend* l = new TLegend(.1, .91, .97, .95);
423 l->SetNColumns(5);
2dbde04b 424 l->SetFillColor(0);
425 l->SetFillStyle(0);
426 l->SetBorderSize(0);
5e8eab11 427 l->SetTextFont(42);
2dbde04b 428 TIter next(mg->GetListOfGraphs());
429 mg->GetListOfGraphs();
430 TGraph* g = 0;
431
f4bcfce1 432 // Get the runs we have here
433 TArrayI runs(fRuns.GetSize());
5e8eab11 434 runs.Reset(INT_MAX);
f4bcfce1 435 Int_t j = 0;
2dbde04b 436 while ((g = static_cast<TGraph*>(next()))) {
437 l->AddEntry(g, g->GetTitle(), "lp");
f4bcfce1 438 Double_t* xs = g->GetX();
439 Int_t n = g->GetN();
440 for (Int_t i = 0; i < n; i++) {
5e8eab11 441 if (FindRun(runs, Int_t(xs[i])) >= 0) continue;
f4bcfce1 442 runs.SetAt(xs[i], j++);
443 }
5e8eab11 444 Double_t ymean = g->GetMean(2);
445 Double_t xh = x2 - .03 * Double_t(x2-x1);
446 TLine* lm = new TLine(x1, ymean, xh, ymean);
447 lm->SetLineColor(g->GetLineColor());
448 lm->SetLineStyle(2);
449 lm->SetLineWidth(1);
450 lm->Draw();
451 TLatex* al = new TLatex(xh, ymean, g->GetTitle());
452 al->SetTextColor(g->GetLineColor());
453 al->SetTextFont(42);
454 al->SetTextSize(.02);
455 al->SetTextAlign(12);
456 al->Draw();
2dbde04b 457 }
458 l->Draw();
459
5e8eab11 460 AddRuns(h, title, &runs);
2dbde04b 461
462 PrintCanvas(mg->GetName());
463 }
f4bcfce1 464 Int_t FindRun(const TArrayI& runs, Int_t run)
465 {
5e8eab11 466 std::sort(&(runs.fArray[0]), &(runs.fArray[runs.GetSize()]));
f4bcfce1 467 Int_t idx = TMath::BinarySearch(runs.GetSize(), runs.fArray, run);
5e8eab11 468 if (idx >= runs.GetSize() || idx < 0 || runs[idx] != run) return -1;
f4bcfce1 469 return idx;
470 }
2dbde04b 471 /**
472 * Add run labels at appropriate places on the plot
473 *
474 * @param h Frame histogram
475 * @param title Title
476 */
f4bcfce1 477 void AddRuns(TH1* h, const char* title, TArrayI* runs=0)
2dbde04b 478 {
479 h->GetXaxis()->SetNoExponent();
5e8eab11 480 // h->GetXaxis()->SetTitleOffset(1);
2dbde04b 481 h->SetYTitle(title);
482 h->SetXTitle("Run #");
483
5e8eab11 484 Int_t r1 = h->GetXaxis()->GetXmin();
485 Int_t r2 = h->GetXaxis()->GetXmax();
486 Double_t lx = 0;
487 Double_t tx = .045; // (r2 - r1) / 18;
488 Double_t wx = 1 - fCanvas->GetLeftMargin() - fCanvas->GetRightMargin();
489 Double_t dy = .025;
490 Double_t y = fCanvas->GetBottomMargin()+dy;
2dbde04b 491 for (Int_t i = 0; i < fRuns.GetSize(); i++) {
5e8eab11 492 Int_t r = fRuns[i];
493 Double_t x = fCanvas->GetLeftMargin() + wx*Double_t(r-r1)/(r2-r1);
f4bcfce1 494
495 // Skip runs out of range
5e8eab11 496 if (r < r1 || r > r2) continue;
f4bcfce1 497
498 // Skip runs not in the graphs
5e8eab11 499 if (runs) {
500 if (FindRun(*runs, r) < 0) {
501 continue;
502 }
503 }
504
f4bcfce1 505
2dbde04b 506 if (TMath::Abs(x - lx) < tx) y += dy;
5e8eab11 507 else y = fCanvas->GetBottomMargin() + dy;
508
509
510 // Info(h->GetName(), "%6d (x,y)=(%12f,%12f) |lx-x|=|%f-x|=%f",
511 // r, x, y, lx, TMath::Abs(lx-x));
2dbde04b 512 lx = x;
5e8eab11 513
514 Double_t* xa = fNAccepted->GetX();
515 Int_t na = fNAccepted->GetN();
516 Int_t idx = TMath::BinarySearch(na, xa, Double_t(r));
517 Color_t color = kBlue+3;
518 if (idx >= 0 && idx < na && r == xa[idx] &&
519 fNAccepted->GetY()[idx] < 10000)
520 color = kRed+3;
2dbde04b 521
5e8eab11 522 TLatex* ll = new TLatex(x, y, Form("%d", r));
523 ll->SetNDC();
2dbde04b 524 ll->SetTextAlign(21);
525 ll->SetTextSize(0.02);
5e8eab11 526 ll->SetTextColor(color);
527 ll->SetTextFont(42);
2dbde04b 528 // ll->SetTextAngle(90);
529 ll->Draw();
5e8eab11 530 TLine* tl = new TLine(x, y, x, 1-fCanvas->GetTopMargin());
531 tl->SetBit(TLine::kLineNDC);
532 tl->SetLineStyle(3);
533 tl->SetLineColor(color);
2dbde04b 534 tl->Draw();
535 }
536 }
3405bb49 537 void WriteRuns(std::ostream& o)
538 {
9a684059 539 o << "<div class='jobid'><!--JOBID--></div>\n"
540 << "<div class='runs'>\n"
2de08f0a 541 << " Runs:<br> ";
3405bb49 542 for (Int_t i = 0; i < fRuns.GetSize(); i++) {
543 o << "<a href='qa_" << Form("%09d", fRuns[i]) << ".html'>"
544 << fRuns[i] << "</a> " << std::flush;
545 }
546 o << "\n"
547 << "</div>" << std::endl;
548 }
549 void WriteFooter()
550 {
551 WriteRuns(*fHtml);
552 QABase::WriteFooter();
553 }
554 void WriteImageFooter(std::ostream& o, const char* pngName)
555 {
556 WriteRuns(o);
557 QABase::WriteImageFooter(o, pngName);
558 }
2dbde04b 559 TGraph* fNAccepted; // Graph of number of accepted events
560 TGraphErrors* fVz; // Graph of mean vertex
561 UInt_t fFirst; // First run
562 UInt_t fLast; // Last run
563 TArrayI fRuns; // Seen runs
bae153e5 564 TObjArray fFiles;
2dbde04b 565};
566
567//
568// EOF
569//
570
571
572