rectanglepy 0.1.3__tar.gz → 0.1.6__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 (55) hide show
  1. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/.bumpversion.cfg +1 -1
  2. rectanglepy-0.1.6/.github/workflows/release_testpypi.yaml +44 -0
  3. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/CHANGELOG.md +7 -0
  4. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/PKG-INFO +1 -1
  5. rectanglepy-0.1.6/docs/api.md +17 -0
  6. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/docs/notebooks/example.ipynb +14 -13
  7. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/pyproject.toml +1 -1
  8. rectanglepy-0.1.6/src/rectanglepy/__init__.py +8 -0
  9. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/src/rectanglepy/pp/create_signature.py +9 -6
  10. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/src/rectanglepy/pp/rectangle_signature.py +3 -16
  11. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/src/rectanglepy/rectangle.py +94 -13
  12. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/src/rectanglepy/tl/deconvolution.py +8 -1
  13. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/tests/test_pp.py +1 -1
  14. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/tests/test_rectangle.py +3 -1
  15. rectanglepy-0.1.3/docs/api.md +0 -15
  16. rectanglepy-0.1.3/src/rectanglepy/__init__.py +0 -8
  17. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/.cruft.json +0 -0
  18. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/.editorconfig +0 -0
  19. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  20. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  21. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  22. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  23. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/.github/workflows/build.yaml +0 -0
  24. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/.github/workflows/release.yaml +0 -0
  25. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/.github/workflows/test.yaml +0 -0
  26. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/.gitignore +0 -0
  27. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/.pre-commit-config.yaml +0 -0
  28. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/.readthedocs.yaml +0 -0
  29. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/LICENSE +0 -0
  30. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/README.md +0 -0
  31. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/docs/Makefile +0 -0
  32. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/docs/_static/.gitkeep +0 -0
  33. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/docs/_templates/.gitkeep +0 -0
  34. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/docs/_templates/autosummary/class.rst +0 -0
  35. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/docs/changelog.md +0 -0
  36. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/docs/conf.py +0 -0
  37. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/docs/contributing.md +0 -0
  38. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/docs/extensions/typed_returns.py +0 -0
  39. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/docs/index.md +0 -0
  40. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/docs/make.bat +0 -0
  41. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/docs/references.bib +0 -0
  42. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/docs/references.md +0 -0
  43. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/src/rectanglepy/data/hao1_annotations_small.zip +0 -0
  44. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/src/rectanglepy/data/hao1_counts_small.zip +0 -0
  45. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/src/rectanglepy/data/small_fino_bulks.zip +0 -0
  46. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/src/rectanglepy/pp/__init__.py +0 -0
  47. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/src/rectanglepy/tl/__init__.py +0 -0
  48. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/tests/data/TIL10_signature.txt +0 -0
  49. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/tests/data/bulk_small.csv +0 -0
  50. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/tests/data/cell_annotations_small.txt +0 -0
  51. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/tests/data/quanTIseq_SimRNAseq_mixture_smaller.csv +0 -0
  52. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/tests/data/quanTIseq_SimRNAseq_read_fractions_small.txt +0 -0
  53. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/tests/data/sc_object_small.csv +0 -0
  54. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/tests/data/signature_hao1.csv +0 -0
  55. {rectanglepy-0.1.3 → rectanglepy-0.1.6}/tests/test_tl.py +0 -0
@@ -1,5 +1,5 @@
1
1
  [bumpversion]
2
- current_version = 0.1.3
2
+ current_version = 0.1.6
3
3
  tag = True
4
4
  commit = True
5
5
 
