rectanglepy 0.1.7__tar.gz → 0.1.8__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 (53) hide show
  1. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/.bumpversion.cfg +1 -1
  2. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/CHANGELOG.md +10 -0
  3. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/PKG-INFO +2 -1
  4. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/pyproject.toml +2 -1
  5. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/src/rectanglepy/pp/create_signature.py +11 -4
  6. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/src/rectanglepy/pp/rectangle_signature.py +4 -0
  7. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/src/rectanglepy/rectangle.py +15 -3
  8. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/tests/test_rectangle.py +9 -3
  9. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/.cruft.json +0 -0
  10. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/.editorconfig +0 -0
  11. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  12. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  13. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  14. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  15. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/.github/workflows/build.yaml +0 -0
  16. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/.github/workflows/release.yaml +0 -0
  17. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/.github/workflows/release_testpypi.yaml +0 -0
  18. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/.github/workflows/test.yaml +0 -0
  19. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/.gitignore +0 -0
  20. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/.pre-commit-config.yaml +0 -0
  21. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/.readthedocs.yaml +0 -0
  22. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/LICENSE +0 -0
  23. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/README.md +0 -0
  24. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/docs/Makefile +0 -0
  25. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/docs/_static/.gitkeep +0 -0
  26. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/docs/_templates/.gitkeep +0 -0
  27. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/docs/_templates/autosummary/class.rst +0 -0
  28. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/docs/api.md +0 -0
  29. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/docs/changelog.md +0 -0
  30. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/docs/conf.py +0 -0
  31. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/docs/contributing.md +0 -0
  32. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/docs/extensions/typed_returns.py +0 -0
  33. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/docs/index.md +0 -0
  34. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/docs/make.bat +0 -0
  35. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/docs/notebooks/example.ipynb +0 -0
  36. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/docs/references.bib +0 -0
  37. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/docs/references.md +0 -0
  38. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/src/rectanglepy/__init__.py +0 -0
  39. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/src/rectanglepy/data/hao1_annotations_small.zip +0 -0
  40. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/src/rectanglepy/data/hao1_counts_small.zip +0 -0
  41. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/src/rectanglepy/data/small_fino_bulks.zip +0 -0
  42. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/src/rectanglepy/pp/__init__.py +0 -0
  43. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/src/rectanglepy/tl/__init__.py +0 -0
  44. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/src/rectanglepy/tl/deconvolution.py +0 -0
  45. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/tests/data/TIL10_signature.txt +0 -0
  46. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/tests/data/bulk_small.csv +0 -0
  47. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/tests/data/cell_annotations_small.txt +0 -0
  48. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/tests/data/quanTIseq_SimRNAseq_mixture_smaller.csv +0 -0
  49. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/tests/data/quanTIseq_SimRNAseq_read_fractions_small.txt +0 -0
  50. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/tests/data/sc_object_small.csv +0 -0
  51. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/tests/data/signature_hao1.csv +0 -0
  52. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/tests/test_pp.py +0 -0
  53. {rectanglepy-0.1.7 → rectanglepy-0.1.8}/tests/test_tl.py +0 -0
@@ -1,5 +1,5 @@
1
1
  [bumpversion]
2
- current_version = 0.1.7
2
+ current_version = 0.1.8
3
3
  tag = True
4
4
  commit = True
5
5
 
@@ -10,6 +10,16 @@ and this project adheres to [Semantic Versioning][].
10
10
 
11
11
  ## [Unreleased]
12
12
 
13
+ ## [0.1.8] - 2024-09-06
14
+
15
+ ### Added
16
+
17
+ - RectangleSignatureResult now returns correlation of bulk genes with the calculated Unknown cell type fraction
18
+
19
+ ### Fixed
20
+
21
+ - The consensus method now returns the estimations normalized to 1
22
+
13
23
  ## [0.1.7] - 2024-07-25
14
24
 
15
25
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rectanglepy
3
- Version: 0.1.7
3
+ Version: 0.1.8
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
@@ -30,6 +30,7 @@ License: MIT License
30
30
  SOFTWARE.
31
31
  License-File: LICENSE
32
32
  Requires-Python: >=3.10
33
+ Requires-Dist: anndata<0.10.9,>=0.8.0
33
34
  Requires-Dist: loguru
34
35
  Requires-Dist: numpy<2.0.0,>=1.0.0
35
36
  Requires-Dist: pydeseq2==0.4.1
@@ -4,7 +4,7 @@ requires = ["hatchling"]
4
4
 
5
5
  [project]
6
6
  name = "rectanglepy"
7
- version = "0.1.7"
7
+ version = "0.1.8"
8
8
  description = "Hierarchical deconvolution of bulk transcriptomics"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -23,6 +23,7 @@ dependencies = [
23
23
  "quadprog==0.1.11",
24
24
  "loguru",
25
25
  "numpy>=1.0.0,<2.0.0",
26
+ "anndata>=0.8.0,<0.10.9",
26
27
  ]
27
28
 
28
29
  [project.optional-dependencies]
@@ -34,7 +34,9 @@ def _create_condition_number_matrices(de_adjusted, pseudo_signature):
34
34
  loop_range = min(longest_de_analysis, 200)
35
35
  range_minimum = 30
36
36
 
37
- if loop_range < range_minimum:
37
+ if loop_range < 8:
38
+ range_minimum = 2
39
+ elif loop_range < range_minimum:
38
40
  range_minimum = 8
39
41
 
40
42
  for i in range(range_minimum, loop_range):
@@ -368,9 +370,14 @@ def _optimize_parameters(
368
370
  bulks, real_fractions = _generate_pseudo_bulks(sc_data, annotations, genes)
369
371
  for p in ps:
370
372
  for lfc in lfcs:
371
- rmse, pearson_r = _assess_parameter_fit(lfc, p, bulks, real_fractions, pseudo_signature_counts, de_results)
372
- logger.info(f"RMSE:{rmse}, Pearson R:{pearson_r} for p={p}, lfc={lfc}")
373
- results.append({"p": p, "lfc": lfc, "rmse": rmse, "pearson_r": pearson_r})
373
+ try:
374
+ rmse, pearson_r = _assess_parameter_fit(
375
+ lfc, p, bulks, real_fractions, pseudo_signature_counts, de_results
376
+ )
377
+ logger.info(f"RMSE:{rmse}, Pearson R:{pearson_r} for p={p}, lfc={lfc}")
378
+ results.append({"p": p, "lfc": lfc, "rmse": rmse, "pearson_r": pearson_r})
379
+ except Exception as e:
380
+ logger.error(f"Error in assessing parameter fit for p={p}, lfc={lfc}: {e}")
374
381
 
375
382
  results_df = pd.DataFrame(results)
376
383
  results_df = results_df.sort_values(by=["pearson_r", "rmse"], ascending=[False, True])
@@ -22,6 +22,8 @@ class RectangleSignatureResult:
22
22
  The number of marker genes per cell type, as a dictionary. Keys are cell type names, values are the number of marker genes.
23
23
  optimization_result
24
24
  The result of the p lfc cut off optimization, as a pd.DataFrame. Contains the following columns: p, lfc, pearson_r, rsme
25
+ unkn_gene_corr
26
+ The correlation between the unknown cell type and the genes linked to the unknown cell type.
25
27
  """
26
28
 
27
29
  def __init__(
@@ -36,6 +38,7 @@ class RectangleSignatureResult:
36
38
  marker_genes_per_cluster: dict[str, [str]] = None,
37
39
  clustered_signature_genes: pd.Series = None,
38
40
  cluster_assignments: list[int or str] = None,
41
+ unkn_gene_corr: pd.Series = None,
39
42
  ):
40
43
  self.signature_genes = signature_genes
41
44
  self.bias_factors = bias_factors
@@ -47,6 +50,7 @@ class RectangleSignatureResult:
47
50
  self.clustered_bias_factors = clustered_bias_factors
48
51
  self.clustered_signature_genes = clustered_signature_genes
49
52
  self.assignments = cluster_assignments
53
+ self.unkn_gene_corr = unkn_gene_corr
50
54
 
51
55
  def get_signature_matrix(self, include_mrna_bias=True) -> pd.DataFrame:
52
56
  """Calculates the signature matrix by multiplying the pseudobulk_sig_cpm DataFrame subset by signature_genes and the bias_factors Series.
@@ -110,13 +110,17 @@ def rectangle_consens(
110
110
  sample_size=sample_size,
111
111
  run=i,
112
112
  )
113
- rectangle_signature_results.append(signatures)
114
113
  most_recent_signatures = signatures
115
114
  cell_fractions = deconvolution(signatures, bulks, correct_mrna_bias, n_cpus)
116
115
  estimations.append(cell_fractions)
117
-
116
+ unkn_gene_corr = _genes_linked_to_unkn(bulks, cell_fractions["Unknown"])
117
+ signatures.unkn_gene_corr = unkn_gene_corr
118
+ rectangle_signature_results.append(signatures)
119
+ consensus_estimations = pd.concat(estimations).groupby(level=0).median()
120
+ # normalize the estimations to 1
121
+ consensus_estimations = consensus_estimations.div(consensus_estimations.sum(axis=1), axis=0)
118
122
  consensus_results = ConsensusResult(estimations, rectangle_signature_results)
119
- return pd.concat(estimations).groupby(level=0).median(), most_recent_signatures, consensus_results
123
+ return consensus_estimations, most_recent_signatures, consensus_results
120
124
 
121
125
 
122
126
  def rectangle(
@@ -197,3 +201,11 @@ def load_tutorial_data() -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
197
201
  bulks = pd.read_csv(bulks_file, index_col=0, compression="zip")
198
202
 
199
203
  return sc_counts.T, annotations, bulks.T
204
+
205
+
206
+ def _genes_linked_to_unkn(bulks: DataFrame, unkn_fractions: pd.Series):
207
+ genes = bulks.columns
208
+ corr = []
209
+ for gene in genes:
210
+ corr.append(unkn_fractions.corr(bulks.loc[:, gene]))
211
+ return pd.Series(corr, index=genes).sort_values(ascending=False)
@@ -15,12 +15,15 @@ def test_load_tutorial_data():
15
15
 
16
16
  def test_rectangle():
17
17
  sc_data, annotations, bulks = rectanglepy.load_tutorial_data()
18
+ sc_data = sc_data.iloc[:, :500]
18
19
  sc_data_adata = AnnData(sc_data, obs=annotations.to_frame(name="cell_type"))
19
20
 
20
21
  result = rectanglepy.rectangle(sc_data_adata, bulks)
22
+ estimations, signatures = result
21
23
 
22
- assert isinstance(result[0], pd.DataFrame)
23
- assert isinstance(result[1], RectangleSignatureResult)
24
+ assert isinstance(estimations, pd.DataFrame)
25
+ assert isinstance(signatures, RectangleSignatureResult)
26
+ assert isinstance(signatures.unkn_gene_corr, pd.Series)
24
27
 
25
28
 
26
29
  def test_rectangle_consensus():
@@ -36,10 +39,13 @@ def test_rectangle_consensus():
36
39
  assert isinstance(result[1], RectangleSignatureResult)
37
40
  assert isinstance(result[2], ConsensusResult)
38
41
 
39
- # all bias factors should differ, else there is a problem with the random sampling
42
+ estimations = result[0]
40
43
  consensus_results = result[2]
41
44
  signature_results = consensus_results.rectangle_signature_results
42
45
  bias_factors = [result.bias_factors for result in signature_results]
46
+ # there was a problem with the random sampling, the bias factors should differ
43
47
  assert bias_factors[0]["Monocytes"] != bias_factors[1]["Monocytes"]
44
48
  assert bias_factors[0]["Monocytes"] != bias_factors[2]["Monocytes"]
45
49
  assert bias_factors[1]["Monocytes"] != bias_factors[2]["Monocytes"]
50
+ # in the consensus we have to make sure that the estimations are again normalized to 1
51
+ assert estimations.sum(axis=1).all() == 1.0
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
File without changes