SingleCellExperiment 0.5.0__tar.gz → 0.5.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. singlecellexperiment-0.5.0/.github/workflows/pypi-test.yml → singlecellexperiment-0.5.2/.github/workflows/run-tests.yml +0 -1
  2. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/.pre-commit-config.yaml +2 -2
  3. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/CHANGELOG.md +6 -0
  4. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/PKG-INFO +3 -3
  5. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/README.md +1 -1
  6. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/docs/changelog.md +6 -0
  7. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/docs/readme.md +1 -1
  8. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/setup.cfg +1 -1
  9. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/src/SingleCellExperiment.egg-info/PKG-INFO +3 -3
  10. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/src/SingleCellExperiment.egg-info/SOURCES.txt +2 -2
  11. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/src/SingleCellExperiment.egg-info/requires.txt +1 -1
  12. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/src/singlecellexperiment/SingleCellExperiment.py +158 -26
  13. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/tests/test_sce.py +25 -0
  14. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/tests/test_sce_combine_cols.py +15 -0
  15. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/tests/test_sce_combine_rows.py +11 -0
  16. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/.coveragerc +0 -0
  17. /singlecellexperiment-0.5.0/.github/workflows/pypi-publish.yml → /singlecellexperiment-0.5.2/.github/workflows/publish-pypi.yml +0 -0
  18. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/.gitignore +0 -0
  19. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/.readthedocs.yml +0 -0
  20. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/AUTHORS.md +0 -0
  21. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/CONTRIBUTING.md +0 -0
  22. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/LICENSE.txt +0 -0
  23. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/docs/Makefile +0 -0
  24. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/docs/_static/.gitignore +0 -0
  25. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/docs/authors.md +0 -0
  26. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/docs/conf.py +0 -0
  27. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/docs/contributing.md +0 -0
  28. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/docs/index.md +0 -0
  29. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/docs/license.md +0 -0
  30. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/docs/requirements.txt +0 -0
  31. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/docs/tutorial.md +0 -0
  32. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/pyproject.toml +0 -0
  33. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/setup.py +0 -0
  34. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/src/SingleCellExperiment.egg-info/dependency_links.txt +0 -0
  35. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/src/SingleCellExperiment.egg-info/not-zip-safe +0 -0
  36. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/src/SingleCellExperiment.egg-info/top_level.txt +0 -0
  37. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/src/singlecellexperiment/__init__.py +0 -0
  38. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/src/singlecellexperiment/_combineutils.py +0 -0
  39. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/src/singlecellexperiment/_ioutils.py +0 -0
  40. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/src/singlecellexperiment/io/__init__.py +0 -0
  41. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/src/singlecellexperiment/io/h5ad.py +0 -0
  42. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/src/singlecellexperiment/io/tenx.py +0 -0
  43. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/tests/conftest.py +0 -0
  44. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/tests/data/adata.h5ad +0 -0
  45. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/tests/data/mocks.py +0 -0
  46. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/tests/data/tenx.sub.h5 +0 -0
  47. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/tests/test_sce_io.py +0 -0
  48. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/tests/test_sce_methods.py +0 -0
  49. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/tests/test_sce_slice.py +0 -0
  50. {singlecellexperiment-0.5.0 → singlecellexperiment-0.5.2}/tox.ini +0 -0
@@ -4,7 +4,6 @@ on:
4
4
  push:
5
5
  branches: [master]
6
6
  pull_request:
7
- branches: [master]
8
7
 
9
8
  jobs:
10
9
  build:
@@ -2,7 +2,7 @@ exclude: '^docs/conf.py'
2
2
 
3
3
  repos:
4
4
  - repo: https://github.com/pre-commit/pre-commit-hooks
5
- rev: v4.6.0
5
+ rev: v5.0.0
6
6
  hooks:
7
7
  - id: trailing-whitespace
8
8
  - id: check-added-large-files
@@ -33,7 +33,7 @@ repos:
33
33
 
34
34
  - repo: https://github.com/astral-sh/ruff-pre-commit
35
35
  # Ruff version.
36
- rev: v0.6.8
36
+ rev: v0.8.4
37
37
  hooks:
38
38
  - id: ruff
39
39
  args: [--fix, --exit-non-zero-on-fix]
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## Version 0.5.1 - 0.5.2
4
+
5
+ - Add wrapper class methods to combine experiments by rows or columns.
6
+ - Expand function names for readability, still backwards compatible with the older function and method names.
7
+ - Add getters and setters to replace a specific alternative experiment or reduced dimension.
8
+
3
9
  ## Version 0.5.0
4
10
 
5
11
  - chore: Remove Python 3.8 (EOL)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: SingleCellExperiment
3
- Version: 0.5.0
3
+ Version: 0.5.2
4
4
  Summary: Container class for single-cell experiments
5
5
  Home-page: https://github.com/BiocPy/SingleCellExperiment
6
6
  Author: jkanche
@@ -14,7 +14,7 @@ Requires-Python: >=3.9
14
14
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
15
15
  License-File: LICENSE.txt
16
16
  Requires-Dist: importlib-metadata; python_version < "3.8"
17
- Requires-Dist: summarizedexperiment>=0.4.5
17
+ Requires-Dist: summarizedexperiment>=0.5.1
18
18
  Provides-Extra: optional
19
19
  Requires-Dist: anndata==0.9.2; python_version <= "3.9" and extra == "optional"
20
20
  Requires-Dist: anndata>0.9.2; python_version > "3.9" and extra == "optional"
@@ -41,7 +41,7 @@ Requires-Dist: numpy>1.24.4; python_version > "3.9" and extra == "testing"
41
41
 
42
42
  [![Project generated with PyScaffold](https://img.shields.io/badge/-PyScaffold-005CA0?logo=pyscaffold)](https://pyscaffold.org/)
43
43
  [![PyPI-Server](https://img.shields.io/pypi/v/SingleCellExperiment.svg)](https://pypi.org/project/SingleCellExperiment/)
44
- ![Unit tests](https://github.com/BiocPy/SingleCellExperiment/actions/workflows/pypi-test.yml/badge.svg)
44
+ ![Unit tests](https://github.com/BiocPy/SingleCellExperiment/actions/workflows/run-tests.yml/badge.svg)
45
45
 
46
46
  # SingleCellExperiment
47
47
 
@@ -1,6 +1,6 @@
1
1
  [![Project generated with PyScaffold](https://img.shields.io/badge/-PyScaffold-005CA0?logo=pyscaffold)](https://pyscaffold.org/)
2
2
  [![PyPI-Server](https://img.shields.io/pypi/v/SingleCellExperiment.svg)](https://pypi.org/project/SingleCellExperiment/)
3
- ![Unit tests](https://github.com/BiocPy/SingleCellExperiment/actions/workflows/pypi-test.yml/badge.svg)
3
+ ![Unit tests](https://github.com/BiocPy/SingleCellExperiment/actions/workflows/run-tests.yml/badge.svg)
4
4
 
5
5
  # SingleCellExperiment
6
6
 
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## Version 0.5.1 - 0.5.2
4
+
5
+ - Add wrapper class methods to combine experiments by rows or columns.
6
+ - Expand function names for readability, still backwards compatible with the older function and method names.
7
+ - Add getters and setters to replace a specific alternative experiment or reduced dimension.
8
+
3
9
  ## Version 0.5.0
4
10
 
5
11
  - chore: Remove Python 3.8 (EOL)
@@ -1,6 +1,6 @@
1
1
  [![Project generated with PyScaffold](https://img.shields.io/badge/-PyScaffold-005CA0?logo=pyscaffold)](https://pyscaffold.org/)
2
2
  [![PyPI-Server](https://img.shields.io/pypi/v/SingleCellExperiment.svg)](https://pypi.org/project/SingleCellExperiment/)
3
- ![Unit tests](https://github.com/BiocPy/SingleCellExperiment/actions/workflows/pypi-test.yml/badge.svg)
3
+ ![Unit tests](https://github.com/BiocPy/SingleCellExperiment/actions/workflows/run-tests.yml/badge.svg)
4
4
 
5
5
  # SingleCellExperiment
6
6
 
@@ -24,7 +24,7 @@ package_dir =
24
24
  python_requires = >=3.9
25
25
  install_requires =
26
26
  importlib-metadata; python_version<"3.8"
27
- summarizedexperiment>=0.4.5
27
+ summarizedexperiment>=0.5.1
28
28
 
29
29
  [options.packages.find]
30
30
  where = src
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: SingleCellExperiment
3
- Version: 0.5.0
3
+ Version: 0.5.2
4
4
  Summary: Container class for single-cell experiments
5
5
  Home-page: https://github.com/BiocPy/SingleCellExperiment
6
6
  Author: jkanche
@@ -14,7 +14,7 @@ Requires-Python: >=3.9
14
14
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
15
15
  License-File: LICENSE.txt
16
16
  Requires-Dist: importlib-metadata; python_version < "3.8"
17
- Requires-Dist: summarizedexperiment>=0.4.5
17
+ Requires-Dist: summarizedexperiment>=0.5.1
18
18
  Provides-Extra: optional
19
19
  Requires-Dist: anndata==0.9.2; python_version <= "3.9" and extra == "optional"
20
20
  Requires-Dist: anndata>0.9.2; python_version > "3.9" and extra == "optional"
@@ -41,7 +41,7 @@ Requires-Dist: numpy>1.24.4; python_version > "3.9" and extra == "testing"
41
41
 
42
42
  [![Project generated with PyScaffold](https://img.shields.io/badge/-PyScaffold-005CA0?logo=pyscaffold)](https://pyscaffold.org/)
43
43
  [![PyPI-Server](https://img.shields.io/pypi/v/SingleCellExperiment.svg)](https://pypi.org/project/SingleCellExperiment/)
44
- ![Unit tests](https://github.com/BiocPy/SingleCellExperiment/actions/workflows/pypi-test.yml/badge.svg)
44
+ ![Unit tests](https://github.com/BiocPy/SingleCellExperiment/actions/workflows/run-tests.yml/badge.svg)
45
45
 
46
46
  # SingleCellExperiment
47
47
 
@@ -11,8 +11,8 @@ pyproject.toml
11
11
  setup.cfg
12
12
  setup.py
13
13
  tox.ini
14
- .github/workflows/pypi-publish.yml
15
- .github/workflows/pypi-test.yml
14
+ .github/workflows/publish-pypi.yml
15
+ .github/workflows/run-tests.yml
16
16
  docs/Makefile
17
17
  docs/authors.md
18
18
  docs/changelog.md
@@ -1,4 +1,4 @@
1
- summarizedexperiment>=0.4.5
1
+ summarizedexperiment>=0.5.1
2
2
 
3
3
  [:python_version < "3.8"]
4
4
  importlib-metadata
@@ -350,7 +350,7 @@ class SingleCellExperiment(RangedSummarizedExperiment):
350
350
  ######>> reduced_dims <<######
351
351
  ##############################
352
352
 
353
- def get_reduced_dims(self) -> Dict[str, Any]:
353
+ def get_reduced_dimensions(self) -> Dict[str, Any]:
354
354
  """Access dimensionality embeddings.
355
355
 
356
356
  Returns:
@@ -359,7 +359,11 @@ class SingleCellExperiment(RangedSummarizedExperiment):
359
359
  """
360
360
  return self._reduced_dims
361
361
 
362
- def set_reduced_dims(self, reduced_dims: Dict[str, Any], in_place: bool = False) -> "SingleCellExperiment":
362
+ def get_reduced_dims(self) -> Dict[str, Any]:
363
+ """Alias for :py:meth:`~get_reduced_dimensions`, for back-compatibility."""
364
+ return self.get_reduced_dimensions()
365
+
366
+ def set_reduced_dimensions(self, reduced_dims: Dict[str, Any], in_place: bool = False) -> "SingleCellExperiment":
363
367
  """Set new reduced dimensions.
364
368
 
365
369
  Args:
@@ -379,25 +383,43 @@ class SingleCellExperiment(RangedSummarizedExperiment):
379
383
  output._reduced_dims = reduced_dims
380
384
  return output
381
385
 
386
+ def set_reduced_dims(self, reduced_dims: Dict[str, Any], in_place: bool = False) -> "SingleCellExperiment":
387
+ """Alias for :py:meth:`~set_reduced_dimensions`, for back-compatibility."""
388
+ return self.set_reduced_dimensions(reduced_dims=reduced_dims, in_place=in_place)
389
+
382
390
  @property
383
391
  def reduced_dims(self) -> Dict[str, Any]:
384
- """Alias for :py:meth:`~get_reduced_dims`."""
385
- return self.get_reduced_dims()
392
+ """Alias for :py:meth:`~get_reduced_dimensions`."""
393
+ return self.get_reduced_dimensions()
386
394
 
387
395
  @reduced_dims.setter
388
396
  def reduced_dims(self, reduced_dims: Dict[str, Any]):
389
- """Alias for :py:meth:`~set_reduced_dims`."""
397
+ """Alias for :py:meth:`~set_reduced_dimensions`."""
398
+ warn(
399
+ "Setting property 'reduced_dims' is an in-place operation, use 'set_reduced_dimensions' instead",
400
+ UserWarning,
401
+ )
402
+ self.set_reduced_dimensions(reduced_dims, in_place=True)
403
+
404
+ @property
405
+ def reduced_dimensions(self) -> Dict[str, Any]:
406
+ """Alias for :py:meth:`~get_reduced_dimensions`."""
407
+ return self.get_reduced_dimensions()
408
+
409
+ @reduced_dimensions.setter
410
+ def reduced_dimensions(self, reduced_dims: Dict[str, Any]):
411
+ """Alias for :py:meth:`~set_reduced_dimensions`."""
390
412
  warn(
391
- "Setting property 'reduced_dims' is an in-place operation, use 'set_reduced_dims' instead",
413
+ "Setting property 'reduced_dimensions' is an in-place operation, use 'set_reduced_dimensions' instead",
392
414
  UserWarning,
393
415
  )
394
- self.set_reduced_dims(reduced_dims, in_place=True)
416
+ self.set_reduced_dimensions(reduced_dims, in_place=True)
395
417
 
396
418
  ####################################
397
419
  ######>> reduced_dims_names <<######
398
420
  ####################################
399
421
 
400
- def get_reduced_dim_names(self) -> List[str]:
422
+ def get_reduced_dimension_names(self) -> List[str]:
401
423
  """Access reduced dimension names.
402
424
 
403
425
  Returns:
@@ -405,7 +427,11 @@ class SingleCellExperiment(RangedSummarizedExperiment):
405
427
  """
406
428
  return list(self._reduced_dims.keys())
407
429
 
408
- def set_reduced_dim_names(self, names: List[str], in_place: bool = False) -> "SingleCellExperiment":
430
+ def get_reduced_dim_names(self) -> Dict[str, Any]:
431
+ """Alias for :py:meth:`~get_reduced_dimension_names`, for back-compatibility."""
432
+ return self.get_reduced_dimension_names()
433
+
434
+ def set_reduced_dimension_names(self, names: List[str], in_place: bool = False) -> "SingleCellExperiment":
409
435
  """Replace :py:attr:`~.reduced_dims`'s names.
410
436
 
411
437
  Args:
@@ -431,29 +457,47 @@ class SingleCellExperiment(RangedSummarizedExperiment):
431
457
  output._reduced_dims = new_reduced_dims
432
458
  return output
433
459
 
460
+ def set_reduced_dim_names(self, names: List[str], in_place: bool = False) -> "SingleCellExperiment":
461
+ """Alias for :py:meth:`~set_reduced_dimension_names`, for back-compatibility."""
462
+ return self.set_reduced_dimension_names(names=names, in_place=in_place)
463
+
434
464
  @property
435
465
  def reduced_dim_names(self) -> List[str]:
436
- """Alias for :py:meth:`~get_reduced_dim_names`."""
437
- return self.get_reduced_dim_names()
466
+ """Alias for :py:meth:`~get_reduced_dimension_names`."""
467
+ return self.get_reduced_dimension_names()
438
468
 
439
469
  @reduced_dim_names.setter
440
470
  def reduced_dim_names(self, names: List[str]):
441
- """Alias for :py:meth:`~set_reduced_dim_names`."""
471
+ """Alias for :py:meth:`~set_reduced_dimension_names`."""
472
+ warn(
473
+ "Renaming names of property 'reduced_dims' is an in-place operation, use 'set_reduced_dimension_names' instead",
474
+ UserWarning,
475
+ )
476
+ self.set_reduced_dimension_names(names, in_place=True)
477
+
478
+ @property
479
+ def reduced_dimension_names(self) -> List[str]:
480
+ """Alias for :py:meth:`~get_reduced_dimension_names`."""
481
+ return self.get_reduced_dimension_names()
482
+
483
+ @reduced_dimension_names.setter
484
+ def reduced_dimension_names(self, names: List[str]):
485
+ """Alias for :py:meth:`~set_reduced_dimension_names`."""
442
486
  warn(
443
- "Renaming names of property 'reduced_dims' is an in-place operation, use 'set_reduced_dim_names' instead",
487
+ "Renaming names of property 'reduced_dims' is an in-place operation, use 'set_reduced_dimension_names' instead",
444
488
  UserWarning,
445
489
  )
446
- self.set_reduced_dim_names(names, in_place=True)
490
+ self.set_reduced_dimension_names(names, in_place=True)
447
491
 
448
492
  ####################################
449
493
  ######>> reduced_dim getter <<######
450
494
  ####################################
451
495
 
452
- def reduced_dim(self, dimension: Union[str, int]) -> Any:
496
+ def get_reduced_dimension(self, name: Union[str, int]) -> Any:
453
497
  """Access an embedding by name.
454
498
 
455
499
  Args:
456
- dimension:
500
+ name:
457
501
  Name or index position of the reduced dimension.
458
502
 
459
503
  Raises:
@@ -465,21 +509,53 @@ class SingleCellExperiment(RangedSummarizedExperiment):
465
509
  Returns:
466
510
  The embedding.
467
511
  """
468
- if isinstance(dimension, int):
469
- if dimension < 0:
512
+ if isinstance(name, int):
513
+ if name < 0:
470
514
  raise IndexError("Index cannot be negative.")
471
515
 
472
- if dimension > len(self.reduced_dim_names):
516
+ if name > len(self.reduced_dim_names):
473
517
  raise IndexError("Index greater than the number of reduced dimensions.")
474
518
 
475
- return self._reduced_dims[self.reduced_dim_names[dimension]]
476
- elif isinstance(dimension, str):
477
- if dimension not in self._reduced_dims:
478
- raise AttributeError(f"Reduced dimension: {dimension} does not exist.")
519
+ return self._reduced_dims[self.reduced_dim_names[name]]
520
+ elif isinstance(name, str):
521
+ if name not in self._reduced_dims:
522
+ raise AttributeError(f"Reduced dimension: {name} does not exist.")
523
+
524
+ return self._reduced_dims[name]
525
+
526
+ raise TypeError(f"'dimension' must be a string or integer, provided '{type(name)}'.")
527
+
528
+ def reduced_dim(self, name: Union[str, int]) -> Any:
529
+ """Alias for :py:meth:`~get_reduced_dimension`, for back-compatibility."""
530
+ return self.get_reduced_dimension(name=name)
531
+
532
+ def set_reduced_dimension(self, name: str, embedding: Any, in_place: bool = False) -> "SingleCellExperiment":
533
+ """Add or replace :py:attr:`~singlecellexperiment.SingleCellExperiment.reduced_dimension`'s.
534
+
535
+ Args:
536
+ name:
537
+ New or existing embedding or dimension name.
538
+
539
+ embedding:
540
+ Embeddings may be represented as a matrix or a data frame, must contain a shape.
541
+
542
+ in_place:
543
+ Whether to modify the ``SingleCellExperiment`` in place.
479
544
 
480
- return self._reduced_dims[dimension]
545
+ Returns:
546
+ A modified ``SingleCellExperiment`` object, either as a copy of the original
547
+ or as a reference to the (in-place-modified) original.
548
+ """
549
+ output = self._define_output(in_place)
481
550
 
482
- raise TypeError(f"'dimension' must be a string or integer, provided '{type(dimension)}'.")
551
+ _tmp_red_dims = output._reduced_dims
552
+ if in_place is False:
553
+ _tmp_red_dims = _tmp_red_dims.copy()
554
+ _tmp_red_dims[name] = embedding
555
+
556
+ _validate_reduced_dims(_tmp_red_dims, self._shape)
557
+ output._reduced_dims = _tmp_red_dims
558
+ return output
483
559
 
484
560
  ################################
485
561
  ######>> main_expt_name <<######
@@ -629,7 +705,7 @@ class SingleCellExperiment(RangedSummarizedExperiment):
629
705
  ######>> alternative_experiment getter <<######
630
706
  ###############################################
631
707
 
632
- def alternative_experiment(self, name: Union[str, int]) -> Any:
708
+ def get_alternative_experiment(self, name: Union[str, int]) -> Any:
633
709
  """Access alternative experiment by name.
634
710
 
635
711
  Args:
@@ -661,6 +737,42 @@ class SingleCellExperiment(RangedSummarizedExperiment):
661
737
 
662
738
  raise TypeError(f"'name' must be a string or integer, provided '{type(name)}'.")
663
739
 
740
+ def alternative_experiment(self, name: Union[str, int]) -> Any:
741
+ """Alias for :py:meth:`~get_alternative_experiment`, for back-compatibility."""
742
+ return self.get_alternative_experiment(name=name)
743
+
744
+ def set_alternative_experiment(
745
+ self, name: str, alternative_experiment: Any, in_place: bool = False
746
+ ) -> "SingleCellExperiment":
747
+ """Add or replace :py:attr:`~singlecellexperiment.SingleCellExperiment.alternative_experiment`'s.
748
+
749
+ Args:
750
+ name:
751
+ New or existing alternative experiment name.
752
+
753
+ alternative_experiment:
754
+ Alternative experiments must contain the same cells (rows) as the primary experiment.
755
+ Is a subclasses of
756
+ :py:class:`~summarizedexperiment.SummarizedExperiment.SummarizedExperiment`.
757
+
758
+ in_place:
759
+ Whether to modify the ``SingleCellExperiment`` in place.
760
+
761
+ Returns:
762
+ A modified ``BasSingleCellExperimenteSE`` object, either as a copy of the original
763
+ or as a reference to the (in-place-modified) original.
764
+ """
765
+ output = self._define_output(in_place)
766
+
767
+ _tmp_alt_expt = output._alternative_experiments
768
+ if in_place is False:
769
+ _tmp_alt_expt = _tmp_alt_expt.copy()
770
+ _tmp_alt_expt[name] = alternative_experiment
771
+
772
+ _validate_alternative_experiments(_tmp_alt_expt, self._shape)
773
+ output._alternative_experiments = _tmp_alt_expt
774
+ return output
775
+
664
776
  ###########################
665
777
  ######>> row_pairs <<######
666
778
  ###########################
@@ -1027,6 +1139,26 @@ class SingleCellExperiment(RangedSummarizedExperiment):
1027
1139
 
1028
1140
  return MuData(expts)
1029
1141
 
1142
+ ############################
1143
+ ######>> combine ops <<#####
1144
+ ############################
1145
+
1146
+ def relaxed_combine_rows(self, *other) -> "SingleCellExperiment":
1147
+ """Wrapper around :py:func:`~relaxed_combine_rows`."""
1148
+ return relaxed_combine_rows(self, *other)
1149
+
1150
+ def relaxed_combine_columns(self, *other) -> "SingleCellExperiment":
1151
+ """Wrapper around :py:func:`~relaxed_combine_columns`."""
1152
+ return relaxed_combine_columns(self, *other)
1153
+
1154
+ def combine_rows(self, *other) -> "SingleCellExperiment":
1155
+ """Wrapper around :py:func:`~combine_rows`."""
1156
+ return combine_rows(self, *other)
1157
+
1158
+ def combine_columns(self, *other) -> "SingleCellExperiment":
1159
+ """Wrapper around :py:func:`~combine_columns`."""
1160
+ return combine_columns(self, *other)
1161
+
1030
1162
 
1031
1163
  ############################
1032
1164
  ######>> combine ops <<#####
@@ -118,3 +118,28 @@ def test_SCE_creation_with_alts_should_fail():
118
118
  column_data=col_data,
119
119
  alternative_experiments={"alt": tse},
120
120
  )
121
+
122
+ def test_SCE_creation_modifications():
123
+ rse = SummarizedExperiment(
124
+ assays={"counts": counts}, row_data=row_data, column_data=col_data
125
+ )
126
+
127
+ tse = SingleCellExperiment(
128
+ assays={"counts": counts},
129
+ row_data=row_data,
130
+ column_data=col_data,
131
+ alternative_experiments={"alt": rse},
132
+ )
133
+
134
+ assert tse is not None
135
+ assert isinstance(tse, sce)
136
+
137
+ with pytest.raises(Exception):
138
+ tse.set_reduced_dimension("something", np.random.rand(ncols - 1, 4), in_place=False)
139
+
140
+ nassay_tse = tse.set_reduced_dimension("something", np.random.rand(tse.shape[1], 4), in_place=False)
141
+
142
+ assert nassay_tse.get_reduced_dimension_names() != tse.get_reduced_dimension_names()
143
+
144
+ tse.set_reduced_dimension("something", np.random.rand(tse.shape[1], 4), in_place=True)
145
+ assert nassay_tse.get_reduced_dimension_names() == tse.get_reduced_dimension_names()
@@ -27,6 +27,15 @@ def test_combine_columns(experiments):
27
27
  assert len(combined.alternative_experiments) == 0
28
28
  assert len(combined.column_data["A"]) == 20
29
29
 
30
+ combined2 = experiments.se_unnamed.combine_columns(
31
+ experiments.se_unnamed_2
32
+ )
33
+ assert combined2 is not None
34
+ assert isinstance(combined2, SingleCellExperiment)
35
+ assert len(combined2.alternative_experiments) == 0
36
+ assert len(combined2.column_data["A"]) == 20
37
+
38
+
30
39
 
31
40
  def test_relaxed_combine_columns(experiments):
32
41
  ncols = 10
@@ -48,6 +57,12 @@ def test_relaxed_combine_columns(experiments):
48
57
  assert len(combined.alternative_experiments) == 0
49
58
  assert len(combined.row_data["A"]) == 100
50
59
 
60
+ combined2 = experiments.se_unnamed.relaxed_combine_columns(test2)
61
+ assert combined2 is not None
62
+ assert isinstance(combined2, SingleCellExperiment)
63
+ assert len(combined2.alternative_experiments) == 0
64
+ assert len(combined2.row_data["A"]) == 100
65
+
51
66
 
52
67
  def test_combine_with_alts(experiments):
53
68
  combined = biocutils.combine_columns(
@@ -25,6 +25,11 @@ def test_combine_rows(experiments):
25
25
  assert len(combined.alternative_experiments) == 0
26
26
  assert len(combined.row_data["A"]) == 200
27
27
 
28
+ combined2 = experiments.se_unnamed.combine_rows(experiments.se_unnamed_2)
29
+ assert combined2 is not None
30
+ assert isinstance(combined2, SingleCellExperiment)
31
+ assert len(combined2.alternative_experiments) == 0
32
+ assert len(combined2.row_data["A"]) == 200
28
33
 
29
34
  def test_relaxed_combine_rows(experiments):
30
35
  ncols = 10
@@ -46,6 +51,12 @@ def test_relaxed_combine_rows(experiments):
46
51
  assert len(combined.alternative_experiments) == 0
47
52
  assert len(combined.row_data["A"]) == 200
48
53
 
54
+ combined2 = experiments.se_unnamed.relaxed_combine_rows(test2)
55
+ assert combined2 is not None
56
+ assert isinstance(combined2, SingleCellExperiment)
57
+ assert len(combined2.alternative_experiments) == 0
58
+ assert len(combined2.row_data["A"]) == 200
59
+
49
60
 
50
61
  def test_combine_with_alts(experiments):
51
62
  combined = biocutils.combine_rows(