19 #include <TLegendEntry.h> 34 , fBandType(kSmallestInterval)
36 , fQuantileLineColor(kBlack)
38 , fDrawCentral68(true)
74 probsum[0] = probability;
77 fHistogram->GetQuantiles(nquantiles, quantiles, probsum);
90 if (
fBandType == kUserSpecified && intervals.size() == 1) {
91 BCLog::OutWarning(
"BCH1D::CheckIntervals : at least two intervals values must be specified for user-specified intervals. No bands will be drawn.");
102 std::vector<double> intervals;
111 if (nbands > 0) intervals.push_back(0.90);
112 if (nbands > 1) intervals.push_back(0.95);
113 if (nbands > 2) intervals.push_back(0.99);
114 for (
int i = 3; i < nbands; ++i)
115 intervals.push_back(0.9 + intervals.back() / 10.);
119 if (nbands > 0) intervals.push_back(0.10);
120 if (nbands > 1) intervals.push_back(0.05);
121 if (nbands > 2) intervals.push_back(0.01);
122 for (
int i = 3; i < nbands; ++i)
123 intervals.push_back(intervals.back() / 10.);
126 case kCentralInterval:
127 case kSmallestInterval:
145 if (intervals.empty())
148 unsigned nbands = intervals.size() - ((
fBandType == kUserSpecified) ? 1 : 0);
151 std::vector<std::pair<double, double> > bounds;
154 nbands = bounds.size();
162 for (
int i = nbands - 1; i >= 0; --i) {
164 TH1* hist_band = NULL;
165 std::string legend_text;
170 for (
int b = 1; b <= hist_band->GetNbinsX(); ++b)
171 if (hist_band->GetBinContent(b) < bounds[i].first)
172 hist_band->SetBinContent(b, 0);
173 legend_text =
"smallest %.1f%% interval(s)";
175 double p[2] = {0, 1};
180 legend_text =
"%.0f%% upper limit";
185 legend_text =
"%.0f%% lower limit";
190 p[1] = intervals[i + 1];
191 legend_text = Form(
"%%.1f%%%% interval from %.1f%%%% to %.1f%%%%", p[0] * 100, p[1] * 100);
194 case kCentralInterval:
196 p[0] = 0.5 - intervals[i] / 2;
197 p[1] = 0.5 + intervals[i] / 2;
198 legend_text =
"central %.1f%% interval";
213 hist_band->SetLineWidth(0);
214 hist_band->SetLineStyle(0);
215 hist_band->SetTitle(Form(legend_text.data(), hist_band->Integral(
"width") * 100));
218 hist_band->Draw(options.data());
245 std::vector<double> q(n - 1, 0);
246 std::vector<double> p(n - 1, 0);
247 for (
unsigned i = 1; i < n; ++i)
248 p[i - 1] = i * 1. / n;
249 if (
GetHistogram()->GetQuantiles(n - 1, &q[0], &p[0]) != (
int)n - 1)
252 TLine* quantile_line =
new TLine();
254 quantile_line->SetLineStyle(2);
257 double ymin = gPad->GetUymin();
258 double ymax = gPad->GetUymax();
259 if (gPad->GetLogy()) {
260 ymin = pow(10, ymin);
261 ymax = pow(10, ymax);
265 for (
unsigned i = 0; i < n - 1; ++i)
268 std::string quantile_text;
271 quantile_text =
"median";
274 quantile_text =
"terciles";
277 quantile_text =
"quartiles";
280 quantile_text =
"quintiles";
283 quantile_text =
"sextiles";
286 quantile_text =
"septiles";
289 quantile_text =
"octiles";
292 quantile_text =
"deciles";
295 quantile_text =
"duodeciles";
298 quantile_text =
"vigintiles";
301 quantile_text =
"percentiles";
304 quantile_text = Form(
"%d-quantiles", n);
316 double ymin = gPad->GetUymin();
317 double ymax = gPad->GetUymax();
318 double ymid = 0.5 * (ymin + ymax);
319 if (gPad->GetLogy()) {
320 ymin = pow(10, ymin);
321 ymax = pow(10, ymax);
322 ymid = pow(10, ymid);
325 TMarker* marker_median =
new TMarker(
GetMedian(), ymid * (
fLogy ? pow(ymax / ymin, -0.1) : 0.8), 21);
328 marker_median->SetMarkerSize(
fMarkerScale * gPad->GetWNDC());
329 marker_median->Draw();
331 TLegendEntry* le = 0;
332 double q[2], p[2] = {0.1587, 0.8413};
335 TArrow* arrow_ci =
new TArrow(q[0], ymid * (
fLogy ? pow(ymax / ymin, -0.1) : 0.8),
336 q[1], ymid * (
fLogy ? pow(ymax / ymin, -0.1) : 0.8),
337 0.02 * gPad->GetWNDC(),
"<|>");
339 arrow_ci->SetLineColor(marker_median->GetMarkerColor());
340 arrow_ci->SetFillColor(marker_median->GetMarkerColor());
342 le =
AddLegendEntry(arrow_ci,
"median and central 68% interval",
"PL");
343 le->SetLineColor(arrow_ci->GetLineColor());
346 le->SetMarkerStyle(marker_median->GetMarkerStyle());
347 le->SetMarkerSize(marker_median->GetMarkerSize());
348 le->SetMarkerColor(marker_median->GetMarkerColor());
362 if (max < xmin || min > xmax)
365 std::string newName(name);
367 newName = std::string(
GetHistogram()->GetName()) +
"_subhist";
369 if ( min <= xmin && max >= xmax ) {
372 min = std::max<double>(min, xmin);
373 max = std::min<double>(max, xmax);
375 int imin = (min > xmin) ?
GetHistogram()->FindFixBin(min) : 1;
379 std::vector<double> bins(
GetHistogram()->GetNbinsX() + 2, 0);
380 bins[0] = (preserve_range) ? xmin : min;
381 int i0 = (preserve_range) ? 2 : imin + 1;
382 int i1 = (preserve_range) ?
GetHistogram()->GetNbinsX() : imax;
384 for (
int i = i0; i <= i1; ++i) {
385 bins[n++] =
GetHistogram()->GetXaxis()->GetBinLowEdge(i);
391 if (preserve_range || max ==
GetHistogram()->GetXaxis()->GetBinUpEdge(i1))
392 bins[n++] =
GetHistogram()->GetXaxis()->GetBinUpEdge(i1);
400 imin = h0->FindFixBin(min);
401 imax = h0->FindFixBin(max);
402 for (
int i = imin; i <= imax; ++i)
413 double p[7] = {5e-2, 10e-2, 16e-2, 50e-2, 84e-2, 90e-2, 95e-2};
417 BCLog::OutSummary(prefix + Form(
"Mean +- sqrt(Variance): %+.*g +- %.*g", prec,
GetHistogram()->GetMean(), prec,
GetHistogram()->GetRMS()));
418 BCLog::OutSummary(prefix + Form(
"Median +- central 68%% interval: %+.*g + %.*g - %.*g", prec, q[3], prec, q[4] - q[3], prec, q[3] - q[2]));
419 BCLog::OutSummary(prefix + Form(
"(Marginalized) mode: %+.*g", prec,
GetLocalMode()));
420 BCLog::OutSummary(prefix + Form(
"%2.0f%% quantile: %+.*g", 100 * p[0], prec, q[0]));
421 BCLog::OutSummary(prefix + Form(
"%2.0f%% quantile: %+.*g", 100 * p[1], prec, q[1]));
422 BCLog::OutSummary(prefix + Form(
"%2.0f%% quantile: %+.*g", 100 * p[2], prec, q[2]));
423 BCLog::OutSummary(prefix + Form(
"%2.0f%% quantile: %+.*g", 100 * p[4], prec, q[4]));
424 BCLog::OutSummary(prefix + Form(
"%2.0f%% quantile: %+.*g", 100 * p[5], prec, q[5]));
425 BCLog::OutSummary(prefix + Form(
"%2.0f%% quantile: %+.*g", 100 * p[6], prec, q[6]));
428 for (
unsigned i = 0; i < v.size(); ++i)
435 BCLog::OutSummary(prefix + Form(
"Smallest interval%s containing %.1f%% and local mode%s:", (intervals.size() > 1 ?
"s" :
""), 100. * total_mass, (intervals.size() > 1 ?
"s" :
"")));
436 for (
unsigned i = 0; i < intervals.size(); ++i)
443 BCLog::OutSummary(prefix + Form(
"(%.*g, %.*g) (local mode at %.*g with rel. height %.*g; rel. area %.*g)",
447 prec, relative_height,
448 prec, relative_mass));
456 std::vector<BCH1D::BCH1DSmallestInterval> result;
458 for (
unsigned i = 0; i < bounds.size(); ++i) {
460 smallest_interval.total_mass = 0;
462 if (
GetHistogram()->GetBinContent(b) >= bounds[i].first) {
464 interval.xmin =
GetHistogram()->GetXaxis()->GetBinLowEdge(b);
465 interval.xmax =
GetHistogram()->GetXaxis()->GetBinUpEdge(b);
466 interval.relative_height =
GetHistogram()->GetBinContent(b);
468 interval.relative_mass +=
GetHistogram()->Integral(b, b,
"width");
470 interval.xmax =
GetHistogram()->GetXaxis()->GetBinUpEdge(++b);
471 interval.relative_mass +=
GetHistogram()->Integral(b, b,
"width");
472 if (
GetHistogram()->GetBinContent(b) > interval.relative_height) {
473 interval.relative_height =
GetHistogram()->GetBinContent(b);
477 smallest_interval.intervals.push_back(interval);
478 if (smallest_interval.total_mass == 0) {
479 smallest_interval.mode = interval.mode;
480 smallest_interval.max_val = interval.relative_height;
481 }
else if (interval.relative_height > smallest_interval.max_val) {
482 smallest_interval.mode = interval.mode;
483 smallest_interval.max_val = interval.relative_height;
485 smallest_interval.total_mass += interval.relative_mass;
487 for (
unsigned j = 0; j < smallest_interval.intervals.size(); ++j) {
488 smallest_interval.intervals[j].relative_mass /= smallest_interval.total_mass;
489 smallest_interval.intervals[j].relative_height /= smallest_interval.max_val;
491 result.push_back(smallest_interval);
497 BCH1D::BCH1DInterval::BCH1DInterval():
498 xmin(std::numeric_limits<double>::quiet_NaN()),
499 xmax(std::numeric_limits<double>::quiet_NaN()),
500 mode(std::numeric_limits<double>::quiet_NaN()),
507 BCH1D::BCH1DSmallestInterval::BCH1DSmallestInterval():
double fMarkerScale
Marker size scale.
std::vector< int > fBandColors
The colors of the color scheme.
unsigned fNQuantiles
Number of quantiles to draw.
virtual void DrawBands(const std::string &options="same")
Draw bands.
int GetQuantileLineColor()
virtual void DrawMarkers()
Draw markers (global mode, local mode, etc.).
T * OwnClone(const T *o)
Create a clone of the input but avoid registering the object with ROOT so it cannot be deleted twice...
void PrintSummary(const std::string &prefix="", unsigned prec=6) const
Print information to log.
double GetQuantile(double probability)
Returns the quantile of the distribution.
virtual std::vector< double > DefaultIntervals(int nbands=-1)
Return default intervals.
A guard object to prevent ROOT from taking over ownership of TNamed objects.
TH1 * GetSubHistogram(double min, double max, const std::string &name="", bool preserve_range=false)
Get histogram with bins outside min, max band being zero.
virtual void DrawMarkers()
Draw markers: global mode, local mode, mean, quantiles, median.
TLegendEntry * AddLegendEntry(TObject *obj, const std::string &label, const std::string &options)
Add legend entry, checking first for unused extra entries.
void CopyOptions(const BCH1D &other)
Copy options from other.
void PrintSummary(const std::string &prefix="", unsigned prec=6) const
Print information to log.
virtual void CheckIntervals(std::vector< double > &intervals)
Check intervals: remove values below 0 or above 1, and sort to proper order for band type...
virtual void CheckIntervals(std::vector< double > &intervals, int sort)
Check intervals: remove values below 0 or above 1.
BCH1D(const TH1 *const hist=0)
The default constructor.
int GetBandColor(int index) const
Returns a band color of the current color scheme.
virtual void CopyOptions(const BCHistogramBase &other)
Copy options from.
TH1 * fHistogram
The histogram.
std::vector< double > fIntervals
intervals to draw.
Contains information about an interval.
std::vector< std::pair< double, double > > GetSmallestIntervalBounds(std::vector< double > masses, bool overcoverage=true)
Get probability density levels bounding from below the smallest-interval levels with probability mass...
short GetBandFillStyle() const
BCHColorScheme
An enumerator for the color schemes.
A base class for drawing histograms in BAT style.
virtual void SetColorScheme(BCHColorScheme scheme)
Sets the color scheme.
virtual std::vector< double > DefaultIntervals(int nbands=-1)
Return default intervals.
bool fBandOvercoverage
flag for whether bands should overcover.
std::vector< TObject * > fROOTObjects
Storage for plot objects.
std::vector< BCH1D::BCH1DSmallestInterval > GetSmallestIntervals(std::vector< double > masses)
void SetQuantileLineColor(int c)
Set quantile line color.
void PrintSummary(const std::string &prefix="", unsigned prec=6, std::vector< double > intervals=std::vector< double >(0))
Print information to log.
bool fDrawMedian
flag for drawing median.
virtual void DrawQuantiles(unsigned n)
Draw quantiles.
int GetMarkerColor() const
Returns the marker colors (used for mean, median, and mode.
void SetColorScheme(BCHColorScheme scheme)
Sets the color scheme.
bool fDrawCentral68
flag for darwing central 68% interval arrows.
A class for handling 1D distributions.
Vector of intervals with information about total mass.
int fQuantileLineColor
Quantile line color.
virtual void DrawMedian()
Draw median & central 68% interval.
unsigned fNBands
Number of credibility interval bands to draw.
TLegendEntry * AddBandLegendEntry(TObject *obj, const std::string &label, const std::string &options)
Add band legend entry, creating unused extra entries if necessary.
BCH1DBandType fBandType
Band type.
bool fLogy
Flag for controlling log plotting of y axis.