Skip to content

combine_bins fast path accepts bin-edge outer coords rejected by the C++ implementation #3955

Description

@SimonHeybrock

bin and hist accept a bin-edge outer coord when the combine_bins fast path applies, whereas the C++ implementation rejects such input with

BinEdgeError: Requested binning in dimension 'strain' but input contains a bin-edge coordinate with no corresponding event-coordinate. Provide an event coordinate or convert the bin-edge coordinate to a non-edge coordinate.

The fast path was introduced in 2022 and routes around that check, so which semantics apply depends on whether _can_operate_on_bins happens to return True. What the fast path does instead depends on how many dims are flattened:

  • one flattened dim: _combine_bins builds DataArray(var_bins.size(), coords=coords), where the coord has one value too many. The subsequent flatten is a mere rename, so the coord survives and its first N values are used, one per input bin — i.e. the bin's left edge. No error, silently different from the reference implementation.
  • more than one flattened dim: flatten drops the bin-edge coord and binning fails later with a confusing KeyError: "Expected 'y' in <scipp.Dict.keys {}>."

Reproducer for both:

import scipp as sc

# One flattened dim: silently succeeds
da = sc.data.table_xyz(100).bin(x=5)
da.coords['s'] = sc.linspace('x', 0.0, 1.0, 6, unit='m')  # bin-edge over 'x'
da.bin(s=sc.linspace('s', 0.0, 1.0, 3, unit='m'))

# Two flattened dims: KeyError
da = sc.data.table_xyz(100).bin(x=2, y=3)
del da.bins.coords['y']
da.bin(y=2, dim=da.dims)

Both should raise BinEdgeError. Tests are marked xfail in tests/binning_test.py.

Fixing this is a user-visible break: docs/user-guide/binned-data/filtering.ipynb relies on the silent left-edge behavior and needs to pass a non-edge coord instead.

Activity

  1. added a commit that references this issue on Aug 25, 2026
    9614791
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions