//________________________________________________________ void GFHistManager::ColourStatsBoxes(GFHistArray *hists) const { // colours stats boxes like hists' line colors and moves the next to each other if (!hists) return; Double_t x1 = fStatsX1, x2 = fStatsX2, y1 = fStatsY1, y2 = fStatsY2; for (Int_t iH = 0; iH < hists->GetEntriesFast(); ++iH) { TH1 *h = hists->At(iH); if (!h) continue; TObject *statObj = h->GetListOfFunctions()->FindObject("stats"); if (statObj && statObj->InheritsFrom(TPaveStats::Class())) { TPaveStats *stats = static_cast<TPaveStats*>(statObj); stats->SetLineColor(hists->At(iH)->GetLineColor()); stats->SetTextColor(hists->At(iH)->GetLineColor()); stats->SetX1NDC(x1); stats->SetX2NDC(x2); stats->SetY1NDC(y1); stats->SetY2NDC(y2); y2 = y1 - 0.005; // shift down 2 y1 = y2 - (fStatsY2 - fStatsY1); // shift down 1 if (y1 < 0.) { y1 = fStatsY1; y2 = fStatsY2; // restart y-positions x2 = x1 - 0.005; // shift left 2 x1 = x2 - (fStatsX2 - fStatsX1); // shift left 1 if (x1 < 0.) { // give up, start again: x1 = fStatsX1, x2 = fStatsX2, y1 = fStatsY1, y2 = fStatsY2; } } } else if (gStyle->GetOptStat() != 0) { // failure in case changed in list via TExec.... this->Warning("ColourStatsBoxes", "No stats found for %s", hists->At(iH)->GetName()); } } }
//________________________________________________________ void GFHistManager::ColourFuncs(GFHistArray *hists) const { // adjust colour of funcs to match hist, but only if exactly one function per hist if (!hists) return; for (Int_t iH = 0; iH < hists->GetEntriesFast(); ++iH) { TH1 *h = hists->At(iH); if (!h) continue; // look for _the_ TF1 (not > 1!) TF1 *func = NULL; TIter nextprim(h->GetListOfFunctions()); while (TObject* next = nextprim()) { if (next->InheritsFrom(TF1::Class())) { if (func) { // there is already a TF1, so... func = NULL; // remove it again... break; // ...and stop searching for more! } else { func = static_cast<TF1*>(next); } } } // if exactly 1 found, adjust line style/colour if (func) { func->SetLineColor(h->GetLineColor()); func->SetLineStyle(h->GetLineStyle()); } } }
/** * Create ratios to other data * * @param ib Bin number * @param res Result * @param alice ALICE result if any * @param cms CMS result if any * @param all Stack to add ratio to */ void Ratio2Stack(Int_t ib, TH1* res, TGraph* alice, TGraph* cms, THStack* all) { if (!all || !res || !(alice || cms)) return; Int_t off = 5*ib; TGraph* gs[] = { (alice ? alice : cms), (alice ? cms : 0), 0 }; TGraph** pg = gs; while (*pg) { TGraph* g = *pg; const char* n = (g == alice ? "ALICE" : "CMS"); TH1* r = static_cast<TH1*>(res->Clone(Form("ratio%s", n))); TString tit(r->GetTitle()); tit.ReplaceAll("Corrected", Form("Ratio to %s", n)); r->SetTitle(tit); r->SetMarkerColor(g->GetMarkerColor()); r->SetLineColor(g->GetLineColor()); TObject* tst = r->FindObject("legend"); if (tst) r->GetListOfFunctions()->Remove(tst); for (Int_t i = 1; i <= r->GetNbinsX(); i++) { Double_t c = r->GetBinContent(i); Double_t e = r->GetBinError(i); Double_t o = g->Eval(r->GetBinCenter(i)); if (o < 1e-12) { r->SetBinContent(i, 0); r->SetBinError(i, 0); continue; } r->SetBinContent(i, (c - o) / o + off); r->SetBinError(i, e / o); } all->Add(r); pg++; } TLegend* leg = StackLegend(all); if (!leg) return; TString txt = res->GetTitle(); txt.ReplaceAll("Corrected P(#it{N}_{ch}) in ", ""); if (ib == 0) txt.Append(" "); // (#times1)"); // else if (ib == 1) txt.Append(" (#times10)"); else txt.Append(Form(" (+%d)", off)); TObject* dummy = 0; TLegendEntry* e = leg->AddEntry(dummy, txt, "p"); e->SetMarkerStyle(res->GetMarkerStyle()); e->SetMarkerSize(res->GetMarkerSize()); e->SetMarkerColor(kBlack); e->SetFillColor(0); e->SetFillStyle(0); e->SetLineColor(kBlack); }
Bool_t KVCanvas::ExpandFunctionRange() { Bool_t up = kFALSE; TH1* hh = FindHisto(); if (!hh) return up; TObject* obj = 0; TIter it(hh->GetListOfFunctions()); while ((obj = it())) { ((TF1*)obj)->SetRange(hh->GetXaxis()->GetXmin(), hh->GetXaxis()->GetXmax()); up = kTRUE; } return up; }
/** * Get or create a stack legend. This is done by adding a TLegend * object to the list of functions for the first histogram in the * stack. * * @param stack Stack to get the legend from/modify * * @return The legend object or null */ TLegend* StackLegend(THStack* stack) { TList* hists = stack->GetHists(); if (!hists) return 0; TObject* first = hists->First(); if (!first) return 0; TH1* hist = static_cast<TH1*>(first); TList* list = hist->GetListOfFunctions(); TObject* o = list->FindObject("legend"); if (o) return static_cast<TLegend*>(o); TLegend* l = new TLegend(0.65, 0.65, 0.9, 0.9, "", "NDC"); l->SetName("legend"); l->SetBorderSize(0); l->SetFillColor(0); l->SetFillStyle(0); l->SetTextFont(42); list->Add(l); return l; }
//________________________________________________________________ Bool_t KVCanvas::HandleKey(Int_t , Int_t py) { // Handle keys // Info("HandleKey","key pressed : %d %d",px,py); TObject* obj = 0; TIter next(GetListOfPrimitives()); if (!fEnabledShortcuts) return kTRUE; if (fSelected->InheritsFrom("TFrame")) fSelected = FindHisto(); if (fSelected->InheritsFrom("TH2")) fSelected = FindHisto(); if (!fSelected) return kTRUE; switch ((EKeySym)py) { case kKey_F1: break; case kKey_F2: break; case kKey_F3: break; case kKey_F4: break; case kKey_F5: break; case kKey_F6: break; case kKey_F7: break; case kKey_F8: break; case kKey_F9: SetLogx(!fLogx); Modified(); Update(); break; case kKey_F10: SetLogy(!fLogy); Modified(); Update(); break; case kKey_F11: SetLogz(!fLogz); Modified(); Update(); break; case kKey_F12: if (fSelected->InheritsFrom("TH1")) { gPad->cd(); ((TH1*)fSelected)->GetXaxis()->UnZoom(); ((TH1*)fSelected)->GetYaxis()->UnZoom(); Modified(); Update(); } else if (fSelected->InheritsFrom("TAxis")) { ((TAxis*)fSelected)->UnZoom(); Modified(); Update(); } break; case kKey_a: break; case kKey_b: break; case kKey_c: if (gCopyObject) { gCopyObject->Delete(); gCopyObject = 0; } if (fSelected) gCopyObject = fSelected->Clone(); // gCopyObject = fSelected; break; case kKey_d: if (fSelected->InheritsFrom("TF1")) { TH1* hh = 0; if ((hh = FindHisto())) hh->GetListOfFunctions()->Remove(fSelected); } else GetListOfPrimitives()->Remove(fSelected); Modified(); Update(); break; case kKey_e: GetCanvasImp()->ShowEditor(!GetCanvasImp()->HasEditor()); break; case kKey_f: if (fSelected->InheritsFrom("TH1"))((TH1*)fSelected)->FitPanel(); break; case kKey_g: if (GetGridx() && GetGridy()) { SetGrid(0, 0); while ((obj = next())) { if (obj->InheritsFrom(TPad::Class())) { ((TPad*)obj)->SetGrid(0, 0); } } } else { SetGrid(); while ((obj = next())) { if (obj->InheritsFrom(TPad::Class())) { ((TPad*)obj)->SetGrid(); } } } Modified(); Update(); break; case kKey_i: ShowShortcutsInfos(); break; case kKey_j: fJPressed = kTRUE; return kTRUE; break; case kKey_l: if (fSelected->InheritsFrom("TH2")) SetLogz(!fLogz); else if (fSelected->InheritsFrom("TH1")) SetLogy(!fLogy); Modified(); Update(); break; case kKey_n: if (fSelected->InheritsFrom("TH1")) { ((TH1*)fSelected)->Sumw2(); ((TH1*)fSelected)->Scale(1. / ((TH1*)fSelected)->Integral()); } Modified(); Update(); break; case kKey_p: fPPressed = kTRUE; return kTRUE; break; // case kKey_q: // Close(); // return kTRUE; // break; case kKey_r: if (ExpandFunctionRange()) { Modified(); Update(); } break; case kKey_s: SaveCanvasAs(); break; case kKey_t: break; case kKey_u: Modified(); Update(); break; case kKey_v: if (gCopyObject) { cd(); Modified(); Update(); TString option = ""; if (FindHisto()) option += "same"; gCopyObject->Draw(option.Data()); Modified(); Update(); gCopyObject = 0; } break; case kKey_w: fAgeOfEmpire = !fAgeOfEmpire; break; case kKey_x: if (fPPressed && fSelected->InheritsFrom("TH2")) ProfileX((TH2*)fSelected); if (fJPressed && fSelected->InheritsFrom("TH2")) ProjectionX((TH2*)fSelected); if (!fPPressed && !fJPressed) { gCopyObject = fSelected; GetListOfPrimitives()->Remove(gCopyObject); Modified(); Update(); } break; case kKey_y: if (fPPressed && fSelected->InheritsFrom("TH2")) ProfileY((TH2*)fSelected); if (fJPressed && fSelected->InheritsFrom("TH2")) ProjectionY((TH2*)fSelected); break; case kKey_Left: if (fSelected->InheritsFrom("TAxis")) MoveAxis((TAxis*)fSelected, -1); else if (fSelected->InheritsFrom("TH1")) MoveAxis(FindHisto()->GetXaxis(), -1); break; case kKey_Down: if (fSelected->InheritsFrom("TAxis")) MoveAxis((TAxis*)fSelected, -1); else if (fSelected->InheritsFrom("TH1")) MoveAxis(FindHisto()->GetYaxis(), -1); break; case kKey_Right: if (fSelected->InheritsFrom("TAxis")) MoveAxis((TAxis*)fSelected, 1); else if (fSelected->InheritsFrom("TH1")) MoveAxis(FindHisto()->GetXaxis(), 1); break; case kKey_Up: if (fSelected->InheritsFrom("TAxis")) MoveAxis((TAxis*)fSelected, 1); else if (fSelected->InheritsFrom("TH1")) MoveAxis(FindHisto()->GetYaxis(), 1); break; case kKey_Plus: if (fSelected->InheritsFrom("TH2")) { ((TH2*)fSelected)->SetMinimum(((TH1*)fSelected)->GetMinimum() + 1); Modified(); Update(); } else if (fSelected->InheritsFrom("TF1")) { ((TF1*)fSelected)->SetNpx(((TF1*)fSelected)->GetNpx() + 50); Modified(); Update(); } else if (fSelected->InheritsFrom("TH1")) { TObject* obj = 0; TIter it(((TH1*)fSelected)->GetListOfFunctions()); while ((obj = it())) { ((TF1*)obj)->SetNpx(((TF1*)obj)->GetNpx() + 50); } Modified(); Update(); } break; case kKey_Minus: if (fSelected->InheritsFrom("TH2")) { if (((TH1*)fSelected)->GetMinimum() > 0)((TH2*)fSelected)->SetMinimum(((TH1*)fSelected)->GetMinimum() - 1); Modified(); Update(); } else if (fSelected->InheritsFrom("TF1")) { ((TF1*)fSelected)->SetNpx(((TF1*)fSelected)->GetNpx() - 50); Modified(); Update(); } else if (fSelected->InheritsFrom("TH1")) { TObject* obj = 0; TIter it(((TH1*)fSelected)->GetListOfFunctions()); while ((obj = it()))((TF1*)obj)->SetNpx(((TF1*)obj)->GetNpx() - 50); Modified(); Update(); } break; case kKey_Space: break; default: fPPressed = kFALSE; fJPressed = kFALSE; return kTRUE; } fPPressed = kFALSE; fJPressed = kFALSE; return kTRUE; }
void check1SLimits( const char* workDir, // workDir: usual tag where to look for files in Output const char* lFileName="cLimits_683_NominalABCD_Asym_2SPL_woSyst.csv", // file name to save limits results bool dosyst = false, int mode = 1, // mode=0 -> pass, mode=1 -> prompt, mode=2 -> nonprompt const char* workDirFail="" ) { TString slFileName(lFileName); if ( dosyst && !slFileName.Contains("wSys") ) { cout << "Comparison requires systematics but limits file does not contain them" << endl; return; } // list of files set<anabin> thebins = allbins(); const char* ppp = "../Fitter"; // systematic uncertainties for fit map<anabin, syst> syst_All; if ( dosyst ) { if (mode==0) syst_All = readSyst_all_pass("",ppp,workDir); if (mode==1) syst_All = readSyst_all_prompt("",ppp,workDir,workDirFail); if (mode==2) syst_All = readSyst_all_nonprompt("",ppp,workDir,workDirFail); } // bin edges float ptmin, ptmax, ymin, ymax, centmin, centmax; // histo for 1sigma limits checks TH1* hCL = new TH1D("hOneSigmaCLComparison","",thebins.size(),0,thebins.size()); hCL->GetYaxis()->SetTitle("CL_{1#sigma}/#sigma"); hCL->GetYaxis()->SetTitleOffset(1.15); hCL->SetStats(0); hCL->SetDirectory(0); hCL->SetMarkerColor(1); hCL->SetMarkerStyle(20); hCL->SetMarkerSize(1); hCL->SetLineColor(1); TLine* l1 = new TLine(0.,1.,hCL->GetXaxis()->GetXmax(),1.); l1->SetLineWidth(3); hCL->GetListOfFunctions()->Add(l1); map<anabin,limits> maplim = readLimits(Form("csv/%s",slFileName.Data())); int cnt=1; for (set<anabin>::const_iterator it=thebins.begin(); it!=thebins.end(); it++) { cout << "Checking 1 sigma limits for analysis bin " << cnt << endl; anabin thebin = *it; ptmin = thebin.ptbin().low(); ptmax = thebin.ptbin().high(); ymin = thebin.rapbin().low(); ymax = thebin.rapbin().high(); centmin = thebin.centbin().low(); centmax = thebin.centbin().high(); double sigmaDoubleR = 0; double doubleR = 0; if (mode==0) { doubleR = doubleratio_pass_nominal(workDir,thebin,ppp); sigmaDoubleR = doubleratio_pass_stat(workDir,thebin,ppp); } if (mode==1) { doubleR = doubleratio_prompt_nominal(workDir,workDirFail,thebin,ppp); sigmaDoubleR = doubleratio_prompt_stat(workDir,workDirFail,thebin,ppp); } if (mode==2) { doubleR = doubleratio_nonprompt_nominal(workDir,workDirFail,thebin,ppp); sigmaDoubleR = doubleratio_nonprompt_stat(workDir,workDirFail,thebin,ppp); } double systAll=0; if ( dosyst ) { systAll = syst_All[thebin].value_dR; sigmaDoubleR = sqrt(pow(sigmaDoubleR,2)+pow(systAll,2)); } limits lim = maplim[thebin]; TString binName(Form("Pt[%.1f,%.1f]-Y[%.1f,%.1f]-C[%.1f,%.1f]",ptmin,ptmax,ymin,ymax,centmin,centmax)); double comp = -1.; if ( sigmaDoubleR != 0 ) comp = (lim.val.second-lim.val.first)/(2.*sigmaDoubleR); hCL->SetBinContent(cnt,comp); hCL->GetXaxis()->SetBinLabel(cnt,binName.Data()); cnt++; } // loop on the files TFile* fSave = new TFile("oneSigmaCLComparison.root","RECREATE"); TCanvas* c = new TCanvas("cOneSigmaCLComparison","",90,116,1265,535); c->Range(-3.690909,-0.01066472,33.30606,0.01252061); c->SetFillColor(0); c->SetBorderMode(0); c->SetBorderSize(2); c->SetRightMargin(0.1163896); c->SetTopMargin(0.03732809); c->SetBottomMargin(0.1630648); c->SetFrameBorderMode(0); c->SetFrameBorderMode(0); gPad->SetGridx(); gPad->SetGridy(); hCL->Draw("p"); c->Write("cOneSigmaCLComparison", TObject::kOverwrite | TObject::kSingleKey); fSave->Close(); delete fSave; }
//------------------------------------------------------------------------------ void PlotAlignmentValidation::plotSubDetResiduals(bool plotNormHisto,unsigned int subDetId) { setNiceStyle(); gStyle->SetOptStat(11111); gStyle->SetOptFit(0000); TCanvas *c = new TCanvas("c", "c", 600,600); c->SetTopMargin(0.15); TString histoName= ""; if (plotNormHisto) {histoName= "h_NormXprime";} else histoName= "h_Xprime_"; switch (subDetId){ case 1 : histoName+="TPBBarrel_0";break; case 2 : histoName+="TPEendcap_1";break; case 3 : histoName+="TPEendcap_2";break; case 4 : histoName+="TIBBarrel_0";break; case 5 : histoName+="TIDEndcap_1";break; case 6 : histoName+="TIDEndcap_2";break; case 7 : histoName+="TOBBarrel_3";break; case 8 : histoName+="TECEndcap_4";break; case 9 : histoName+="TECEndcap_5";break; } int tmpcounter = 0; TH1 *sumHisto = 0; for(std::vector<TkOfflineVariables*>::iterator it = sourceList.begin(); it != sourceList.end(); ++it) { if (tmpcounter == 0 ) { TFile *f= (*it)->getFile(); sumHisto =(TH1*) f->FindKeyAny(histoName)->ReadObj();//FindObjectAny(histoName.Data()); sumHisto->SetLineColor(tmpcounter+1); sumHisto->SetLineStyle(tmpcounter+1); sumHisto->GetFunction("tmp")->SetBit(TF1::kNotDraw); sumHisto->Draw(); //get statistic box coordinate to plot all boxes one below the other //gStyle->SetStatY(0.91); //gStyle->SetStatW(0.15); //gStyle->SetStatBorderSize(1); //gStyle->SetStatH(0.10); tmpcounter++; } else { sumHisto = (TH1*) (*it)->getFile()->FindObjectAny(histoName); sumHisto->SetLineColor(tmpcounter+1); sumHisto->SetLineStyle(tmpcounter+1); sumHisto->GetFunction("tmp")->SetBit(TF1::kNotDraw); //hstack->Add(sumHisto); c->Update(); tmpcounter++; } TObject *statObj = sumHisto->GetListOfFunctions()->FindObject("stats"); if (statObj && statObj->InheritsFrom(TPaveStats::Class())) { TPaveStats *stats = static_cast<TPaveStats*>(statObj); stats->SetLineColor(tmpcounter+1); stats->SetTextColor(tmpcounter+1); stats->SetFillColor(10); stats->SetX1NDC(0.91-tmpcounter*0.1); stats->SetX2NDC(0.15); stats->SetY1NDC(1); stats->SetY2NDC(0.10); sumHisto->Draw("sames"); } } //hstack->Draw("nostack"); char PlotName[1000]; sprintf( PlotName, "%s/%s.eps", outputDir.c_str(), histoName.Data() ); c->Print(PlotName); //delete c; //c=0; }
void EMCDistribution_PeakSample_Fast(bool full_gain = false) { const TString gain = "RAW"; TString hname = "EMCDistribution_" + gain + TString(full_gain ? "_FullGain" : "") + cuts; TH2 *h2 = NULL; { if (full_gain) { h2 = new TH2F(hname, Form(";Calibrated Tower Energy Sum (ADC);Count / bin"), 100, .05 * 100, 25 * 100, 64, -.5, 63.5); QAHistManagerDef::useLogBins(h2->GetXaxis()); } else { h2 = new TH2F(hname, Form(";Calibrated Tower Energy Sum (ADC);Count / bin"), 260, -.2 * 100, 5 * 100, 64, -.5, 63.5); } T->Draw( "TOWER_" + gain + "_CEMC[].get_bineta() + 8* TOWER_" + gain + "_CEMC[].get_binphi():(TOWER_RAW_CEMC[].signal_samples[10] - TOWER_RAW_CEMC[].signal_samples[0])*(-1)>>" + hname, "", "goff"); } TText *t; TCanvas *c1 = new TCanvas( "EMCDistribution_PeakSample_Fast_" + TString(full_gain ? "_FullGain" : "") + cuts, "EMCDistribution_PeakSample_Fast_" + TString(full_gain ? "_FullGain" : "") + cuts, 1800, 950); c1->Divide(8, 8, 0., 0.01); int idx = 1; TPad *p; for (int iphi = 8 - 1; iphi >= 0; iphi--) { for (int ieta = 0; ieta < 8; ieta++) { p = (TPad *) c1->cd(idx++); c1->Update(); p->SetLogy(); if (full_gain) { p->SetLogx(); } p->SetGridx(0); p->SetGridy(0); TString hname = Form("hEnergy_ieta%d_iphi%d", ieta, iphi) + TString(full_gain ? "_FullGain" : ""); TH1 *h = h2->ProjectionX(hname, ieta + 8 * iphi + 1, ieta + 8 * iphi + 1); // axis bin number is encoded as ieta+8*iphi+1 h->SetLineWidth(0); h->SetLineColor(kBlue + 3); h->SetFillColor(kBlue + 3); h->GetXaxis()->SetTitleSize(.09); h->GetXaxis()->SetLabelSize(.08); h->GetYaxis()->SetLabelSize(.08); h->Draw(); if (full_gain) h->Fit("x*gaus", "M"); else h->Fit("landau", "M"); double peak = -1; TF1 *fit = ((TF1 *) (h->GetListOfFunctions()->At(0))); if (fit) { fit->SetLineColor(kRed); peak = fit->GetParameter(1); } cout << Form("Finished <Col%d Row%d> = %.1f", ieta, iphi, peak) << endl; TText *t = new TText(.9, .9, Form("<Col%d Row%d> = %.1f", ieta, iphi, peak)); t->SetTextAlign(33); t->SetTextSize(.15); t->SetNDC(); t->Draw(); } } SaveCanvas(c1, TString(_file0->GetName()) + TString("_DrawPrototype3EMCalTower_") + TString(c1->GetName()), false); }
TH1* GetCentK(TDirectory* top, Double_t c1, Double_t c2, Int_t s, TLegend* l) { TString dname; dname.Form("cent%06.2f_%06.2f", c1, c2); dname.ReplaceAll(".", "d"); TDirectory* d = top->GetDirectory(dname); if (!d) { Warning("GetCetnK", "Directory %s not found in %s", dname.Data(), top->GetName()); return; } TDirectory* det = d->GetDirectory("details"); if (!det) { Warning("GetCetnK", "Directory details not found in %s", d->GetName()); d->ls(); return; } TObject* o = det->Get("scalar"); if (!o) { Warning("GetCetnK", "Object scalar not found in %s", det->GetName()); return; } if (!o->IsA()->InheritsFrom(TH1::Class())) { Warning("GetCetnK", "Object %s is not a TH1, but a %s", o->GetName(), o->ClassName()); return; } TH1* h = static_cast<TH1*>(o->Clone()); Color_t col = cc[(s-1)%10]; h->SetLineColor(col); h->SetMarkerColor(col); h->SetFillColor(col); h->SetFillStyle(1001); // h->SetTitle(Form("%5.2f-%5.2f%% #times %d", c1, c2, s)); h->SetTitle(Form("%2.0f-%2.0f%% + %d", c1, c2, s-1)); TF1* f = new TF1("", "[0]",-2.2,2.2); f->SetParameter(0,s-1); f->SetLineColor(col); f->SetLineStyle(7); f->SetLineWidth(1); // h->Scale(s); h->Add(f); h->GetListOfFunctions()->Add(f); f->SetParameter(0,s); for (Int_t i = 1; i <= h->GetNbinsX(); i++) { if (TMath::Abs(h->GetBinCenter(i)) > 2) { h->SetBinContent(i,0); h->SetBinError(i,0); } } TLegendEntry* e = l->AddEntry(h, h->GetTitle(), "f"); e->SetFillColor(col); e->SetFillStyle(1001); e->SetLineColor(col); return h; }
/** * Add the bin histograms to our summary stacks * * @param bin Bin stack * @param i Current off-set in the stacks * @param measured All measured @f$ P(N_{ch})@f$ * @param truth All MC truth @f$ P(N_{ch})@f$ * @param accepted All MC accepted @f$ P(N_{ch})@f$ * @param unfolded All unfolded @f$ P(N_{ch})@f$ * @param corrected All corrected @f$ P(N_{ch})@f$ * @param result The result in this bin */ void Bin2Stack(const THStack* bin, Int_t i, THStack* measured, THStack* truth, THStack* accepted, THStack* unfolded, THStack* corrected, TH1*& result) { Int_t open, closed; Double_t factor; Float_t size; BinAttributes(i, open, closed, size, factor); TIter next(bin->GetHists()); TH1* h = 0; while ((h = static_cast<TH1*>(next()))) { THStack* tmp = 0; Int_t col = h->GetMarkerColor(); Int_t sty = 0; switch (col) { case kColorMeasured: tmp = measured; sty = closed; break; case kColorTruth: tmp = truth; sty = open; break; case kColorAccepted: tmp = accepted; sty = open; break; case kColorUnfolded: tmp = unfolded; sty = closed; break; case kColorCorrected: tmp = corrected; sty = closed; break; default: continue; } // Now clone, and add to the appropriate stack TH1* cln = static_cast<TH1*>(h->Clone(h->GetName())); cln->SetDirectory(0); cln->SetMarkerStyle(sty); cln->SetMarkerSize(size); cln->Scale(factor); // Scale by 10^i if (col == kColorCorrected) result = cln; // Make sure we do not get the old legend TObject* tst = cln->FindObject("legend"); if (tst) cln->GetListOfFunctions()->Remove(tst); tmp->Add(cln, next.GetOption()); } // Add entries to our stacks TString txt = bin->GetTitle(); if (i == 0) txt.Append(" (#times1)"); else if (i == 1) txt.Append(" (#times10)"); else txt.Append(Form(" (#times10^{%d})", i)); THStack* stacks[] = { measured, truth, accepted, unfolded, corrected, 0 }; THStack** pstack = stacks; while (*pstack) { TLegend* leg = StackLegend(*pstack); pstack++; if (!leg) continue; TObject* dummy = 0; TLegendEntry* e = leg->AddEntry(dummy, txt, "p"); e->SetMarkerStyle(closed); e->SetMarkerSize(1.2*size); e->SetMarkerColor(kBlack); e->SetFillColor(0); e->SetFillStyle(0); e->SetLineColor(kBlack); } }