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