Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions hist/hist/src/TAxis.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -477,15 +477,38 @@ Int_t TAxis::GetLast() const

////////////////////////////////////////////////////////////////////////////////
/// Return center of bin
///
/// If fXmin is -inf, it will return -inf even if fXmax is finite
/// If fXmax is +inf, it will return +inf even if fXmin is finite

Double_t TAxis::GetBinCenter(Int_t bin) const
{
Double_t binwidth;
if (!fXbins.fN || bin<1 || bin>fNbins) {
binwidth = (fXmax - fXmin) / Double_t(fNbins);
if (std::isinf(binwidth)) {
if (std::isfinite(fXmin))
return fXmax;
else if (std::isfinite(fXmax))
return fXmin;
else if (fXmin == -std::numeric_limits<double>::infinity() && fXmax == std::numeric_limits<double>::infinity())
return 0.;
else
return std::numeric_limits<double>::quiet_NaN();
}
return fXmin + (bin - 0.5) * binwidth;
} else {
binwidth = fXbins.fArray[bin] - fXbins.fArray[bin-1];
if (std::isinf(binwidth)) {
if (std::isfinite(fXbins.fArray[bin-1]))
return fXbins.fArray[bin];
else if (std::isfinite(fXbins.fArray[bin]))
return fXbins.fArray[bin-1];
else if (fXbins.fArray[bin-1] == -std::numeric_limits<double>::infinity() && fXbins.fArray[bin] == std::numeric_limits<double>::infinity())
return 0.;
else
return std::numeric_limits<double>::quiet_NaN();
}
return fXbins.fArray[bin-1] + 0.5*binwidth;
}
}
Expand Down
11 changes: 11 additions & 0 deletions hist/hist/src/TH1Merger.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,17 @@ Bool_t TH1Merger::AutoP2Merge()

Double_t xu = hist->GetBinCenter(ibin);
Int_t jbin = fH0->FindBin(xu);
if (jbin == fH0->GetXaxis()->GetNbins() + 1 || jbin == 0) {
auto eps = 1e-12;
// if upper/lower edge is +/-infinite, the bin center is +/-infinite if the other edge is finite,
// so FindBin is in overflow/underflow
// Check close to the lower or upper edges instead of the bin center in these cases
if (std::isinf(hist->GetXaxis()->GetBinUpEdge(ibin))) {
jbin = fH0->GetXaxis()->FindBin(hist->GetXaxis()->GetBinLowEdge(ibin) + eps);
} else if (std::isinf(hist->GetXaxis()->GetBinLowEdge(ibin))) {
jbin = fH0->GetXaxis()->FindBin(hist->GetXaxis()->GetBinUpEdge(ibin) - eps);
}
}

fH0->AddBinContent(jbin, cu);
if (fH0->fSumw2.fN)
Expand Down
17 changes: 15 additions & 2 deletions hist/hist/src/TH1Merger.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "TProfile2D.h"
#include "TProfile3D.h"
#include "TList.h"
#include <cmath>

class TH1Merger {

Expand All @@ -41,13 +42,25 @@ class TH1Merger {
return outAxis.FindFixBin(inAxis.GetBinCenter(ibin));
}

// find bin number estending the axis
/// find bin number extending the axis
static Int_t FindBinNumber(Int_t ibin, const TAxis & inAxis, TAxis & outAxis) {
// should I ceck in case of underflow/overflow if underflow/overflow values of input axis
// outside output axis ?
if (ibin == 0 ) return 0; // return underflow
if (ibin == inAxis.GetNbins()+1 ) return outAxis.GetNbins()+1; // return overflow
return outAxis.FindBin(inAxis.GetBinCenter(ibin));
auto binOut = outAxis.FindBin(inAxis.GetBinCenter(ibin));
if (binOut == outAxis.GetNbins() + 1 || binOut == 0) {
auto eps = 1e-12;
// if upper/lower edge is +/-infinite, the bin center is +/-infinite if the other edge is finite,
// so FindBin is in overflow/underflow
// Check close to the lower or upper edges instead of the bin center in these cases
if (std::isinf(inAxis.GetBinUpEdge(ibin))) {
binOut = outAxis.FindBin(inAxis.GetBinLowEdge(ibin) + eps);
} else if (std::isinf(inAxis.GetBinLowEdge(ibin))) {
binOut = outAxis.FindBin(inAxis.GetBinUpEdge(ibin) - eps);
}
}
return binOut;
}

// Function to find if axis label list has duplicates
Expand Down
13 changes: 12 additions & 1 deletion hist/hist/src/TH2.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2293,7 +2293,18 @@ TH1D *TH2::DoProjection(bool onX, const char *name, Int_t firstbin, Int_t lastbi
}
}
// find corresponding bin number in h1 for outbin
Int_t binOut = h1->GetXaxis()->FindBin( outAxis->GetBinCenter(outbin) );
Int_t binOut = h1->GetXaxis()->FindBin(outAxis->GetBinCenter(outbin));
if (binOut == h1->GetXaxis()->GetNbins() + 1 || binOut == 0) {
auto eps = 1e-12;
// if upper/lower edge is +/-infinite, the bin center is +/-infinite if the other edge is finite,
// so FindBin is in overflow/underflow
// Check close to the lower or upper edges instead of the bin center in these cases
if (std::isinf(outAxis->GetBinUpEdge(outbin))) {
binOut = h1->GetXaxis()->FindBin(outAxis->GetBinLowEdge(outbin) + eps);
} else if (std::isinf(outAxis->GetBinLowEdge(outbin))) {
binOut = h1->GetXaxis()->FindBin(outAxis->GetBinUpEdge(outbin) - eps);
}
}
h1->SetBinContent(binOut ,cont);
if (computeErrors) h1->SetBinError(binOut,TMath::Sqrt(err2));
// sum all content
Expand Down
38 changes: 35 additions & 3 deletions hist/hist/src/TH3.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2058,14 +2058,25 @@ TH1D *TH3::DoProject1D(const char* name, const char * title, const TAxis* projX,
}
}
}
Int_t ix = h1->FindBin( projX->GetBinCenter(ixbin) );
Int_t ix = h1->FindBin(projX->GetBinCenter(ixbin));
if (ix == h1->GetNbinsX() + 1 || ix == 0) {
auto eps = 1e-12;
// if upper/lower edge is +/-infinite, the bin center is +/-infinite if the other edge is finite,
// so FindBin is in overflow/underflow
// Check close to the lower or upper edges instead of the bin center in these cases
if (std::isinf(projX->GetBinUpEdge(ixbin))) {
ix = h1->FindBin(projX->GetBinLowEdge(ixbin) + eps);
} else if (std::isinf(projX->GetBinLowEdge(ixbin))) {
ix = h1->FindBin(projX->GetBinUpEdge(ixbin) - eps);
}
}
h1->SetBinContent(ix ,cont);
if (computeErrors) h1->SetBinError(ix, TMath::Sqrt(err2) );
// sum all content
totcont += cont;

}
if ( labels ) h1->GetXaxis()->SetCanExtend(extendable);
if (labels) h1->GetXaxis()->SetCanExtend(extendable);

// since we use a combination of fill and SetBinError we need to reset and recalculate the statistics
// for weighted histograms otherwise sumw2 will be wrong.
Expand Down Expand Up @@ -2267,11 +2278,32 @@ TH2D *TH3::DoProject2D(const char* name, const char * title, const TAxis* projX,

for (ixbin=0;ixbin<=1+projX->GetNbins();ixbin++) {
if ( projX->TestBit(TAxis::kAxisRange) && ( ixbin < ixmin || ixbin > ixmax )) continue;
Int_t ix = h2->GetYaxis()->FindBin( projX->GetBinCenter(ixbin) );
Int_t ix = h2->GetYaxis()->FindBin(projX->GetBinCenter(ixbin));
auto eps = 1e-12;
if (ix == h2->GetYaxis()->GetNbins() + 1 || ix == 0) {
// if upper/lower edge is +/-infinite, the bin center is +/-infinite if the other edge is finite,
// so FindBin is in overflow/underflow
// Check close to the lower or upper edges instead of the bin center in these cases
if (std::isinf(projX->GetBinUpEdge(ixbin))) {
ix = h2->GetYaxis()->FindBin(projX->GetBinLowEdge(ixbin) + eps);
} else if (std::isinf(projX->GetBinLowEdge(ixbin))) {
ix = h2->GetYaxis()->FindBin(projX->GetBinUpEdge(ixbin) - eps);
}
}

for (iybin=0;iybin<=1+projY->GetNbins();iybin++) {
if ( projY->TestBit(TAxis::kAxisRange) && ( iybin < iymin || iybin > iymax )) continue;
Int_t iy = h2->GetXaxis()->FindBin( projY->GetBinCenter(iybin) );
if (iy == h2->GetXaxis()->GetNbins() + 1 || iy == 0) {
// if upper/lower edge is +/-infinite, the bin center is +/-infinite if the other edge is finite,
// so FindBin is in overflow/underflow
// Check close to the lower or upper edges instead of the bin center in these cases
if (std::isinf(projY->GetBinUpEdge(iybin))) {
iy = h2->GetXaxis()->FindBin(projY->GetBinLowEdge(iybin) + eps);
} else if (std::isinf(projY->GetBinLowEdge(iybin))) {
iy = h2->GetXaxis()->FindBin(projY->GetBinUpEdge(iybin) - eps);
}
}

Double_t cont = 0;
Double_t err2 = 0;
Expand Down
21 changes: 21 additions & 0 deletions hist/hist/test/test_TH1.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <cstddef>
#include <random>
#include <vector>
#include <limits>

#include "ROOT/TestSupport.hxx"

Expand Down Expand Up @@ -320,3 +321,23 @@ TEST(TAxis, EqualBinEdges)
{
ROOT_EXPECT_ERROR(TAxis _({1, 1}), "TAxis::Set", "bins must be in increasing order");
}

TEST(TH2, ProjectionYInfiniteUpperEdge)
{
Double_t xedges[] = {0., 1.};
Double_t yedges[] = {1., std::numeric_limits<double>::infinity()};
TH2D h("h_inf", "h_inf;X;Y", 1, xedges, 1, yedges);
h.SetBinContent(1, 1, 11.);
auto projY = h.ProjectionY();
EXPECT_EQ(projY->GetBinContent(1), h.Integral(1, 1, 1, 1));
}

TEST(TH2, ProjectionYInfiniteLowerEdge)
{
Double_t xedges[] = {0, 1.};
Double_t yedges[] = {-std::numeric_limits<double>::infinity(), 2};
TH2D h("h_inf", "h_inf;X;Y", 1, xedges, 1, yedges);
h.SetBinContent(1, 1, 11.);
auto projY = h.ProjectionY();
EXPECT_EQ(projY->GetBinContent(1), h.Integral(1, 1, 1, 1));
}
Loading