3 * @author Christian Holm Christensen <cholm@nbi.dk>
4 * @date Thu Nov 17 12:28:17 2011
6 * @brief Class to make the QA trending tree
8 * @ingroup pwg2_forward_qa_scripts
23 # include <TLegendEntry.h>
25 # include <TLinearFitter.h>
30 # include "QAStructs.h"
51 // --- A quantity ----------------------------------------------------
53 * Class to make the QA trending tree
55 * @ingroup pwg2_forward_qa_scripts
57 struct QATrender : public QABase
60 /******************************************************************/
65 struct Ring : public QARing
73 Ring(UShort_t d, Char_t r) : QARing(d, r) {}
75 * Get the detector specific list
77 * @param parent Parent list
79 * @return Found list or null
81 TList* GetDetectorList(const TList* parent) const
83 TObject* o = QATrender::GetSubList(parent, Form("FMD%d%c", fD, fR));
84 return static_cast<TList*>(o);
87 * Calculate numbers from read histograms
89 * @param parent Parent list
90 * @param name Name of histogram
91 * @param q Qauntity to store in
93 * @return true on success
95 Bool_t ExtractYQuantity(const TList* parent, const char* name,
103 TH1* h = QATrender::GetHistogram(parent, name);
105 // Warning("ExtractYQuantity", "Histogram %s not found", name);
113 for (Int_t i = 1; i <= h->GetNbinsX(); i++) {
114 Double_t y = h->GetBinContent(i);
115 Double_t e = h->GetBinError(i);
117 if (y <= 1e-12) continue;
118 if (e != 0) w = 1 / (e*e);
121 min = TMath::Min(min, y);
122 max = TMath::Max(max, y);
123 // Info("", " %s %3d: y=%f,\t e=%f,\t w=%f", name, i, y, e, w);
128 // Warning("ExtractYQuantity",
129 // "Sum of weights for %s too small %g<1e-6",
133 q->mean = sum / sumw;
134 q->var = TMath::Sqrt(1/sumw);
135 // Info(name, " mean=%f, var=%f", q->mean, q->var);
139 * Process data from the energy loss fits
141 * @param parent Parent list
143 * @return true on success
145 Bool_t ProcessEnergyLoss(const TList* parent)
147 TList* det = GetDetectorList(parent);
148 if (!det) return false;
150 TList* res = QATrender::GetSubList(det, "FitResults");
151 if (!res) return false;
153 ExtractYQuantity(res, Form("FMD%d%c_chi2", fD, fR), fChi2);
154 ExtractYQuantity(res, Form("FMD%d%c_c", fD, fR), fC);
155 ExtractYQuantity(res, Form("FMD%d%c_delta", fD, fR), fDelta);
156 ExtractYQuantity(res, Form("FMD%d%c_xi", fD, fR), fXi);
157 ExtractYQuantity(res, Form("FMD%d%c_sigma", fD, fR), fSigma);
159 TH1* status = QATrender::GetHistogram(res, "status");
160 if (!status) return false;
161 fFitStatus->nLow = UShort_t(status->GetBinContent(3));
162 fFitStatus->nCandidates = UShort_t(status->GetBinContent(4));
163 fFitStatus->nFitted = UShort_t(status->GetBinContent(5));
168 * Process data on neighbors
170 * @param parent Parent list
171 * @param p (optional) Pad to draw
173 * @return true on success
175 Bool_t ProcessNeighbors(const TList* parent, TVirtualPad* p)
177 if (!p) return true; // Case of no drawing
179 TList* det = GetDetectorList(parent);
180 if (!det) return false;
182 TH1* before = QATrender::GetHistogram(det, "neighborsBefore");
183 TH1* after = QATrender::GetHistogram(det, "neighborsAfter");
184 if (!before || !after) return false;
186 if (before->GetMaximum() > 0) p->SetLogz();
188 if (fD == 3) p->SetRightMargin(0.15);
190 before->SetTitle(Form("FMD%d%c",fD,fR));
191 before->Draw("colz");
192 after->Draw("same box");
194 before->GetXaxis()->SetRangeUser(-.5, 2);
195 before->GetYaxis()->SetRangeUser(-.5, 2);
197 TLatex* ltx = new TLatex(p->GetLeftMargin()+.01,
198 p->GetBottomMargin()+.01,
201 ltx->SetTextSize(.07);
207 * Process data on single, double, and triple hits
209 * @param parent Parent list
210 * @param p (optional) Pad to draw
212 * @return true on success
214 Bool_t Process123(const TList* parent, TVirtualPad* p)
216 TList* det = GetDetectorList(parent);
217 if (!det) return false;
223 TH1* one = QATrender::GetHistogram(det, "singleEloss");
224 TH1* two = QATrender::GetHistogram(det, "doubleEloss");
225 TH1* three = QATrender::GetHistogram(det, "tripleEloss");
226 if (!one || !two || !three) return false;
228 Int_t nOne = one->GetEntries();
229 Int_t nTwo = two->GetEntries();
230 Int_t nThree = three->GetEntries();
231 Int_t total = nOne + nTwo + nThree;
233 fMerge->one = Double_t(nOne) / total;
234 fMerge->two = Double_t(nTwo) / total;
235 fMerge->three = Double_t(nThree) / total;
241 one->SetTitle(Form("FMD%d%c", fD, fR));
242 one->GetXaxis()->SetRangeUser(0, 8);
244 if (one->GetMaximum() > 0) p->SetLogy();
246 if ((p->GetNumber() % 3) != 1) p->SetLeftMargin(.1);
248 one->SetLineStyle(1);
249 two->SetLineStyle(2);
250 three->SetLineStyle(3);
256 // Double_t ts = 0.03;
257 Double_t y = 1-p->GetTopMargin()-1.2*gStyle->GetTitleH(); // +ts;
258 Double_t x = p->GetLeftMargin() + .25;
259 TLatex* ltx = new TLatex(x, y, "Fraction of ...");
261 ltx->SetTextColor(kBlue+3);
262 ltx->SetTextAlign(13);
263 // ltx->SetTextAlign(33);
264 ltx->SetTextSize(.07);
268 DrawText(ltx, x, y, "Singles:", Form("%5.2f%%", fMerge->one * 100));
269 DrawText(ltx, x, y, "Doubles:", Form("%5.2f%%", fMerge->two * 100));
270 DrawText(ltx, x, y, "Triples:", Form("%5.2f%%", fMerge->three * 100));
277 * Process energy loss distributions
279 * @param p1 First parent list (sharing filter)
280 * @param p2 Second parent list (density calculator)
281 * @param p (optional) Pad to draw
283 * @return true on success
285 Bool_t ProcessELoss(TList* p1, TList* p2, TVirtualPad* p)
287 TList* det1 = GetDetectorList(p1);
288 if (!det1) return false;
290 TList* det2 = GetDetectorList(p2);
291 if (!det2) return false;
293 TH1* before = QATrender::GetHistogram(det1, "esdEloss");
294 TH1* after = QATrender::GetHistogram(det1, "anaEloss");
295 TH1* presented = QATrender::GetHistogram(det2, "eloss");
296 TH1* used = QATrender::GetHistogram(det2, "elossUsed");
298 if (!before || !after || !presented || !used) return false;
300 const Double_t lowCut = 0.15;
302 Int_t low = before->GetXaxis()->FindBin(lowCut);
303 Int_t ib = Int_t(before->Integral(low,before->GetNbinsX()));
304 Int_t ia = Int_t(after->Integral(low,after->GetNbinsX()));
305 Int_t ip = Int_t(presented->Integral(low,presented->GetNbinsX()));
306 Int_t iu = Int_t(used->Integral(low,used->GetNbinsX()));
308 Double_t dba = ib > 0 ? (100.*(ia-ib))/ib : 0;
309 Double_t dbp = ib > 0 ? (100.*(ip-ib))/ib : 0;
310 Double_t dbu = ib > 0 ? (100.*(iu-ib))/ib : 0;
311 Double_t dap = ia > 0 ? (100.*(ip-ia))/ia : 0;
312 Double_t dau = ia > 0 ? (100.*(iu-ia))/ia : 0;
313 Double_t dpu = ip > 0 ? (100.*(iu-ip))/ip : 0;
315 fDataLoss->merge = dba;
316 fDataLoss->density = dau;
317 fDataLoss->full = dbu;
321 if (before->GetMaximum() > 0) p->SetLogy();
323 before->SetTitle(Form("FMD%d%c",fD,fR));
325 before->SetLineStyle(1);
326 after->SetLineStyle(2);
327 used->SetLineStyle(3);
331 presented->Draw("same");
335 Double_t x = p->GetLeftMargin() + .25;
336 Double_t y = 1-p->GetTopMargin()-gStyle->GetTitleH()+ts;
337 TLatex* ltx = new TLatex(x, y, Form("FMD%d%c", fD, fR));
339 ltx->SetTextAlign(13);
340 ltx->SetTextSize(ts);
341 ltx->SetTextColor(kBlue+3);
343 // ltx->SetTextSize(.05);
344 TString inte(Form("Integral [%4.2f,#infty]", lowCut));
345 DrawText(ltx, x, y, Form("%s before:", inte.Data()), Form("%9d", ib));
346 DrawText(ltx, x, y, Form("%s after:", inte.Data()), Form("%9d", ia));
347 DrawText(ltx, x, y, Form("%s input:", inte.Data()), Form("%9d", ip));
348 DrawText(ltx, x, y, Form("%s user:", inte.Data()), Form("%9d", iu));
349 TLine* l = new TLine;
351 l->DrawLineNDC(x, y-0.9*ts, 1-p->GetRightMargin()-0.01, y-0.9*ts);
352 if (ib != 0 && ia != 0) {
353 DrawText(ltx, x, y, "Change (merging)", Form("%5.1f%%", dba));
354 DrawText(ltx, x, y, "Change (input)", Form("%5.1f%% (%5.1f%%)",
356 DrawText(ltx, x, y, "Change (use)", Form("%5.1f%% (%5.1f%%)",
359 before->GetXaxis()->SetRangeUser(0, 4);
365 * Process occupancy information
367 * @param parent Parent list
368 * @param p (optional) Pad to draw
370 * @return true on success
372 Bool_t ProcessOccupancy(const TList* parent, TVirtualPad* p)
374 TList* det = GetDetectorList(parent);
375 if (!det) return false;
377 TH1* occ = QATrender::GetHistogram(det, "occupancy");
378 if (!occ) return false;
380 fOccupancy->mean = occ->GetMean();
381 fOccupancy->var = occ->GetRMS();
385 for (Int_t i = occ->GetNbinsX(); i >= 1; i--) {
386 Double_t y = occ->GetBinContent(i);
387 if (y < 1e-6) continue;
388 fOccupancy->max = occ->GetXaxis()->GetBinUpEdge(i);
395 if (occ->GetMaximum() > 0) p->SetLogy();
397 p->SetRightMargin(0.01);
399 occ->SetTitle(Form("FMD%d%c", fD, fR));
402 // Double_t ts = 0.03;
403 Double_t y = 1-p->GetTopMargin()-1.2*gStyle->GetTitleH(); // +ts;
404 Double_t x = p->GetLeftMargin() + .25;
405 TLatex* ltx = new TLatex(x, y, "");
407 ltx->SetTextColor(kBlue+3);
408 ltx->SetTextAlign(13);
409 // ltx->SetTextAlign(33);
410 ltx->SetTextSize(.07);
414 DrawText(ltx, x, y, "Mean:", Form("%5.2f%%", fOccupancy->mean));
415 DrawText(ltx, x, y, "Variance:", Form("%5.2f%%", fOccupancy->var));
416 DrawText(ltx, x, y, "Max:", Form("%5.2f%%", fOccupancy->max));
423 * Process method correlations
425 * @param parent Parent list
426 * @param p (optional) Pad to draw
428 * @return true on success
430 Bool_t ProcessCorrelation(const TList* parent, TVirtualPad* p)
432 TList* det = GetDetectorList(parent);
433 if (!det) return false;
435 TH1* co = QATrender::GetHistogram(det, "elossVsPoisson");
436 if (!co) return false;
437 TH2* corr = static_cast<TH2*>(co);
439 fCorrelation->alpha = 0;
440 fCorrelation->beta = 0;
442 fCorrelation->ea = 0;
444 fCorrelation->eb = 0;
445 fCorrelation->chi2 = 0;
448 Double_t xmax = corr->GetXaxis()->GetXmax();
450 if (corr->GetEntries() > 0) {
451 // Calculate the linear regression
452 // Double_t dx = (xmax-xmin);
453 // Double_t rxy = corr->GetCorrelationFactor();
454 Double_t sx = corr->GetRMS(1);
455 Double_t sy = corr->GetRMS(2);
456 Double_t sx2 = sx*sx;
457 Double_t sy2 = sy*sy;
458 Double_t cxy = corr->GetCovariance();
459 Double_t mx = corr->GetMean(1);
460 Double_t my = corr->GetMean(2);
462 if (TMath::Abs(cxy) > 1e-6) {
463 fCorrelation->beta = ((sy2 - delta*sx2 +
464 TMath::Sqrt(TMath::Power(sy2-delta*sx2,2) +
465 4*delta*cxy*cxy)) / 2 / cxy);
466 fCorrelation->alpha = my - fCorrelation->beta * mx;
471 TLinearFitter* fitter = new TLinearFitter(1);
472 fitter->SetFormula("1 ++ x");
473 for (Int_t i = 1; i <= corr->GetNbinsX(); i++) {
474 Double_t x = corr->GetXaxis()->GetBinCenter(i);
475 if (x < -1 || x > xmax) continue;
476 for (Int_t j = 1; j <= corr->GetNbinsY(); j++) {
477 Double_t y = corr->GetYaxis()->GetBinCenter(j);
478 if (y < -1 || y > xmax) continue;
479 Double_t c = corr->GetBinContent(i,j);
480 if (c < .1) continue;
481 fitter->AddPoint(&x, y, c);
485 fCorrelation->a = fitter->GetParameter(0);
486 fCorrelation->ea = fitter->GetParError(0);
487 fCorrelation->b = fitter->GetParameter(1);
488 fCorrelation->eb = fitter->GetParError(1);
489 Double_t chi2 = fitter->GetChisquare();
490 Int_t ndf = (fitter->GetNpoints() -
491 fitter->GetNumberFreeParameters() );
492 fCorrelation->chi2 = chi2 / ndf;
499 if (corr->GetMaximum() > 0) p->SetLogz();
500 // if (fD == 3) p->SetRightMargin(0.15);
502 corr->GetXaxis()->SetRangeUser(-1,xmax);
503 corr->GetYaxis()->SetRangeUser(-1,xmax);
504 corr->SetTitle(Form("FMD%d%c",fD,fR));
507 TF1* f = new TF1("f", "[0]+[1]*x", xmin, xmax);
508 f->SetParameters(fCorrelation->alpha, fCorrelation->beta);
513 TLine* l = new TLine(-1,-1,xmax,xmax);
516 l->SetLineColor(kBlack);
519 Double_t x = p->GetLeftMargin() + .05;
520 Double_t y = 1-p->GetTopMargin()-gStyle->GetTitleH(); // +ts;
521 TLatex* ltx = new TLatex(x, y, "Deming regression: y=#alpha+#beta x");
523 ltx->SetTextAlign(13);
524 ltx->SetTextSize(0.06);
525 ltx->SetTextColor(kBlue+3);
528 DrawText(ltx, x, y, "#alpha:", Form("%5.3f", fCorrelation->alpha));
529 DrawText(ltx, x, y, "#beta:", Form("%5.3f", fCorrelation->beta));
532 DrawText(ltx, x, y, "A:", Form("%5.3f#pm%5.3f",
535 DrawText(ltx, x, y, "B:", Form("%5.3f#pm%5.3f",
538 DrawText(ltx, x, y, "#chi^{2}/#nu:", Form("%5.3f", fCorrelation->chi2));
546 /******************************************************************/
550 QATrender(Bool_t keep=false, Bool_t single=false)
555 fDensityCalculator(0),
560 fFMD1i = new Ring(1, 'I');
561 fFMD2i = new Ring(2, 'I');
562 fFMD2o = new Ring(2, 'O');
563 fFMD3i = new Ring(3, 'I');
564 fFMD3o = new Ring(3, 'O');
569 virtual ~QATrender() {}
574 QATrender(const QATrender& o)
576 fCurrentFile(o.fCurrentFile),
577 fSharingFilter(o.fSharingFilter),
578 fEventInspector(o.fEventInspector),
579 fDensityCalculator(o.fDensityCalculator),
580 fEnergyFitter(o.fEnergyFitter),
585 * Assignment operator
587 * @return Reference to this
589 QATrender operator=(const QATrender&) { return *this; }
592 // --- Interface ---------------------------------------------------
594 * Add a file to be processed
596 * @param filename Name of file
598 void AddFile(const char* filename)
600 fFiles.Add(new TObjString(filename));
611 while ((o = next())) {
612 ProcessOne(o->GetName());
622 if (!fOutput) return;
627 gSystem->Exec(Form("chmod g+rw %s", OutputName()));
630 * Process a single file
632 * @param filename File to open.
634 * @return true on success
636 Bool_t ProcessOne(const char* filename)
639 fCurrentFile->Close();
643 fCurrentFile = TFile::Open(filename, "READ");
645 Error("ProcessOne", "Failed to open %s", filename);
650 // Error("ProcessOne", "Failed to get lists from %s", filename);
654 if (!ProcessGlobal()) {
655 Error("ProcessOne", "Failed to get global stuff from %s", filename);
658 fTeXName = Form("qa_%09d", fGlobal->runNo);
659 MakeCanvas(Form("QA plots for run %d", fGlobal->runNo));
660 Bool_t eloss = ProcessELossFitter();
661 Bool_t merge = ProcessSharingFilter();
662 Bool_t dense = ProcessDensityCalculator();
663 if (fTree) fTree->Fill();
666 return eloss && merge && dense;
668 // --- Processing member functions ---------------------------------
672 * @return true on success
674 Bool_t ProcessGlobal()
676 TObject* oRun = GetObject(fEventInspector, "runNo");
677 if (!oRun) return false;
679 fGlobal->runNo = oRun->GetUniqueID();
680 TH1* oAcc = GetHistogram(fEventInspector,"nEventsAccepted");
681 if (!oAcc) return false;
683 fGlobal->nAccepted = oAcc->GetEntries();
684 fGlobal->meanVz = oAcc->GetMean();
685 fGlobal->sigmaVz = oAcc->GetRMS();
690 * Clean a stack for histograms that match @a what
692 * @param stack Stack to clean
693 * @param what Pattern
695 void CleanStack(THStack* stack, const char* what)
697 TList* l = stack->GetHists();
699 // Clean up list of histogram. Histograms with no entries or
700 // no functions are deleted. We have to do this using the TObjLink
701 // objects stored in the list since ROOT cannot guaranty the validity
702 // of iterators when removing from a list - tsck. Should just implement
704 TObjLink* lnk = l->FirstLink();
706 TObject* o = lnk->GetObject();
707 TString s(o->GetName());
708 if (s.Contains(what)) {
709 TObjLink* keep = lnk->Next();
718 * Process the information from the energy loss fitter
721 * @return true on succes
723 Bool_t ProcessELossFitter()
725 MakeCanvasTitle("Summary of energy loss fits");
727 THStack* chi2 = static_cast<THStack*>(GetObject(fEnergyFitter, "chi2"));
728 THStack* c = static_cast<THStack*>(GetObject(fEnergyFitter, "c"));
729 THStack* delta = static_cast<THStack*>(GetObject(fEnergyFitter, "delta"));
730 THStack* xi = static_cast<THStack*>(GetObject(fEnergyFitter, "xi"));
731 THStack* sigma = static_cast<THStack*>(GetObject(fEnergyFitter, "sigma"));
733 if (!chi2) return false;
734 if (!c) return false;
735 if (!delta) return false;
736 if (!xi) return false;
737 if (!sigma) return false;
739 CleanStack(chi2, "_n");
740 CleanStack(c, "status");
743 THStack* stacks[] = { chi2, c, delta, xi, sigma, 0 };
744 for (int i = 0; i < 5; i++) {
745 THStack* stack = stacks[i];
746 TVirtualPad* p = GetPad(i+1);
747 // stack->GetHists()->ls();
749 p->SetLeftMargin(.6/nL);
750 p->SetTopMargin(.01);
751 p->SetRightMargin(.01);
755 stack->Draw("nostack");
756 stack->GetHistogram()->SetYTitle(stack->GetTitle());
757 stack->GetHistogram()->SetXTitle("#eta");
759 TAxis* yaxis = stack->GetHistogram()->GetYaxis();
760 if (i == 0) yaxis->SetRangeUser(0,20); // Chi2
761 if (i == 1) stack->SetMaximum(1); // c
762 if (i == 2) stack->SetMaximum(1); // delta
763 if (i == 3) stack->SetMaximum(0.1); // xi
764 if (i == 4) stack->SetMaximum(0.5); // sigma{,n}
765 // if (i == 0) p->SetLogy();
766 yaxis->SetTitleSize(0.3/nL);
767 yaxis->SetLabelSize(0.08);
768 yaxis->SetTitleOffset(3/nL);
769 yaxis->SetNdivisions(5);
770 yaxis->SetTitleFont(42);
771 yaxis->SetLabelFont(42);
772 yaxis->SetDecimals();
774 TAxis* xaxis = stack->GetHistogram()->GetXaxis();
775 xaxis->SetTitleSize(0.3/nL);
776 xaxis->SetLabelSize(0.08);
777 xaxis->SetTitleOffset(2./nL);
778 xaxis->SetNdivisions(10);
779 xaxis->SetTitleFont(42);
780 xaxis->SetLabelFont(42);
781 xaxis->SetDecimals();
783 stack->Draw("nostack");
786 TVirtualPad* p = GetPad(6);
787 p->SetFillColor(kWhite);
790 TLatex* l = new TLatex(x, y, "Fits to #Delta (energy loss) spectra");
791 l->SetTextColor(kBlue+3);
795 y -= 2 * 1.2*l->GetTextSize();
796 l->DrawLatex(x, y, "F(#Delta;c,#Delta_{p},#xi,#sigma)="
797 "#frac{c}{#sqrt{2#pi}#sigma}#int_{-#infty}^{#infty}d#Delta'"
798 "L(#Delta;#Delta',#xi) G(#Delta_{p};#Delta',#sigma^{2})");
799 y -= 1.2*l->GetTextSize();
801 DrawText(l, x, y, "#chi^{2}/#nu", "Goodness of fit", .2);
802 DrawText(l, x, y, "c", "Overall constant", .2);
803 DrawText(l, x, y, "#Delta_{p}", "Most probable value", .2);
804 DrawText(l, x, y, "#xi", "'Width' of Landau (L)", .2);
805 DrawText(l, x, y, "#sigma", "'Width' of Gaussian (G)", .2);
807 // stack->GetHists()->ls();
809 PrintCanvas("fitResults", fGlobal->runNo);
812 static_cast<Ring*>(fFMD1i)->ProcessEnergyLoss(fEnergyFitter);
813 static_cast<Ring*>(fFMD2i)->ProcessEnergyLoss(fEnergyFitter);
814 static_cast<Ring*>(fFMD2o)->ProcessEnergyLoss(fEnergyFitter);
815 static_cast<Ring*>(fFMD3i)->ProcessEnergyLoss(fEnergyFitter);
816 static_cast<Ring*>(fFMD3o)->ProcessEnergyLoss(fEnergyFitter);
821 * Process the information from the sharing filter
824 * @return true on success
826 Bool_t ProcessSharingFilter()
828 // --- Neighbors -------------------------------------------------
829 MakeCanvasTitle("Correlation of neighboring strips");
831 for (Int_t i = 1; i <= 6; i++) {
832 TVirtualPad* p = GetPad(i);
834 Ring* r = GetRing(i);
837 r->ProcessNeighbors(fSharingFilter, p);
840 if ((p = GetPad(4))) {
841 p->SetFillColor(kWhite);
843 TLatex* l = new TLatex(.2, .7, "Gradient: before merging");
845 l->SetTextColor(kBlue+3);
847 l->DrawText(.2, .6, "Boxes: after merging");
850 PrintCanvas("neighbors", fGlobal->runNo);
853 // --- 123 -------------------------------------------------------
854 MakeCanvasTitle("#Delta for singles, doubles, and triples");
856 for (Int_t i = 1; i <= 6; i++) {
859 Ring* r = GetRing(i);
862 r->Process123(fSharingFilter, p);
864 if ((p = GetPad(4))) {
865 TLegend* ll = new TLegend(.2, .2, .8, .8);
867 ll->SetBorderSize(0);
868 TLegendEntry* e = ll->AddEntry("dummy", "Singles", "l");
870 e = ll->AddEntry("dummy", "Doubles", "l");
872 e = ll->AddEntry("dummy", "Triples", "l");
876 PrintCanvas("123", fGlobal->runNo);
881 * Process the information from the density calculator
884 * @return true on success
886 Bool_t ProcessDensityCalculator()
888 // --- ELoss -----------------------------------------------------
889 MakeCanvasTitle("Energy loss from ESD, after merging, used");
891 for (Int_t i = 1; i <= 6; i++) {
892 TVirtualPad* p = GetPad(i);
894 Ring* r = GetRing(i);
897 r->ProcessELoss(fSharingFilter, fDensityCalculator, p);
900 if ((p = GetPad(4))) {
901 TLegend* ll = new TLegend(.2, .2, .8, .8);
903 ll->SetBorderSize(0);
904 TLegendEntry* e = ll->AddEntry("dummy", "From ESDs", "l");
906 e = ll->AddEntry("dummy", "After Merging", "l");
908 e = ll->AddEntry("dummy", "Used", "l");
912 PrintCanvas("recAna", fGlobal->runNo);
915 // --- Occupancy -------------------------------------------------
916 MakeCanvasTitle("Occupancy");
918 for (Int_t i = 1; i <= 6; i++) {
921 Ring* r = GetRing(i);
924 r->ProcessOccupancy(fDensityCalculator, p);
926 if ((p = GetPad(4))) {
927 TLatex* ltx = new TLatex(.2, .8, "Calculated assuming Poisson stat.");
929 ltx->SetTextColor(kBlue+3);
932 TObject* etaL = GetObject(fDensityCalculator, "etaLumping");
933 TObject* phiL = GetObject(fDensityCalculator, "phiLumping");
935 ltx->DrawLatex(.2, .7, Form("Regions of %s strips #times %s sectors",
936 etaL->GetTitle(), phiL->GetTitle()));
938 PrintCanvas("occupancy", fGlobal->runNo);
941 // --- Correlation of methods ------------------------------------
942 MakeCanvasTitle("Correlation of N_{ch} methods");
944 for (Int_t i = 1; i <= 6; i++) {
947 Ring* r = GetRing(i);
950 r->ProcessCorrelation(fDensityCalculator, p);
952 if ((p = GetPad(4))) {
953 TLatex* ltx = new TLatex(.2, .8, "Correlation of N_{ch} methods");
955 ltx->SetTextColor(kBlue+3);
957 ltx->DrawLatex(.24, .7, "From #DeltaE fits along x");
958 ltx->DrawLatex(.24, .6, "From Poisson assumption along y");
959 ltx->DrawLatex(.24, .4, "Solid line: regression");
960 ltx->DrawLatex(.24, .3, "Dashed line: x=y to guide the eye");
962 PrintCanvas("elossVsPoisson", fGlobal->runNo);
968 // --- Utilities ---------------------------------------------------
970 * Close current file if open, and reset other pointers
976 fCurrentFile->Close();
980 fDensityCalculator = 0;
984 if (fSingle) keep = true;
988 * Get the ring corresponding to a pad
990 * @param padNo Pad number
992 * @return Pointer to ring
994 Ring* GetRing(Int_t padNo)
998 case 1: r = fFMD1i; break;
999 case 2: r = fFMD2i; break;
1000 case 3: r = fFMD3i; break;
1001 case 5: r = fFMD2o; break;
1002 case 6: r = fFMD3o; break;
1004 if (r) return static_cast<Ring*>(r);
1008 * Get the pad corresponding to a number. Also clears the pad
1010 * @param padNo Pad number to get
1012 * @return Pointer to pad or null
1014 TVirtualPad* GetPad(Int_t padNo)
1016 if (!fCanvas) return 0;
1017 TVirtualPad* p = fCanvas->cd(padNo);
1020 p->SetFillColor(kWhite);
1025 * Make canvas title. Canvas is divided into 3x2 pads
1027 * @param what Title on canvas
1029 void MakeCanvasTitle(const char* what)
1031 if (!fCanvas) return;
1035 fCanvas->Divide(3,2,0,0);
1037 // --- List utilities ----------------------------------------------
1039 * Get a sub-list from parent list
1041 * @param parent Parent list
1042 * @param name Name of sub-list
1044 * @return Pointer to the list
1046 static TList* GetSubList(const TList* parent, const char* name)
1048 TList* tmp = static_cast<TList*>(parent->FindObject(name));
1050 Error("GetLists", "List %s not found in %s", name,
1057 * Get the lists from the file
1060 * @return true on success
1064 if (!fCurrentFile) return 0;
1066 const char* folder = "ForwardResults";
1067 TList* forward = static_cast<TList*>(fCurrentFile->Get(folder));
1069 Error("GetLists", "List %s not found in %s", folder,
1070 fCurrentFile->GetName());
1074 fSharingFilter = GetSubList(forward, "fmdSharingFilter");
1075 fEventInspector = GetSubList(forward, "fmdEventInspector");
1076 fDensityCalculator = GetSubList(forward, "fmdDensityCalculator");
1077 fEnergyFitter = GetSubList(forward, "fmdEnergyFitter");
1079 if (!fSharingFilter) return false;
1080 if (!fEventInspector) return false;
1081 if (!fDensityCalculator) return false;
1082 if (!fEnergyFitter) return false;
1087 * Find and object in a list
1089 * @param list List to look in
1090 * @param name Name of object
1092 * @return Pointer to object or null
1094 static TObject* GetObject(const TList* list, const char* name)
1096 if (!list) return 0;
1097 TObject* o = list->FindObject(name);
1099 Error("GetObject", "Failed to find object %s in %s",
1100 name, list->GetName());
1106 * Get a histogram from a list
1109 * @param name Name of histogram
1111 * @return Pointer to object or null
1113 static TH1* GetHistogram(const TList* list, const char* name)
1115 return static_cast<TH1*>(GetObject(list, name));
1118 * Draw some text on a pad
1120 * @param l LaTeX object to use
1121 * @param x x coordinate
1122 * @param y y coordinate (incremented on return)
1123 * @param c1 First text
1124 * @param c2 Second text
1125 * @param dx Distance between c1 start and c2 start
1128 DrawText(TLatex* l, Double_t x, Double_t& y, const char* c1, const char* c2,
1131 y -= 1.2*l->GetTextSize();
1132 l->DrawLatex(x, y, c1);
1133 l->DrawLatex(x+dx, y, c2);
1137 // --- Members -----------------------------------------------------
1138 TFile* fCurrentFile; // Current input file
1139 TList* fSharingFilter; // Sharing filter list
1140 TList* fEventInspector; // Event inspector list
1141 TList* fDensityCalculator; // Density calculator list
1142 TList* fEnergyFitter; // Energy fitter list
1143 TList fFiles; // List of files to process
1144 Bool_t fKeep; // Keep PNGs