@@ -0,0 +1,44 @@
1
+ name: Manual Upload to TestPyPI
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ jobs:
7
+ package:
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - uses: actions/checkout@v2
11
+ - name: Set up Python 3.10
12
+ uses: actions/setup-python@v2
13
+ with:
14
+ python-version: "3.10"
15
+ - name: Install build dependencies
16
+ run: python -m pip install --upgrade pip wheel twine build
17
+ - name: Build package
18
+ run: python -m build
19
+ - name: Check package
20
+ run: twine check --strict dist/*.whl
21
+
22
+ release:
23
+ name: Release
24
+ runs-on: ubuntu-latest
25
+ steps:
26
+ - name: Checkout code
27
+ uses: actions/checkout@v3
28
+
29
+ - name: Set up Python 3.10
30
+ uses: actions/setup-python@v4
31
+ with:
32
+ python-version: "3.10"
33
+
34
+ - name: Install hatch
35
+ run: pip install hatch
36
+
37
+ - name: Install twine
38
+ run: pip install twine
39
+
40
+ - name: Build project for distribution
41
+ run: hatch build
42
+
43
+ - name: Publish a Python distribution to test PyPI
44
+ run: twine upload --repository testpypi dist/* -u __token__ -p ${{ secrets.TESTPYPI_API_TOKEN }}
@@ -10,6 +10,13 @@ and this project adheres to [Semantic Versioning][].
10
10
 
11
11
  ## [Unreleased]
12
12
 
13
+ ## [0.1.6] - 2024-05-07
14
+
15
+ ### Added
16
+
17
+ - Added consenus method to Rectangle
18
+ - RectangleSignatureResult now contains list of marker genes per cell type / cluster
19
+
13
20
  ## [0.1.0] - 2024-04-25
14
21
 
15
22
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rectanglepy
3
- Version: 0.1.3
3
+ Version: 0.1.6
4
4
  Summary: Hierarchical deconvolution of bulk transcriptomics
5
5
  Project-URL: Documentation, https://rectanglepy.readthedocs.io/
6
6
  Project-URL: Source, https://github.com/ComputationalBiomedicineGroup/Rectangle
@@ -0,0 +1,17 @@
1
+ # API
2
+
3
+ ## Rectangle
4
+
5
+ ```{eval-rst}
6
+ .. currentmodule:: rectanglepy
7
+
8
+ .. autosummary::
9
+ :toctree: generated
10
+
11
+ rectanglepy.rectangle
12
+ rectanglepy.rectangle_consens
13
+ rectanglepy.pp.build_rectangle_signatures
14
+ rectanglepy.tl.deconvolution
15
+ rectanglepy.pp.RectangleSignatureResult
16
+ rectanglepy.ConsensusResult
17
+ ```
@@ -157,6 +157,11 @@
157
157
  "collapsed": false
158
158
  }
159
159
  },
160
+ {
161
+ "metadata": {},
162
+ "cell_type": "markdown",
163
+ "source": "To deconvolute the bulk data in a single step, use the rectangle function. This function returns a tuple of the estimated cell type proportions and the signature result."
164
+ },
160
165
  {
161
166
  "cell_type": "code",
162
167
  "outputs": [],
@@ -195,28 +200,21 @@
195
200
  },
196
201
  {
197
202
  "cell_type": "markdown",
198
- "source": [
199
- "signature_result is a [`RectangleSignatureResult`](../generated/rectanglepy.pp.RectangleSignatureResult.rst) object. Results of estimations vary slightly from machine to machine (due to difference in theunderlying linear algebra packages)"
200
- ],
203
+ "source": "signature_result is a [`RectangleSignatureResult`](../generated/rectanglepy.pp.RectangleSignatureResult.rst) object. ",
201
204
  "metadata": {
202
205
  "collapsed": false
203
206
  }
204
207
  },
205
208
  {
206
209
  "cell_type": "markdown",
207
- "source": [
208
- "## Even sampling and consensus"
209
- ],
210
+ "source": "## Running Rectangle in Consensus mode",
210
211
  "metadata": {
211
212
  "collapsed": false
212
213
  }
213
214
  },
214
215
  {
215
216
  "cell_type": "markdown",
216
- "source": [
217
- "We recommend even subsampling of the sc data.\n",
218
- "You can use the `sample_size` parameter to sample a fixed number of cells per cell type, and run the consensus multiple times to get a more robust result."
219
- ],
217
+ "source": "For some scRNA-seq datatasets it may be beneficial to run rectangle in consensus mode. In this function we run the rectangle algorithm multiple times (`consensus_runs`), where on each iteration we sample `sample_size` cells of each cell type. The final cell type proportions are the median of the proportions estimated in each run.",
220
218
  "metadata": {
221
219
  "collapsed": false
222
220
  }
@@ -224,14 +222,17 @@
224
222
  {
225
223
  "cell_type": "code",
226
224
  "outputs": [],
227
- "source": [
228
- "estimations, signature_result = rectangle.rectangle(sc_adata, bulks, consensus_runs=5, sample_size=1500)"
229
- ],
225
+ "source": "estimations, signature_result, consensus_result = rectangle.rectangle_consens(sc_adata, bulks, consensus_runs=5, sample_size=1500)",
230
226
  "metadata": {
231
227
  "collapsed": false
232
228
  },
233
229
  "execution_count": null
234
230
  },
231
+ {
232
+ "metadata": {},
233
+ "cell_type": "markdown",
234
+ "source": "signature_result holds the signature result([`RectangleSignatureResult`](../generated/rectanglepy.pp.RectangleSignatureResult.rst)) for the most recent consensus run, while consensus_result is a [`ConsensusResult`](../generated/rectanglepy.ConsensusResult.rst) object that holds the results of all the runs."
235
+ },
235
236
  {
236
237
  "cell_type": "markdown",
237
238
  "source": [
@@ -4,7 +4,7 @@ requires = ["hatchling"]
4
4
 
5
5
  [project]
6
6
  name = "rectanglepy"
7
- version = "0.1.3"
7
+ version = "0.1.6"
8
8
  description = "Hierarchical deconvolution of bulk transcriptomics"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -0,0 +1,8 @@
1
+ from importlib.metadata import version
2
+
3
+ from . import pp, tl
4
+ from .rectangle import ConsensusResult, load_tutorial_data, rectangle, rectangle_consens
5
+
6
+ __all__ = ["pp", "tl", "load_tutorial_data", "rectangle", "rectangle_consens", "ConsensusResult"]
7
+
8
+ __version__ = version("rectanglepy")
@@ -155,7 +155,7 @@ def _run_deseq2(countsig: pd.DataFrame, n_cpus: int = None) -> dict[str | int, p
155
155
 
156
156
  def _de_analysis(
157
157
  pseudo_count_sig, sc_data, annotations, p, lfc, optimize_cutoffs: bool, n_cpus: int = None, genes=None
158
- ) -> tuple[Series, dict[str, int] :, DataFrame | None]:
158
+ ) -> tuple[Series, dict[str, [str]] :, DataFrame | None]:
159
159
  logger.info("Starting DE analysis")
160
160
  deseq_results = _run_deseq2(pseudo_count_sig, n_cpus)
161
161
  optimization_results = None
@@ -185,15 +185,15 @@ def _get_marker_genes(deseq_results, logfc, p, pseudo_count_sig):
185
185
  optimal_condition_matrix = condition_number_matrices[optimal_condition_index]
186
186
 
187
187
  markers = optimal_condition_matrix.index
188
- marker_genes_per_cell_type = _count_marker_genes_per_cell_type(de_analysis_adjusted, optimal_condition_number)
188
+ marker_genes_per_cell_type = _get_marker_genes_per_cell_type(de_analysis_adjusted, optimal_condition_number)
189
189
  return markers, marker_genes_per_cell_type
190
190
 
191
191
 
192
- def _count_marker_genes_per_cell_type(de_analysis_adjusted, optimal_condition_number: int) -> dict[str, int]:
192
+ def _get_marker_genes_per_cell_type(de_analysis_adjusted, optimal_condition_number: int) -> dict[str, [str]]:
193
193
  marker_genes_per_cell_type = {}
194
194
  for annotation, result in de_analysis_adjusted.items():
195
- marker_genes_per_cell_type[annotation] = min(len(result), optimal_condition_number)
196
- logger.info(f"Number of marker genes per cell type: {str(marker_genes_per_cell_type)}")
195
+ number_of_genes = min(len(result), optimal_condition_number)
196
+ marker_genes_per_cell_type[annotation] = list(result.index[0:number_of_genes])
197
197
  return marker_genes_per_cell_type
198
198
 
199
199
 
@@ -323,7 +323,9 @@ def build_rectangle_signatures(
323
323
  )
324
324
 
325
325
  clustered_biasfact = _create_bias_factors(clustered_signature, sc_counts, clustered_annotations)
326
- clustered_genes = _de_analysis(clustered_signature, sc_counts, clustered_annotations, p, lfc, False)[0]
326
+ clustered_genes, clustered_marker_genes_per_cell_type, _ = _de_analysis(
327
+ clustered_signature, sc_counts, clustered_annotations, p, lfc, False
328
+ )
327
329
  clustered_signature = _convert_to_cpm(clustered_signature)
328
330
  return RectangleSignatureResult(
329
331
  signature_genes=marker_genes,
@@ -335,6 +337,7 @@ def build_rectangle_signatures(
335
337
  clustered_signature_genes=clustered_genes,
336
338
  clustered_bias_factors=clustered_biasfact,
337
339
  cluster_assignments=assignments,
340
+ marker_genes_per_cluster=clustered_marker_genes_per_cell_type,
338
341
  )
339
342
 
340
343
 
@@ -29,16 +29,18 @@ class RectangleSignatureResult:
29
29
  signature_genes: pd.Series,
30
30
  bias_factors: pd.Series,
31
31
  pseudobulk_sig_cpm: pd.DataFrame,
32
- marker_genes_per_cell_type: dict[str, int],
32
+ marker_genes_per_cell_type: dict[str, [str]],
33
33
  optimization_result: pd.DataFrame = None,
34
34
  clustered_pseudobulk_sig_cpm: pd.DataFrame = None,
35
35
  clustered_bias_factors: pd.Series = None,
36
+ marker_genes_per_cluster: dict[str, [str]] = None,
36
37
  clustered_signature_genes: pd.Series = None,
37
38
  cluster_assignments: list[int or str] = None,
38
39
  ):
39
40
  self.signature_genes = signature_genes
40
41
  self.bias_factors = bias_factors
41
42
  self.pseudobulk_sig_cpm = pseudobulk_sig_cpm
43
+ self.marker_genes_per_cluster = marker_genes_per_cluster
42
44
  self.marker_genes_per_cell_type = marker_genes_per_cell_type
43
45
  self.optimization_result = optimization_result
44
46
  self.clustered_pseudobulk_sig_cpm = clustered_pseudobulk_sig_cpm
@@ -46,21 +48,6 @@ class RectangleSignatureResult:
46
48
  self.clustered_signature_genes = clustered_signature_genes
47
49
  self.assignments = cluster_assignments
48
50
 
49
- def cell_types_with_low_number_of_marker_genes(self) -> list[str]:
50
- """Returns the cell types with less than threshold marker genes.
51
-
52
- Returns
53
- -------
54
- list[str]: The cell types with less than threshold marker genes.
55
-
56
- """
57
- low_annotation_threshold = 30
58
- return [
59
- cell_type
60
- for cell_type, count in self.marker_genes_per_cell_type.items()
61
- if count < low_annotation_threshold
62
- ]
63
-
64
51
  def get_signature_matrix(self, include_mrna_bias=True) -> pd.DataFrame:
65
52
  """Calculates the signature matrix by multiplying the pseudobulk_sig_cpm DataFrame subset by signature_genes and the bias_factors Series.
66
53
 
@@ -8,22 +8,38 @@ from .pp import RectangleSignatureResult, build_rectangle_signatures
8
8
  from .tl import deconvolution
9
9
 
10
10
 
11
- def rectangle(
11
+ class ConsensusResult:
12
+ """A class used to represent the consensus result of the rectangle_consens function.
13
+
14
+ Parameters
15
+ ----------
16
+ estimations
17
+ A list of DataFrame objects representing the estimations from each consensus run.
18
+ rectangle_signature_results
19
+ A list of RectangleSignatureResult objects representing the rectangle signature results from each consensus run.
20
+ """
21
+
22
+ def __init__(self, estimations: list[DataFrame], rectangle_signature_results: list[RectangleSignatureResult]):
23
+ self.estimations = estimations
24
+ self.rectangle_signature_results = rectangle_signature_results
25
+
26
+
27
+ def rectangle_consens(
12
28
  adata: AnnData,
13
29
  bulks: DataFrame,
14
30
  cell_type_col: str = "cell_type",
15
31
  *,
16
32
  layer: str = None,
17
33
  raw: bool = False,
18
- subsample: bool = False,
34
+ subsample: bool = True,
19
35
  sample_size: int = 1500,
20
- consensus_runs: int = 1,
36
+ consensus_runs: int = 5,
21
37
  correct_mrna_bias: bool = True,
22
38
  optimize_cutoffs=True,
23
39
  p=0.015,
24
40
  lfc=1.5,
25
41
  n_cpus: int = None,
26
- ) -> tuple[DataFrame, RectangleSignatureResult]:
42
+ ) -> tuple[DataFrame, RectangleSignatureResult, ConsensusResult]:
27
43
  r"""All in one deconvolution method. Creates signatures and deconvolutes the bulk data. Has options for subsampling and consensus runs.
28
44
 
29
45
  Parameters
@@ -39,26 +55,27 @@ def rectangle(
39
55
  raw
40
56
  A flag indicating whether to use the raw Anndata data. Defaults to False.
41
57
  subsample : bool
42
- A flag indicating whether to balance the single-cell data. Defaults to False.
58
+ A flag indicating whether to balance the single-cell data.
43
59
  sample_size : int
44
- The number of cells to balance the single-cell data to. Defaults to 1500. If cell number is less than this number it takes the original number of cells.
60
+ The number of cells to balance the single-cell data to. If cell number is less than this number it takes the original number of cells.
45
61
  consensus_runs : int
46
- The number of consensus runs to perform. Defaults to 1 for a singular deconvolution run. Consensus runs are performed by subsampling the single-cell data and running the analysis multiple times. The results are then aggregated.
62
+ The number of consensus runs to perform. Consensus runs are performed by subsampling the single-cell data and running the analysis multiple times. The results are then aggregated.
47
63
  optimize_cutoffs
48
- Indicates whether to optimize the p-value and log fold change cutoffs using gridsearch. Defaults to True.
64
+ Indicates whether to optimize the p-value and log fold change cutoffs using gridsearch.
49
65
  p
50
66
  The p-value threshold for the DE analysis (only used if optimize_cutoffs is False).
51
67
  lfc
52
68
  The log fold change threshold for the DE analysis (only used if optimize_cutoffs is False).
53
69
  n_cpus
54
- The number of cpus to use for the DE analysis. Defaults to the number of cpus available.
70
+ The number of cpus to use for the DE analysis. None value takes all cpus available.
55
71
  correct_mrna_bias : bool
56
72
  A flag indicating whether to correct for mRNA bias. Defaults to True.
57
73
 
58
74
  Returns
59
75
  -------
60
- DataFrame : The estimated cell fractions.
61
- RectangleSignatureResult : The result of the rectangle signature analysis.
76
+ DataFrame : The estimated cell fractions consens.
77
+ RectangleSignatureResult : The result of the last consensus run.
78
+ ConsensusResult : Estimations and rectangle signature results for each consensus run.
62
79
  """
63
80
  assert isinstance(adata, AnnData), "adata must be an AnnData object"
64
81
  assert isinstance(bulks, DataFrame), "bulks must be a DataFrame"
@@ -74,6 +91,7 @@ def rectangle(
74
91
  subsample = True
75
92
 
76
93
  estimations = []
94
+ rectangle_signature_results = []
77
95
  most_recent_signatures = None
78
96
 
79
97
  for _i in range(consensus_runs):
@@ -91,11 +109,74 @@ def rectangle(
91
109
  subsample=subsample,
92
110
  sample_size=sample_size,
93
111
  )
112
+ rectangle_signature_results.append(signatures)
113
+ most_recent_signatures = signatures
94
114
  cell_fractions = deconvolution(signatures, bulks, correct_mrna_bias, n_cpus)
95
115
  estimations.append(cell_fractions)
96
- most_recent_signatures = signatures
97
116
 
98
- return pd.concat(estimations).groupby(level=0).median(), most_recent_signatures
117
+ consensus_results = ConsensusResult(estimations, rectangle_signature_results)
118
+ return pd.concat(estimations).groupby(level=0).median(), most_recent_signatures, consensus_results
119
+
120
+
121
+ def rectangle(
122
+ adata: AnnData,
123
+ bulks: DataFrame,
124
+ cell_type_col: str = "cell_type",
125
+ *,
126
+ layer: str = None,
127
+ raw: bool = False,
128
+ correct_mrna_bias: bool = True,
129
+ optimize_cutoffs=True,
130
+ p=0.015,
131
+ lfc=1.5,
132
+ n_cpus: int = None,
133
+ ) -> tuple[DataFrame, RectangleSignatureResult]:
134
+ r"""All in one deconvolution method. Creates signatures and deconvolutes the bulk data. Has options for subsampling and consensus runs.
135
+
136
+ Parameters
137
+ ----------
138
+ adata
139
+ The single-cell count data as a DataFrame. DataFrame must have the genes as index and cell identifier as columns. Each entry should be in raw counts.
140
+ bulks
141
+ The bulk data as a DataFrame. DataFrame must have the bulk identifier as index and the genes as columns. Each entry should be in transcripts per million (TPM).
142
+ cell_type_col
143
+ The annotations corresponding to the single-cell count data. Series data should have the cell identifier as index and the annotations as values.
144
+ layer
145
+ The Anndata layer to use for the single-cell data.
146
+ raw
147
+ A flag indicating whether to use the raw Anndata data.
148
+ optimize_cutoffs
149
+ Indicates whether to optimize the p-value and log fold change cutoffs using gridsearch.
150
+ p
151
+ The p-value threshold for the DE analysis (only used if optimize_cutoffs is False).
152
+ lfc
153
+ The log fold change threshold for the DE analysis (only used if optimize_cutoffs is False).
154
+ n_cpus
155
+ The number of cpus to use for the DE analysis. None value takes all cpus available.
156
+ correct_mrna_bias : bool
157
+ A flag indicating whether to correct for mRNA bias. Defaults to True.
158
+
159
+ Returns
160
+ -------
161
+ DataFrame : The estimated cell fractions.
162
+ RectangleSignatureResult : The result of the rectangle signature analysis.
163
+ """
164
+ estimations, signatures, _ = rectangle_consens(
165
+ adata,
166
+ bulks,
167
+ cell_type_col,
168
+ layer=layer,
169
+ raw=raw,
170
+ subsample=False,
171
+ sample_size=-1,
172
+ consensus_runs=1,
173
+ correct_mrna_bias=correct_mrna_bias,
174
+ optimize_cutoffs=optimize_cutoffs,
175
+ p=p,
176
+ lfc=lfc,
177
+ n_cpus=n_cpus,
178
+ )
179
+ return estimations, signatures
99
180
 
100
181
 
101
182
  def load_tutorial_data() -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
@@ -257,7 +257,14 @@ def _deconvolute(signatures: RectangleSignatureResult, bulk: pd.Series, correct_
257
257
  averaged_start_fractions = (start_fractions + union_direct_fraction) / 2
258
258
 
259
259
  final_fractions = []
260
- cell_types_with_low_number_of_marker_genes = signatures.cell_types_with_low_number_of_marker_genes()
260
+
261
+ low_number_threshold = 30
262
+ cell_types_with_low_number_of_marker_genes = [
263
+ cell_type
264
+ for cell_type, num_marker_genes in signatures.marker_genes_per_cell_type.items()
265
+ if len(num_marker_genes) < low_number_threshold
266
+ ]
267
+
261
268
  for cell_type in list(averaged_start_fractions.index):
262
269
  if cell_type in cell_types_with_low_number_of_marker_genes:
263
270
  final_fractions.append(recursive_fractions[cell_type])
@@ -146,7 +146,7 @@ def test_build_rectangle_signatures(small_data):
146
146
  adata = AnnData(sc_counts.T, obs=annotations.to_frame(name="cell_type"))
147
147
  results = build_rectangle_signatures(adata, "cell_type", bulks=bulk.T, p=0.5, lfc=0.1, optimize_cutoffs=False)
148
148
  assert results.assignments is None # not enough cells to cluster
149
- assert 10 < len(results.signature_genes) < 100
149
+ assert 10 < len(results.signature_genes) < 400
150
150
 
151
151
 
152
152
  def test_generate_pseudo_bulks(small_data):
@@ -2,6 +2,7 @@ import pandas as pd
2
2
  from anndata import AnnData
3
3
 
4
4
  import rectanglepy.rectangle
5
+ from rectanglepy import ConsensusResult
5
6
  from rectanglepy.pp import RectangleSignatureResult
6
7
 
7
8
 
@@ -26,9 +27,10 @@ def test_rectangle_consensus():
26
27
  sc_data, annotations, bulks = rectanglepy.load_tutorial_data()
27
28
  sc_data_adata = AnnData(sc_data, obs=annotations.to_frame(name="cell_type"))
28
29
 
29
- result = rectanglepy.rectangle(
30
+ result = rectanglepy.rectangle_consens(
30
31
  sc_data_adata, bulks, optimize_cutoffs=False, p=0.5, lfc=0.0, consensus_runs=2, sample_size=50
31
32
  )
32
33
 
33
34
  assert isinstance(result[0], pd.DataFrame)
34
35
  assert isinstance(result[1], RectangleSignatureResult)
36
+ assert isinstance(result[2], ConsensusResult)
@@ -1,15 +0,0 @@
1
- # API
2
-
3
- ## Rectangle
4
-
5
- ```{eval-rst}
6
- .. currentmodule:: rectanglepy
7
-
8
- .. autosummary::
9
- :toctree: generated
10
-
11
- rectangle
12
- pp.build_rectangle_signatures
13
- pp.RectangleSignatureResult
14
- tl.deconvolution
15
- ```
@@ -1,8 +0,0 @@
1
- from importlib.metadata import version
2
-
3
- from . import pp, tl
4
- from .rectangle import load_tutorial_data, rectangle
5
-
6
- __all__ = ["pp", "tl", "load_tutorial_data", "rectangle"]
7
-
8
- __version__ = version("rectanglepy")
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes