Skip to content
Merged
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
4 changes: 2 additions & 2 deletions bindings/pyroot/pythonizations/test/th2.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ class TH2UsingDecls(unittest.TestCase):

# Tests
def test_GetBinError(self):
h = ROOT.TH2F("h", "h", 1, 1, 0, 1, 0, 1)
h = ROOT.TH2F("h", "h", 1, 0, 1, 1, 0, 1)
for _ in range(4):
h.Fill(1, 1, 1)
h.Fill(0.5, 0.5, 1)
self.assertEqual(h.GetBinErrorUp(1, 1), 2)
self.assertEqual(h.GetBinErrorLow(1, 1), 2)

Expand Down
10 changes: 6 additions & 4 deletions hist/hist/inc/THLimitsFinder.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ class THLimitsFinder : public TObject {
THLimitsFinder();
~THLimitsFinder() override;
virtual Int_t FindGoodLimits(TH1 *h, Double_t xmin, Double_t xmax);
virtual Int_t FindGoodLimits(TH1 *h, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax);
virtual Int_t FindGoodLimits(TH1 *h, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax);
virtual Int_t FindGoodLimitsXY(TH1 *h, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax,
Int_t newbinsx = 0, Int_t newbinsy = 0);
virtual Int_t FindGoodLimitsXYZ(TH1 *h, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax,
Int_t newbinsx = 0, Int_t newbinsy = 0, Int_t newbinsz = 0);

static void Optimize(Double_t A1, Double_t A2, Int_t nold
,Double_t &BinLow, Double_t &BinHigh, Int_t &nbins, Double_t &BWID, Option_t *option="");
static void Optimize(Double_t A1, Double_t A2, Int_t nold,
Double_t &BinLow, Double_t &BinHigh, Int_t &nbins, Double_t &BWID, Option_t *option="");
static void OptimizeLimits(Int_t nbins, Int_t &newbins, Double_t &xmin, Double_t &xmax, Bool_t isInteger);
static THLimitsFinder *GetLimitsFinder();
static void SetLimitsFinder(THLimitsFinder *finder);
Expand Down
33 changes: 20 additions & 13 deletions hist/hist/src/TH2.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -260,22 +260,29 @@ Int_t TH2::BufferEmpty(Int_t action)
fBuffer = buffer;
}

if (CanExtendAllAxes() || fXaxis.GetXmax() <= fXaxis.GetXmin() || fYaxis.GetXmax() <= fYaxis.GetXmin()) {
const bool xbinAuto = fXaxis.GetXmax() <= fXaxis.GetXmin();
const bool ybinAuto = fYaxis.GetXmax() <= fYaxis.GetXmin();
if (CanExtendAllAxes() || xbinAuto || ybinAuto) {
//find min, max of entries in buffer
Double_t xmin = fBuffer[2];
Double_t xmax = xmin;
Double_t ymin = fBuffer[3];
Double_t ymax = ymin;
Double_t xmin = xbinAuto ? fBuffer[2] : fXaxis.GetXmin();
Double_t xmax = xbinAuto ? xmin : fXaxis.GetXmax();
Double_t ymin = ybinAuto ? fBuffer[3] : fYaxis.GetXmin();
Double_t ymax = ybinAuto ? ymin : fYaxis.GetXmax();
for (Int_t i=1;i<nbentries;i++) {
Double_t x = fBuffer[3*i+2];
if (x < xmin) xmin = x;
if (x > xmax) xmax = x;
Double_t y = fBuffer[3*i+3];
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
if (CanExtendAllAxes() || xbinAuto) {
Double_t x = fBuffer[3*i+2];
if (x < xmin) xmin = x;
if (x > xmax) xmax = x;
}
if (CanExtendAllAxes() || ybinAuto) {
Double_t y = fBuffer[3*i+3];
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
}
}
if (fXaxis.GetXmax() <= fXaxis.GetXmin() || fYaxis.GetXmax() <= fYaxis.GetXmin()) {
THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this,xmin,xmax,ymin,ymax);
if (xbinAuto || ybinAuto) {
THLimitsFinder::GetLimitsFinder()->FindGoodLimitsXY(
this, xmin, xmax, ymin, ymax, xbinAuto ? 0 : fXaxis.GetNbins(), ybinAuto ? 0 : fYaxis.GetNbins());
} else {
fBuffer = nullptr;
Int_t keep = fBufferSize; fBufferSize = 0;
Expand Down
49 changes: 29 additions & 20 deletions hist/hist/src/TH3.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -241,29 +241,38 @@ Int_t TH3::BufferEmpty(Int_t action)
Reset("ICES");
fBuffer = buffer;
}
if (CanExtendAllAxes() || fXaxis.GetXmax() <= fXaxis.GetXmin() ||
fYaxis.GetXmax() <= fYaxis.GetXmin() ||
fZaxis.GetXmax() <= fZaxis.GetXmin()) {
const bool xbinAuto = fXaxis.GetXmax() <= fXaxis.GetXmin();
const bool ybinAuto = fYaxis.GetXmax() <= fYaxis.GetXmin();
const bool zbinAuto = fZaxis.GetXmax() <= fZaxis.GetXmin();
if (CanExtendAllAxes() || xbinAuto || ybinAuto || zbinAuto) {
//find min, max of entries in buffer
Double_t xmin = fBuffer[2];
Double_t xmax = xmin;
Double_t ymin = fBuffer[3];
Double_t ymax = ymin;
Double_t zmin = fBuffer[4];
Double_t zmax = zmin;
Double_t xmin = xbinAuto ? fBuffer[2] : fXaxis.GetXmin();
Double_t xmax = xbinAuto ? xmin : fXaxis.GetXmax();
Double_t ymin = ybinAuto ? fBuffer[3] : fYaxis.GetXmin();
Double_t ymax = ybinAuto ? ymin : fYaxis.GetXmax();
Double_t zmin = zbinAuto ? fBuffer[4] : fZaxis.GetXmin();
Double_t zmax = zbinAuto ? zmin : fZaxis.GetXmax();
for (Int_t i=1;i<nbentries;i++) {
Double_t x = fBuffer[4*i+2];
if (x < xmin) xmin = x;
if (x > xmax) xmax = x;
Double_t y = fBuffer[4*i+3];
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
Double_t z = fBuffer[4*i+4];
if (z < zmin) zmin = z;
if (z > zmax) zmax = z;
if (CanExtendAllAxes() || xbinAuto) {
Double_t x = fBuffer[4*i+2];
if (x < xmin) xmin = x;
if (x > xmax) xmax = x;
}
if (CanExtendAllAxes() || ybinAuto) {
Double_t y = fBuffer[4*i+3];
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
}
if (CanExtendAllAxes() || zbinAuto) {
Double_t z = fBuffer[4*i+4];
if (z < zmin) zmin = z;
if (z > zmax) zmax = z;
}
}
if (fXaxis.GetXmax() <= fXaxis.GetXmin() || fYaxis.GetXmax() <= fYaxis.GetXmin() || fZaxis.GetXmax() <= fZaxis.GetXmin()) {
THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this,xmin,xmax,ymin,ymax,zmin,zmax);
if (xbinAuto || ybinAuto || zbinAuto) {
THLimitsFinder::GetLimitsFinder()->FindGoodLimitsXYZ(
this, xmin, xmax, ymin, ymax, zmin, zmax, xbinAuto ? 0 : fXaxis.GetNbins(),
ybinAuto ? 0 : fYaxis.GetNbins(), zbinAuto ? 0 : fZaxis.GetNbins());
} else {
fBuffer = nullptr;
Int_t keep = fBufferSize; fBufferSize = 0;
Expand Down
73 changes: 42 additions & 31 deletions hist/hist/src/THLimitsFinder.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -71,75 +71,86 @@ Int_t THLimitsFinder::FindGoodLimits(TH1 *h, Double_t xmin, Double_t xmax)
}

////////////////////////////////////////////////////////////////////////////////
/// Compute the best axis limits for the X and Y axis.
/// Compute the best axis limits for the X and Y axis
/// if the corresponding `newbins` variable is set to 0, i.e. the default value.
///
/// If the bit kIsInteger is set, the number of channels is also recomputed.
/// The axis parameters are replaced by the optimized parameters

Int_t THLimitsFinder::FindGoodLimits(TH1 *h, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax)
Int_t THLimitsFinder::FindGoodLimitsXY(TH1 *h, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax,
Int_t newbinsx, Int_t newbinsy)
{
Int_t newbinsx,newbinsy;
TAxis *xaxis = h->GetXaxis();
TAxis *yaxis = h->GetYaxis();

if (xmin >= xmax) {
const Bool_t xbinAuto = newbinsx == 0;
const Bool_t ybinAuto = newbinsy == 0;

if (xbinAuto && xmin >= xmax) {
if (xaxis->GetLabels()) {xmin = 0; xmax = xmin +xaxis->GetNbins();}
else {xmin -= 1; xmax += 1;}
}
if (ymin >= ymax) {
if (ybinAuto && ymin >= ymax) {
if (yaxis->GetLabels()) {ymin = 0; ymax = ymin +yaxis->GetNbins();}
else {ymin -= 1; ymax += 1;}
}

THLimitsFinder::OptimizeLimits(xaxis->GetNbins(),
newbinsx,xmin,xmax,
xaxis->TestBit(TAxis::kIsInteger));

THLimitsFinder::OptimizeLimits(yaxis->GetNbins(),
newbinsy,ymin,ymax,
yaxis->TestBit(TAxis::kIsInteger));
if (xbinAuto)
THLimitsFinder::OptimizeLimits(xaxis->GetNbins(),
newbinsx,xmin,xmax,
xaxis->TestBit(TAxis::kIsInteger));
if (ybinAuto)
THLimitsFinder::OptimizeLimits(yaxis->GetNbins(),
newbinsy,ymin,ymax,
yaxis->TestBit(TAxis::kIsInteger));

h->SetBins(newbinsx,xmin,xmax,newbinsy,ymin,ymax);
return 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Compute the best axis limits for the X, Y and Z axis.
/// Compute the best axis limits and bins for the X, Y and Z axis
/// if the corresponding `newbins` variable is set to 0, i.e. the default value.
///
/// If the bit kIsInteger is set, the number of channels is also recomputed.
/// The axis parameters are replaced by the optimized parameters

Int_t THLimitsFinder::FindGoodLimits(TH1 *h, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax)
Int_t THLimitsFinder::FindGoodLimitsXYZ(TH1 *h, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax,
Double_t zmin, Double_t zmax, Int_t newbinsx, Int_t newbinsy, Int_t newbinsz)
{
Int_t newbinsx,newbinsy,newbinsz;
TAxis *xaxis = h->GetXaxis();
TAxis *yaxis = h->GetYaxis();
TAxis *zaxis = h->GetZaxis();

if (xmin >= xmax) {
const Bool_t xbinAuto = newbinsx == 0;
const Bool_t ybinAuto = newbinsy == 0;
const Bool_t zbinAuto = newbinsz == 0;

if (xbinAuto && xmin >= xmax) {
if (xaxis->GetLabels()) {xmin = 0; xmax = xmin +xaxis->GetNbins();}
else {xmin -= 1; xmax += 1;}
}
if (ymin >= ymax) {
if (ybinAuto && ymin >= ymax) {
if (yaxis->GetLabels()) {ymin = 0; ymax = ymin +yaxis->GetNbins();}
else {ymin -= 1; ymax += 1;}
}
if (zmin >= zmax) {
if (zbinAuto && zmin >= zmax) {
if (zaxis->GetLabels()) {zmin = 0; zmax = zmin +zaxis->GetNbins();}
else {zmin -= 1; zmax += 1;}
}

THLimitsFinder::OptimizeLimits(xaxis->GetNbins(),
newbinsx,xmin,xmax,
xaxis->TestBit(TAxis::kIsInteger));

THLimitsFinder::OptimizeLimits(yaxis->GetNbins(),
newbinsy,ymin,ymax,
yaxis->TestBit(TAxis::kIsInteger));

THLimitsFinder::OptimizeLimits(zaxis->GetNbins(),
newbinsz,zmin,zmax,
zaxis->TestBit(TAxis::kIsInteger));
if (xbinAuto)
THLimitsFinder::OptimizeLimits(xaxis->GetNbins(),
newbinsx,xmin,xmax,
xaxis->TestBit(TAxis::kIsInteger));
if (ybinAuto)
THLimitsFinder::OptimizeLimits(yaxis->GetNbins(),
newbinsy,ymin,ymax,
yaxis->TestBit(TAxis::kIsInteger));
if (zbinAuto)
THLimitsFinder::OptimizeLimits(zaxis->GetNbins(),
newbinsz,zmin,zmax,
zaxis->TestBit(TAxis::kIsInteger));

h->SetBins(newbinsx,xmin,xmax,newbinsy,ymin,ymax,newbinsz,zmin,zmax);
return 0;
Expand All @@ -160,8 +171,8 @@ THLimitsFinder *THLimitsFinder::GetLimitsFinder()
////////////////////////////////////////////////////////////////////////////////
/// This static function can be used to specify a finder derived from THLimitsFinder.
///
/// The finder may redefine the functions FindGoodLimits.
/// Note that the redefined functions may call THLimitsFinder::FindGoodLimits.
/// The finder may redefine the functions FindGoodLimits*.
/// Note that the redefined functions may call THLimitsFinder::FindGoodLimits*.

void THLimitsFinder::SetLimitsFinder(THLimitsFinder *finder)
{
Expand Down
2 changes: 1 addition & 1 deletion hist/hist/src/TProfile2D.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ Int_t TProfile2D::BufferEmpty(Int_t action)
if (y > ymax) ymax = y;
}
if (fXaxis.GetXmax() <= fXaxis.GetXmin() || fYaxis.GetXmax() <= fYaxis.GetXmin()) {
THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this,xmin,xmax,ymin,ymax);
THLimitsFinder::GetLimitsFinder()->FindGoodLimitsXY(this, xmin, xmax, ymin, ymax);
} else {
fBuffer = nullptr;
Int_t keep = fBufferSize; fBufferSize = 0;
Expand Down
2 changes: 1 addition & 1 deletion hist/hist/src/TProfile3D.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ Int_t TProfile3D::BufferEmpty(Int_t action)
if (z > zmax) zmax = z;
}
if (fXaxis.GetXmax() <= fXaxis.GetXmin() || fYaxis.GetXmax() <= fYaxis.GetXmin() || fZaxis.GetXmax() <= fZaxis.GetXmin()) {
THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this,xmin,xmax,ymin,ymax,zmin,zmax);
THLimitsFinder::GetLimitsFinder()->FindGoodLimitsXYZ(this, xmin, xmax, ymin, ymax, zmin, zmax);
} else {
fBuffer = nullptr;
Int_t keep = fBufferSize; fBufferSize = 0;
Expand Down
16 changes: 9 additions & 7 deletions tree/treeplayer/src/TSelectorDraw.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1402,7 +1402,7 @@ void TSelectorDraw::TakeAction()
if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
}
THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h2, fVmin[1], fVmax[1], fVmin[0], fVmax[0]);
THLimitsFinder::GetLimitsFinder()->FindGoodLimitsXY(h2, fVmin[1], fVmax[1], fVmin[0], fVmax[0]);
}
TGraph *pm = new TGraph(fNfill, fVal[1], fVal[0]);
pm->SetEditable(false);
Expand Down Expand Up @@ -1588,7 +1588,7 @@ void TSelectorDraw::TakeEstimate()
if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
}
THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h2, fVmin[1], fVmax[1], fVmin[0], fVmax[0]);
THLimitsFinder::GetLimitsFinder()->FindGoodLimitsXY(h2, fVmin[1], fVmax[1], fVmin[0], fVmax[0]);
}
for (i = 0; i < fNfill; i++) h2->Fill(fVal[1][i], fVal[0][i], fW[i]);
//__________________________Profile histogram_______________________
Expand All @@ -1614,7 +1614,7 @@ void TSelectorDraw::TakeEstimate()
if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
}
THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h2, fVmin[1], fVmax[1], fVmin[0], fVmax[0]);
THLimitsFinder::GetLimitsFinder()->FindGoodLimitsXY(h2, fVmin[1], fVmax[1], fVmin[0], fVmax[0]);
// In case the new lower limits of h2 axis are 0, it is better to set them to the minimum of
// the data set (which should be >0) to avoid data cut when plotting in log scale.
TAxis *aX = h2->GetXaxis();
Expand Down Expand Up @@ -1701,7 +1701,7 @@ void TSelectorDraw::TakeEstimate()
if (fVmax[2] < fVal[2][i]) fVmax[2] = fVal[2][i];
}
}
THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h2, fVmin[1], fVmax[1], fVmin[0], fVmax[0]);
THLimitsFinder::GetLimitsFinder()->FindGoodLimitsXY(h2, fVmin[1], fVmax[1], fVmin[0], fVmax[0]);
// In case the new lower limits of h2 axis are 0, it is better to set them to the minimum of
// the data set (which should be >0) to avoid data cut when plotting in log scale.
TAxis *aX = h2->GetXaxis();
Expand Down Expand Up @@ -1731,7 +1731,8 @@ void TSelectorDraw::TakeEstimate()
if (fVmin[2] > fVal[2][i]) fVmin[2] = fVal[2][i];
if (fVmax[2] < fVal[2][i]) fVmax[2] = fVal[2][i];
}
THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h3, fVmin[2], fVmax[2], fVmin[1], fVmax[1], fVmin[0], fVmax[0]);
THLimitsFinder::GetLimitsFinder()->FindGoodLimitsXYZ(h3, fVmin[2], fVmax[2], fVmin[1], fVmax[1], fVmin[0],
fVmax[0]);
}
if (fAction == 3) {
for (i = 0; i < fNfill; i++) h3->Fill(fVal[2][i], fVal[1][i], fVal[0][i], fW[i]);
Expand Down Expand Up @@ -1783,7 +1784,7 @@ void TSelectorDraw::TakeEstimate()
if (fVmin[2] > fVal[2][i]) fVmin[2] = fVal[2][i];
if (fVmax[2] < fVal[2][i]) fVmax[2] = fVal[2][i];
}
THLimitsFinder::GetLimitsFinder()->FindGoodLimits(hp, fVmin[2], fVmax[2], fVmin[1], fVmax[1]);
THLimitsFinder::GetLimitsFinder()->FindGoodLimitsXY(hp, fVmin[2], fVmax[2], fVmin[1], fVmax[1]);
}
for (i = 0; i < fNfill; i++) hp->Fill(fVal[2][i], fVal[1][i], fVal[0][i], fW[i]);
//__________________________4D scatter plot_______________________
Expand All @@ -1804,7 +1805,8 @@ void TSelectorDraw::TakeEstimate()
if (fVmin[3] > fVal[3][i]) fVmin[3] = fVal[3][i];
if (fVmax[3] < fVal[3][i]) fVmax[3] = fVal[3][i];
}
THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h3, fVmin[2], fVmax[2], fVmin[1], fVmax[1], fVmin[0], fVmax[0]);
THLimitsFinder::GetLimitsFinder()->FindGoodLimitsXYZ(h3, fVmin[2], fVmax[2], fVmin[1], fVmax[1], fVmin[0],
fVmax[0]);
} else {
for (i = 0; i < fNfill; i++) {
if (fVmin[3] > fVal[3][i]) fVmin[3] = fVal[3][i];
Expand Down
Loading