Skip to content

[hist] Fix automatic axis limits in TProfile3D - #23828

Open
Elvand-Lie wants to merge 2 commits into
root-project:masterfrom
Elvand-Lie:fix/tprofile3d-auto-z-binning
Open

Elvand-Lie wants to merge 2 commits into
root-project:masterfrom
Elvand-Lie:fix/tprofile3d-auto-z-binning

Conversation

@Elvand-Lie

@Elvand-Lie Elvand-Lie commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

This Pull request:

Changes or fixes:

TProfile3D::BufferEmpty mishandles automatic axis limits.

With fixed X and Y axes and automatic Z, every entry ends up in the Z overflow:

TProfile3D p("p", "", 4, 0, 4, 5, 0, 10, 3, 0, 0); // automatic Z limits
for (double z : {101., 115., 139.})
   p.Fill(0.5, 1., z, 2.);
p.BufferEmpty();
// master: Z axis stays [0, 0], all 3 entries in the Z overflow, GetMean(3) == 0
// TH3D with the same binning and fills: Z axis [100, 140], GetMean(3) == 118.33

With automatic X, the fixed Y and Z axes are rebinned as well, so they no longer have the limits the user gave.

The outer condition only looked for automatic X or Y limits. Once inside, the block took the limits of all three axes from the buffer and let FindGoodLimitsXYZ choose new limits for every axis, fixed ones included.

The fix ports the per-axis logic of TH3::BufferEmpty:

  • each axis is checked for automatic limits;
  • only automatic (or extendable) axes take their range from the buffer;
  • fixed axes keep their limits and pass their bin counts to FindGoodLimitsXYZ.

The buffer layout of TProfile3D, five values per entry, is kept.

Two tests in hist/hist/test/test_TProfile.cxx:

  • TProfile3D.BufferEmptyFindsAutomaticZLimits: automatic Z with fixed X and Y. The Z axis contains the filled values, no entry is in a Z underflow or overflow bin, the Z mean is (101 + 115 + 139) / 3, and X and Y keep their limits.

  • TProfile3D.BufferEmptyPreservesFixedYAndZLimits: automatic X with fixed Y and Z; Y and Z keep their limits.

  • Both tests fail on master and pass with this change.

  • ctest -R '^gtest-hist-hist-' passes: 33 tests, 0 failures, on Linux with a minimal build.

  • Also checked against TH3D: axes, labels, per-bin contents and entries for automatic, fixed, labelled and extendable axis combinations, including repeated and forced BufferEmpty calls.

  • Not run: the full ROOT test suite, roottest, and platforms other than Linux.

Checklist:

  • tested changes locally
  • updated the docs (if necessary)

Codex (gpt-6.1-sol) implemented the fix and the tests; Claude Code (Claude Opus 5.5) found the bug and validated it. I reviewed the full diff and the tests.

BufferEmpty skipped the limits search when only Z had automatic bins.
Include Z in the outer condition so buffered entries get usable bins.
Test the limits, flow-bin entries and Z mean with fixed X and Y axes.

Assisted-by: codex:gpt-6.1-sol
Assisted-by: claude-code:claude-opus-5-5
Use TH3's per-axis limit search to avoid rebinning fixed companion axes.
Retain their bin counts and limits while optimizing automatic axes.
Cover automatic Z and automatic X with fixed companion axes.

Assisted-by: codex:gpt-6.1-sol
Assisted-by: claude-code:claude-opus-5-5
@Elvand-Lie Elvand-Lie changed the title [hist] Find automatic Z axis limits in TProfile3D::BufferEmpty [hist] Fix automatic axis limits in TProfile3D Oct 24, 2026
@Elvand-Lie
Elvand-Lie marked this pull request as ready for review October 31, 2026 14:05

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant