Skip to content

Commit 3d8038d

Browse files
authored
coerce SCE to/from RSE/SE (#75)
1 parent 5116d37 commit 3d8038d

File tree

3 files changed

+127
-2
lines changed

3 files changed

+127
-2
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
# Changelog
22

3-
## Version 0.6.0
3+
## Version 0.6.0 - 0.6.2
44

55
- Changed related to SummarizedExperiment and implementation of `CompressedGenomicRangesList` in the genomic ranges package.
66
- Update versions of relevant dependency packages.
7+
- Rename `reduced_dims` to `reduced_dimensions`.
8+
- Implement coercions to/from RSE/SE.
79

810
## Version 0.5.8 - 0.5.9
911

src/singlecellexperiment/SingleCellExperiment.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import biocframe
88
import biocutils as ut
9+
from summarizedexperiment import SummarizedExperiment
910
from summarizedexperiment._combineutils import (
1011
check_assays_are_equal,
1112
merge_assays,
@@ -1277,6 +1278,86 @@ def combine_columns(self, *other) -> SingleCellExperiment:
12771278
"""Wrapper around :py:func:`~combine_columns`."""
12781279
return combine_columns(self, *other)
12791280

1281+
#######################
1282+
######>> to rse <<#####
1283+
#######################
1284+
1285+
def to_rangedsummarizedexperiment(self) -> RangedSummarizedExperiment:
1286+
"""Coerce to :py:class:`~summarizedexperiment.RangedSummarizedExperiment.RangedSummarizedExperiment`.
1287+
1288+
Returns:
1289+
A ``RangedSummarizedExperiment`` object.
1290+
"""
1291+
return RangedSummarizedExperiment(
1292+
assays=self._assays,
1293+
row_ranges=self._row_ranges,
1294+
row_data=self._rows,
1295+
column_data=self._cols,
1296+
row_names=self._row_names,
1297+
column_names=self._column_names,
1298+
metadata=self._metadata,
1299+
_validate=False,
1300+
)
1301+
1302+
def to_rse(self) -> RangedSummarizedExperiment:
1303+
"""Alias for :py:meth:`~to_rangedsummarizedexperiment`."""
1304+
return self.to_rangedsummarizedexperiment()
1305+
1306+
@classmethod
1307+
def from_rangedsummarizedexperiment(cls, rse: RangedSummarizedExperiment) -> SingleCellExperiment:
1308+
"""Coerce from :py:class:`~summarizedexperiment.RangedSummarizedExperiment.RangedSummarizedExperiment`.
1309+
1310+
Args:
1311+
rse:
1312+
A ``RangedSummarizedExperiment`` object.
1313+
1314+
Returns:
1315+
A ``SingleCellExperiment`` object.
1316+
"""
1317+
return cls(
1318+
assays=rse.assays,
1319+
row_ranges=rse.row_ranges,
1320+
row_data=rse.row_data,
1321+
column_data=rse.col_data,
1322+
row_names=rse.row_names,
1323+
column_names=rse.column_names,
1324+
metadata=rse.metadata,
1325+
)
1326+
1327+
@classmethod
1328+
def from_rse(cls, rse: RangedSummarizedExperiment) -> SingleCellExperiment:
1329+
"""Alias for :py:meth:`~from_rangedsummarizedexperiment`."""
1330+
return cls.from_rangedsummarizedexperiment(rse)
1331+
1332+
########################
1333+
######>> from se <<#####
1334+
########################
1335+
1336+
@classmethod
1337+
def from_summarizedexperiment(cls, se: SummarizedExperiment) -> SingleCellExperiment:
1338+
"""Coerce from :py:class:`~summarizedexperiment.SummarizedExperiment.SummarizedExperiment`.
1339+
1340+
Args:
1341+
se:
1342+
A ``SummarizedExperiment`` object.
1343+
1344+
Returns:
1345+
A ``SingleCellExperiment`` object.
1346+
"""
1347+
return cls(
1348+
assays=se.assays,
1349+
row_data=se.row_data,
1350+
column_data=se.col_data,
1351+
row_names=se.row_names,
1352+
column_names=se.column_names,
1353+
metadata=se.metadata,
1354+
)
1355+
1356+
@classmethod
1357+
def from_se(cls, se: SummarizedExperiment) -> SingleCellExperiment:
1358+
"""Alias for :py:meth:`~from_summarizedexperiment`."""
1359+
return cls.from_summarizedexperiment(se)
1360+
12801361

12811362
############################
12821363
######>> combine ops <<#####

tests/test_sce_methods.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import numpy as np
66
import pandas as pd
77
import pytest
8-
from summarizedexperiment import SummarizedExperiment
8+
from summarizedexperiment import SummarizedExperiment, RangedSummarizedExperiment
99

1010
from singlecellexperiment import SingleCellExperiment
1111
from singlecellexperiment.SingleCellExperiment import SingleCellExperiment as sce
@@ -90,3 +90,45 @@ def test_SCE_props():
9090

9191
assert tse.reduced_dim_names is not None
9292
assert len(tse.reduced_dim_names) == 1
93+
94+
def test_SCE_to_RSE():
95+
tse = SingleCellExperiment(
96+
assays={"counts": counts}, row_data=row_data, column_data=col_data, row_ranges=gr
97+
)
98+
99+
rse = tse.to_rangedsummarizedexperiment()
100+
assert isinstance(rse, RangedSummarizedExperiment)
101+
assert not isinstance(rse, SingleCellExperiment)
102+
assert rse.shape == tse.shape
103+
assert rse.row_ranges is not None
104+
105+
def test_RSE_to_SCE():
106+
rse = RangedSummarizedExperiment(
107+
assays={"counts": counts}, row_data=row_data, column_data=col_data, row_ranges=gr
108+
)
109+
110+
tse = SingleCellExperiment.from_rangedsummarizedexperiment(rse)
111+
assert isinstance(tse, SingleCellExperiment)
112+
assert tse.shape == rse.shape
113+
assert tse.row_ranges is not None
114+
115+
def test_SCE_to_SE():
116+
tse = SingleCellExperiment(
117+
assays={"counts": counts}, row_data=row_data, column_data=col_data, row_ranges=gr
118+
)
119+
120+
se = tse.to_summarizedexperiment()
121+
assert isinstance(se, SummarizedExperiment)
122+
assert not isinstance(se, SingleCellExperiment)
123+
assert se.shape == tse.shape
124+
assert se.row_data is not None
125+
assert "seqnames" in se.row_data.column_names
126+
127+
def test_SE_to_SCE():
128+
se = SummarizedExperiment(
129+
assays={"counts": counts}, row_data=row_data, column_data=col_data
130+
)
131+
132+
tse = SingleCellExperiment.from_summarizedexperiment(se)
133+
assert isinstance(tse, SingleCellExperiment)
134+
assert tse.shape == se.shape

0 commit comments

Comments
 (0)