Skip to content
Open
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
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## [Upcoming release](https://github.com/open2c/bioframe/compare/v0.8.0...HEAD)

Bug fixes:

- `overlap` again honors `return_input=1`/`"left"` and `return_input=2`/`"right"` to return only
one side's columns; unsupported values now raise `ValueError` instead of silently returning both.

## v0.8.0

Date: 2025-04-08
Expand Down
25 changes: 21 additions & 4 deletions src/bioframe/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,11 @@ def overlap(
outer: use the union of the set of intervals from df1 and df2
inner: use intersection of the set of intervals from df1 and df2

return_input : bool, optional
If True, return columns from input dfs. Default True.
return_input : bool, int, or str, optional
Controls which input columns are returned. If True (default), return
columns from both input dataframes; if False, return neither. To return
only one side, pass ``1``, ``"1"``, or ``"left"`` for ``df1``, or ``2``,
``"2"``, or ``"right"`` for ``df2``.

return_index : bool, optional
If True, return indicies of overlapping pairs as two new columns
Expand Down Expand Up @@ -461,6 +464,20 @@ def overlap(
_verify_columns(df1, on)
_verify_columns(df2, on)

if return_input is True:
return_left = return_right = True
elif return_input is False:
return_left = return_right = False
elif return_input in (1, "1", "left"):
return_left, return_right = True, False
elif return_input in (2, "2", "right"):
return_left, return_right = False, True
else:
raise ValueError(
"return_input must be one of True, False, 1, 2, 'left', 'right'; "
f"got {return_input!r}"
)

events1, events2 = _overlap_intidxs(
df1,
df2,
Expand Down Expand Up @@ -499,11 +516,11 @@ def overlap(

df_input_1 = None
df_input_2 = None
if return_input:
if return_left:
df_input_1 = df1.iloc[events1].reset_index(drop=True)
df_input_1.columns = [c + suffixes[0] for c in df_input_1.columns]

if return_input:
if return_right:
df_input_2 = df2.iloc[events2].reset_index(drop=True)
df_input_2.columns = [c + suffixes[1] for c in df_input_2.columns]

Expand Down
40 changes: 40 additions & 0 deletions tests/test_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,46 @@ def test_overlap():
)


def test_overlap_return_input():
df1 = pd.DataFrame(
[["chr1", 3, 8], ["chr1", 12, 16]],
columns=["chrom", "start", "end"],
)
df2 = pd.DataFrame(
[["chr1", 5, 10]],
columns=["chrom", "start", "end"],
)
left_cols = ["chrom", "start", "end"]
right_cols = ["chrom_", "start_", "end_"]

# True / False return both / neither sides
assert (
list(bioframe.overlap(df1, df2, how="inner", return_input=True).columns)
== left_cols + right_cols
)
assert (
list(bioframe.overlap(df1, df2, how="inner", return_input=False).columns) == []
)

# 1 / "1" / "left" return only df1 columns
for val in (1, "1", "left"):
assert (
list(bioframe.overlap(df1, df2, how="inner", return_input=val).columns)
== left_cols
)

# 2 / "2" / "right" return only df2 columns
for val in (2, "2", "right"):
assert (
list(bioframe.overlap(df1, df2, how="inner", return_input=val).columns)
== right_cols
)

# values outside the supported set raise instead of silently returning both
with pytest.raises(ValueError):
bioframe.overlap(df1, df2, how="inner", return_input="both")


def test_overlap_preserves_coord_dtypes():
df1 = pd.DataFrame(
[
Expand Down