21 #include <TPolyLine.h>
22 #include <TPaveLabel.h>
29 #include <TLegendEntry.h>
34 unsigned int BCH1D::fHCounter=0;
39 , fDefaultCLLimit(95.)
47 for (
unsigned i = 0; i < fROOTObjects.size(); ++i)
48 delete fROOTObjects[i];
54 return fHistogram->GetBinCenter(fHistogram->GetMaximumBin());
64 probsum[0] = probability;
67 fHistogram->GetQuantiles(nquantiles, quantiles, probsum);
77 int binmin = fHistogram->FindBin(valuemin);
78 int binmax = fHistogram->FindBin(valuemax);
81 integral = fHistogram->Integral(binmin, binmax);
90 return fHistogram->Integral(1, fHistogram->FindBin(probability));
97 if(limit>=100. || limit<68.)
99 Form(
"BCH1D::SetDefaultCLLimit : Value %.1f out of range. Keeping default %.1f%% CL limit.",limit,fDefaultCLLimit));
103 fDefaultCLLimit = limit;
117 fColors.push_back(18);
118 fColors.push_back(16);
119 fColors.push_back(14);
120 fColors.push_back(kBlack);
121 fColors.push_back(kBlack);
123 else if (scheme == 1) {
124 fColors.push_back(kGreen);
125 fColors.push_back(kYellow);
126 fColors.push_back(kRed);
127 fColors.push_back(kBlack);
128 fColors.push_back(kBlack);
130 else if (scheme == 2) {
131 fColors.push_back(kBlue+4);
132 fColors.push_back(kBlue+2);
133 fColors.push_back(kBlue);
134 fColors.push_back(kOrange);
135 fColors.push_back(kOrange);
137 else if (scheme == 3) {
138 fColors.push_back(kRed+4);
139 fColors.push_back(kRed+2);
140 fColors.push_back(kRed);
141 fColors.push_back(kGreen);
142 fColors.push_back(kGreen);
150 void BCH1D::Print(
const char* filename, std::string options, std::vector<double> intervals,
int ww,
int wh)
154 while(i<255 && *filename!=
'\0')
155 file[i++]=*filename++;
159 bool flag_logx =
false;
160 bool flag_logy =
false;
161 bool flag_rescale =
false;
164 if (options.find(
"logx") < options.size()) {
168 if (options.find(
"logy") < options.size()) {
172 if (options.find(
"R") < options.size()) {
178 unsigned int cindex = getNextIndex();
180 c =
new TCanvas(TString::Format(
"c_bch1d_%d",cindex), TString::Format(
"c_bch1d_%d",cindex), ww, wh);
182 c =
new TCanvas(TString::Format(
"c_bch1d_%d",cindex));
185 fROOTObjects.push_back(c);
199 Draw(options, intervals);
202 double top = gPad->GetTopMargin();
203 double bottom = gPad->GetBottomMargin();
204 double left = gPad->GetLeftMargin();
205 double right = gPad->GetRightMargin();
207 double dx = 1.-right - left;
208 double dy = 1.-top-bottom;
209 double ratio = dy/dx;
210 double ynew = c->GetWindowWidth()/ratio;
211 c->SetCanvasSize(c->GetWindowWidth(), (int) (ynew + 0.5));
223 void BCH1D::Print(
const char* filename, std::string options,
double interval,
int ww,
int wh)
225 std::vector<double> tempvec;
226 tempvec.push_back(interval);
227 Print(filename, options, tempvec, ww, wh);
231 void BCH1D::Draw(std::string options, std::vector<double> intervals)
234 bool flag_legend =
false;
235 bool flag_logy =
false;
236 bool flag_mode =
false;
237 bool flag_median =
false;
238 bool flag_mean =
false;
239 bool flag_quartiles =
false;
240 bool flag_deciles =
false;
241 bool flag_percentiles =
false;
242 bool flag_smooth1 =
false;
243 bool flag_smooth3 =
false;
244 bool flag_smooth5 =
false;
245 bool flag_smooth10 =
false;
254 std::string draw_options =
"";
257 if (options.find(
"smooth1") < options.size()) {
261 if (options.find(
"smooth3") < options.size()) {
265 if (options.find(
"smooth5") < options.size()) {
269 if (options.find(
"smooth10") < options.size()) {
270 flag_smooth10 =
true;
273 if (options.find(
"same") < options.size()) {
274 draw_options.append(
"SAME");
277 if (options.find(
"logy") < options.size()) {
281 if (options.find(
"L") < options.size()) {
285 if (options.find(
"D1") < options.size()) {
286 draw_options.append(
"C");
289 if (options.find(
"BTsi") < options.size()) {
292 else if (options.find(
"BTul") < options.size()) {
295 else if (options.find(
"BTll") < options.size()) {
302 if (options.find(
"B1") < options.size()) {
304 if (bandtype == 0 && intervals.size() != 2) {
306 intervals.push_back(0.1587);
307 intervals.push_back(0.8413);
309 else if (bandtype == 1 && intervals.size() != 1) {
311 intervals.push_back(0.6827);
313 else if (bandtype == 2 && intervals.size() != 1) {
315 intervals.push_back(0.90);
317 else if (bandtype == 3 && intervals.size() != 1) {
319 intervals.push_back(0.10);
323 if (options.find(
"B2") < options.size()) {
325 if (bandtype == 0 && intervals.size() != 4) {
327 intervals.push_back(0.1587);
328 intervals.push_back(0.8413);
329 intervals.push_back(0.0228);
330 intervals.push_back(0.9772);
332 else if (bandtype == 1 && intervals.size() != 2) {
334 intervals.push_back(0.6827);
335 intervals.push_back(0.9545);
337 else if (bandtype == 2 && intervals.size() != 2) {
339 intervals.push_back(0.90);
340 intervals.push_back(0.95);
342 else if (bandtype == 3 && intervals.size() != 2) {
344 intervals.push_back(0.10);
345 intervals.push_back(0.05);
349 if (options.find(
"B3") < options.size()) {
351 if (bandtype == 0 && intervals.size() != 6) {
353 intervals.push_back(0.1587);
354 intervals.push_back(0.8413);
355 intervals.push_back(0.0228);
356 intervals.push_back(0.9772);
357 intervals.push_back(0.0013);
358 intervals.push_back(0.9987);
360 else if (bandtype == 1 && intervals.size() != 3) {
362 intervals.push_back(0.6827);
363 intervals.push_back(0.9545);
364 intervals.push_back(0.9973);
366 else if (bandtype == 2 && intervals.size() != 3) {
368 intervals.push_back(0.90);
369 intervals.push_back(0.95);
370 intervals.push_back(0.99);
372 else if (bandtype == 3 && intervals.size() != 3) {
374 intervals.push_back(0.10);
375 intervals.push_back(0.05);
376 intervals.push_back(0.01);
380 if (options.find(
"CS0") < options.size()) {
383 else if (options.find(
"CS1") < options.size()) {
386 else if (options.find(
"CS2") < options.size()) {
389 else if (options.find(
"CS3") < options.size()) {
396 if (options.find(
"mode") < options.size()) {
400 if (options.find(
"median") < options.size()) {
403 if (options.find(
"mean") < options.size()) {
406 if (options.find(
"quartiles") < options.size()) {
407 flag_quartiles =
true;
409 if (options.find(
"deciles") < options.size()) {
412 if (options.find(
"percentiles") < options.size()) {
413 flag_percentiles =
true;
417 fHistogram->Scale(1./fHistogram->Integral(
"width"));
420 TLegend* legend =
new TLegend();
421 legend->SetBorderSize(0);
422 legend->SetFillColor(kWhite);
423 legend->SetTextAlign(12);
424 legend->SetTextFont(62);
425 legend->SetTextSize(0.03);
428 fROOTObjects.push_back(legend);
432 fHistogram->Smooth(1);
433 fHistogram->Scale(1.0/fHistogram->Integral(
"width"));
436 fHistogram->Smooth(3);
437 fHistogram->Scale(1.0/fHistogram->Integral(
"width"));
441 fHistogram->Smooth(5);
442 fHistogram->Scale(1.0/fHistogram->Integral(
"width"));
445 fHistogram->Smooth(10);
446 fHistogram->Scale(1.0/fHistogram->Integral(
"width"));
450 fHistogram->Draw(draw_options.c_str());
453 for (
int i = 0; i < nbands; ++i) {
457 double prob_high = 0;
458 double prob_interval = 0;
462 TH1D * hist_band = 0;
465 prob_low = intervals[2*(nbands-i)-2];
466 prob_high = intervals[2*(nbands-i)-1];
469 prob_interval = prob_high - prob_low;
473 else if (bandtype == 1) {
476 for (
int ibin = 1; ibin <= hist_band->GetNbinsX(); ++ibin)
477 hist_band->SetBinContent(ibin, hist_band->GetBinContent(ibin)*fHistogram->GetBinContent(ibin));
479 else if(bandtype == 2) {
483 prob_interval = intervals[nbands-1-i];
485 else if(bandtype == 3) {
489 prob_interval = 1.-intervals[nbands-1-i];
493 hist_band->SetFillStyle(1001);
494 hist_band->SetFillColor(col);
495 hist_band->SetLineColor(col);
498 hist_band->Draw(std::string(draw_options+std::string(
"same")).c_str());
501 fHistogram->Draw(std::string(std::string(
"SAME")+draw_options).c_str());
504 std::string legend_label;
506 legend_label.append(Form(
"central %.1f%% interval ", prob_interval*100));
507 else if (bandtype == 1)
508 legend_label.append(Form(
"smallest %.1f%% interval(s)", prob_interval*100));
509 else if (bandtype == 2)
510 legend_label.append(Form(
"%.0f%% upper limit", prob_interval*100));
511 else if (bandtype == 3)
512 legend_label.append(Form(
"%.0f%% lower limit", prob_interval*100));
514 legend->AddEntry(hist_band, legend_label.c_str(),
"F");
517 fROOTObjects.push_back(hist_band);
524 double ymaxhist = fHistogram->GetBinContent(fHistogram->GetMaximumBin());
525 double ymax = ymaxhist;
529 ymin = 1e-4*ymaxhist;
532 TLine* line_quantiles =
new TLine();
533 line_quantiles->SetLineStyle(2);
534 line_quantiles->SetLineColor(
GetColor(3));
536 if (flag_quartiles) {
537 for (
int i = 1; i < 4; ++i) {
539 int quantile_xbin = fHistogram->FindBin(quantile_x);
540 double quantile_y = fHistogram->GetBinContent(quantile_xbin);
541 double quantile_ymin = 0;
543 quantile_ymin = 1e-4*ymaxhist;
544 line_quantiles->DrawLine(quantile_x, quantile_ymin, quantile_x, quantile_y);
546 TLegendEntry* le = legend->AddEntry(line_quantiles,
"quartiles",
"L");
550 le->SetFillColor(kWhite);
551 le->SetFillStyle(1001);
555 for (
int i = 1; i < 10; ++i) {
557 int quantile_xbin = fHistogram->FindBin(quantile_x);
558 double quantile_y = fHistogram->GetBinContent(quantile_xbin);
559 double quantile_ymin = 0;
561 quantile_ymin = 1e-4*ymaxhist;
562 line_quantiles->DrawLine(quantile_x, quantile_ymin, quantile_x, quantile_y);
564 TLegendEntry* le = legend->AddEntry(line_quantiles,
"deciles",
"FL");
566 le->SetFillStyle(1001);
569 if (flag_percentiles) {
570 for (
int i = 1; i < 100; ++i) {
572 int quantile_xbin = fHistogram->FindBin(quantile_x);
573 double quantile_y = fHistogram->GetBinContent(quantile_xbin);
574 double quantile_ymin = 0;
576 quantile_ymin = 1e-4*ymaxhist;
577 line_quantiles->DrawLine(quantile_x, quantile_ymin, quantile_x, quantile_y);
579 TLegendEntry* le = legend->AddEntry(line_quantiles,
"percentiles",
"L");
581 le->SetFillStyle(1001);
585 fROOTObjects.push_back(line_quantiles);
588 TMarker* marker_mode =
new TMarker(fMode, 0.50*ymaxhist, 24);
589 marker_mode->SetMarkerColor(
GetColor(4));
590 marker_mode->SetMarkerSize(1.5);
592 TMarker* marker_mean =
new TMarker(
GetMean(), 0.55*ymaxhist, 20);
593 marker_mean->SetMarkerColor(
GetColor(4));
594 marker_mean->SetMarkerSize(1.5);
596 TMarker* marker_median =
new TMarker(
GetMedian(), 0.45*ymaxhist, 21);
597 marker_median->SetMarkerColor(
GetColor(4));
598 marker_median->SetMarkerSize(1.5);
601 TArrow* arrow_mode =
new TArrow(fMode, 0.485*ymaxhist,
604 arrow_mode->SetLineColor(
GetColor(4));
605 arrow_mode->SetFillColor(
GetColor(4));
608 TArrow* arrow_std =
new TArrow(
GetMean()-
GetRMS(), 0.55*ymaxhist,
611 arrow_std->SetLineColor(
GetColor(4));
612 arrow_std->SetFillColor(
GetColor(4));
615 TArrow* arrow_ci =
new TArrow(
GetQuantile(0.1587), 0.45*ymaxhist,
618 arrow_ci->SetLineColor(
GetColor(4));
619 arrow_ci->SetFillColor(
GetColor(4));
622 fROOTObjects.push_back(marker_mode);
623 fROOTObjects.push_back(marker_mean);
624 fROOTObjects.push_back(marker_median);
625 fROOTObjects.push_back(arrow_std);
626 fROOTObjects.push_back(arrow_ci);
631 TLegendEntry* le = legend->AddEntry(marker_mode,
"global mode",
"P");
632 le->SetMarkerStyle(24);
633 le->SetMarkerSize(1.5);
640 TLegendEntry* le = legend->AddEntry(arrow_std,
"mean and standard deviation",
"PL");
642 le->SetMarkerStyle(20);
643 le->SetMarkerSize(1.5);
649 marker_median->Draw();
650 TLegendEntry* le = legend->AddEntry(arrow_ci,
"median and central 68.3% interval",
"PL");
652 le->SetMarkerStyle(21);
653 le->SetMarkerSize(1.5);
658 double height = 0.03*legend->GetNRows();
666 fHistogram->GetYaxis()->SetRangeUser(ymin, 1.05*ymaxhist);
671 gPad->SetTopMargin(0.02);
673 double xlegend1 = gPad->GetLeftMargin() + 0.10 * (1.0 - gPad->GetRightMargin() - gPad->GetLeftMargin());
674 double xlegend2 = 1.0-gPad->GetRightMargin();
675 double ylegend1 = 1.-gPad->GetTopMargin()-height;
676 double ylegend2 = 1.-gPad->GetTopMargin();
679 legend->SetX1NDC(xlegend1);
680 legend->SetX2NDC(xlegend2);
681 legend->SetY1NDC(ylegend1);
682 legend->SetY2NDC(ylegend2);
690 gPad->SetTopMargin(1.-ylegend1+0.01);
700 std::vector<double> tempvec;
701 tempvec.push_back(interval);
702 Draw(options, tempvec);
709 double xmin = fHistogram->GetXaxis()->GetXmin();
710 double xmax = fHistogram->GetXaxis()->GetXmax();
711 double ysize = 1.3 * fHistogram->GetMaximum();
713 TH2D* hsc =
new TH2D(
714 TString::Format(
"h2scale_%s_%d",fHistogram->GetName(),
BCLog::GetHIndex()),
"",
715 50, xmin, xmax, 10, 0., ysize);
717 hsc->SetXTitle(fHistogram->GetXaxis()->GetTitle());
718 hsc->SetYTitle(fHistogram->GetYaxis()->GetTitle());
723 TLatex * tmax_text =
new TLatex();
724 tmax_text->SetTextSize(0.035);
725 tmax_text->SetTextFont(62);
726 tmax_text->SetTextAlign(22);
728 double xprint=(xmax+xmin)/2.;
729 double yprint=ysize*(1-1.4*tmax_text->GetTextSize());
731 tmax_text->DrawLatex(xprint,yprint, TString::Format(
"%s = %g", fHistogram->GetXaxis()->GetTitle(), value));
735 TH1D * hist_temp =
new TH1D(TString::Format(
"h1scale_%s_%d", fHistogram->GetName(),
BCLog::GetHIndex()),
"", 100, xmin, xmax);
736 hist_temp->SetBinContent(hist_temp->FindBin(value), fHistogram->GetMaximum());
737 hist_temp->Draw(
"same");
738 fROOTObjects.push_back(hist_temp);
744 if(content<=0. || content>= 1.)
747 int nbins = fHistogram->GetNbinsX();
749 double factor = fHistogram->Integral(
"width");
754 fHistogram->Scale(1./factor);
756 double xmin = fHistogram->GetXaxis()->GetXmin();
757 double xmax = fHistogram->GetXaxis()->GetXmax();
758 double width = xmax - xmin;
766 double integral_out=0.;
769 for(
int i=1;i<nbins+1;i++)
771 if(fHistogram->Integral(i,nbins,
"width") < content)
775 double firstbinwidth = fHistogram->GetBinWidth(i);
779 for(
int j=0;j<ndiv;j++)
781 double dxdown = (double)(ndiv-j)/(double)ndiv * firstbinwidth;
782 xdown = fHistogram->GetBinLowEdge(i) + firstbinwidth - dxdown;
783 double integral = dxdown * fHistogram->GetBinContent(i);
788 xup = xdown + content / fHistogram->GetBinContent(i);
792 for(
int k=i+1;k<nbins+1;k++)
795 double thisbin = fHistogram->GetBinContent(k) * fHistogram->GetBinWidth(k);
797 if(integral+thisbin==content)
799 xup = fHistogram->GetBinLowEdge(k+1);
803 if(integral+thisbin>content)
805 xup = fHistogram->GetBinLowEdge(k) + (content-integral)/thisbin * fHistogram->GetBinWidth(k);
806 integral += thisbin * (xup-fHistogram->GetBinLowEdge(k))/fHistogram->GetBinWidth(k);
813 if(integral < content)
816 if(xup - xdown < width)
822 integral_out = integral;
830 Form(
"BCH1D::GetSmallestInterval : The requested content of %d%% fits within one bin.",(
int)(content*100)));
831 BCLog::OutWarning(
"BCH1D::GetSmallestInterval : MAKE FINER BINNING (OR CHANGE RANGE) !!!");
835 fHistogram->Scale(factor);
846 int imin = fHistogram->FindBin(min);
847 int imax = fHistogram->FindBin(max);
849 int nbins = fHistogram->GetNbinsX();
852 if ( imin<1 || imin>nbins || imax<1 || imax>nbins )
868 double first = ( fHistogram->GetBinLowEdge(imin+1) - min ) * fHistogram->GetBinContent(imin);
871 double last = ( max - fHistogram->GetBinLowEdge(imax) ) * fHistogram->GetBinContent(imax);
876 inbetween = fHistogram->Integral(imin+1, imax-1,
"width");
878 return first + inbetween + last;
891 int imin = fHistogram->FindBin(min);
892 int imax = fHistogram->FindBin(max);
894 int nbins = fHistogram->GetNbinsX();
895 double xmin = fHistogram->GetXaxis()->GetXmin();
896 double xmax = fHistogram->GetXaxis()->GetXmax();
898 if( min==max || (min<=xmin && max>=xmax) )
900 TH1D * h0 = (TH1D*) fHistogram->Clone(name);
915 std::vector<double> xb(nbins + 3);
921 for (
int i=1;i<nbins+2;i++)
923 double x0 = fHistogram->GetBinLowEdge(i);
945 TH1D * h0 =
new TH1D(name,
"",n-1, &xb[0]);
948 double x0 = h0->GetBinCenter(i);
952 int bin=fHistogram->FindBin(x0);
953 h0->SetBinContent(i, fHistogram->GetBinContent(bin));
963 TH1D * hist_yellow = (TH1D*) fHistogram->Clone();
964 hist_yellow->Reset();
965 hist_yellow->SetFillStyle(1001);
966 hist_yellow->SetFillColor(kYellow);
969 TH1D * hist_temp = (TH1D*) fHistogram->Clone(TString::Format(
"%s_%i",fHistogram->GetName(),
BCLog::GetHIndex()));
970 double factor = hist_temp->Integral(
"");
975 hist_temp->Scale(1. / factor);
984 double sumprob = 0.0;
986 while (sumprob < level)
989 int bin = hist_temp->GetMaximumBin();
990 double value = hist_temp->GetMaximum();
993 hist_yellow->SetBinContent(bin, 1.0);
996 hist_temp->SetBinContent(bin, 0.0);
1010 std::vector<double> v;
1014 int nbins = hist->GetNbinsX();
1018 double localmax = -1;
1019 double localmaxpos = -1;
1020 double localint = 0;
1023 for (
int i = 1; i <= nbins; ++i)
1026 if (!flag && hist->GetBinContent(i) > 0.)
1029 v.push_back(hist->GetBinLowEdge(i));
1035 localmax = fHistogram->GetBinContent(i);
1036 localmaxpos = hist->GetBinLowEdge(i);
1043 if ((flag && !(hist->GetBinContent(i) > 0.)) || (flag && i == nbins))
1046 v.push_back(hist->GetBinLowEdge(i) + hist->GetBinWidth(i));
1049 if (i == nbins && localmax < fHistogram->GetBinContent(i))
1050 localmaxpos = hist->GetBinCenter(i) + 0.5 * hist->GetBinWidth(i);
1057 v.push_back(localmax);
1058 v.push_back(localmaxpos);
1061 v.push_back(localint);
1065 if (i < nbins && localmax < fHistogram->GetBinContent(i))
1067 localmax = fHistogram->GetBinContent(i);
1068 localmaxpos = hist->GetBinCenter(i);
1072 localint += fHistogram->GetBinContent(i) / fHistogram->Integral();
1076 for (
int i = 0; i < ninter; ++i)
1077 v[i*5+2] = v.at(i*5+2) / max;
double GetPValue(double probability)
double GetIntegral(double valuemin, double valuemax)
TH1D * GetSubHisto(double min, double max, const char *name)
void DrawDelta(double value) const
void SetColorScheme(int scheme)
void Print(const char *filename, std::string options="BTsiB3CS1D0Lmeanmode", std::vector< double > intervals=std::vector< double >(0), int ww=0, int wh=0)
TH1D * GetSmallestIntervalHistogram(double level)
double IntegralWidth(double min, double max)
std::vector< double > GetSmallestIntervals(double content=0.68)
double GetSmallestInterval(double &min, double &max, double content=.68)
double GetQuantile(double probablity)
void SetDefaultCLLimit(double limit)
void Draw(std::string options="BTsiB3CS1D0Lmeanmode", std::vector< double > intervals=std::vector< double >(0))