nova-clone 0.1.0__py3-none-any.whl
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.
- nova_clone/__init__.py +1 -0
- nova_clone/algorithm/__init__.py +2 -0
- nova_clone/algorithm/_build_intbc_graph.py +135 -0
- nova_clone/algorithm/_call_clones_from_coresets.py +235 -0
- nova_clone/algorithm/_clone_call_ops.py +258 -0
- nova_clone/algorithm/_clone_calling_algorithm.py +1571 -0
- nova_clone/algorithm/_compute_cellbc_vs_coreset_overlap_matrix.py +143 -0
- nova_clone/algorithm/_compute_coreset_co_assignment_matrix.py +170 -0
- nova_clone/algorithm/_find_maximal_coresets.py +428 -0
- nova_clone/algorithm/_keep_reliable_edges.py +202 -0
- nova_clone/algorithm/_make_coresets_disjoint.py +114 -0
- nova_clone/algorithm/_prune_coresets.py +164 -0
- nova_clone/algorithm/_prune_custom_intbcs.py +150 -0
- nova_clone/algorithm/_prune_likely_homoplastic_intbcs.py +162 -0
- nova_clone/algorithm/_prune_likely_sequencing_errors.py +201 -0
- nova_clone/algorithm/_prune_low_cellbc_count_intbcs.py +154 -0
- nova_clone/algorithm/_prune_low_umi_count_intbcs.py +152 -0
- nova_clone/algorithm/_types.py +150 -0
- nova_clone/algorithm/_utils.py +53 -0
- nova_clone/algorithm/cassiopeia/__init__.py +1 -0
- nova_clone/algorithm/cassiopeia/_call_lineage_groups.py +270 -0
- nova_clone/caching/__init__.py +24 -0
- nova_clone/caching/_cached.py +175 -0
- nova_clone/caching/_cached_computation.py +369 -0
- nova_clone/caching/_cached_parallel_computation.py +428 -0
- nova_clone/caching/_common.py +200 -0
- nova_clone/data/__init__.py +1 -0
- nova_clone/qc/__init__.py +179 -0
- nova_clone/qc/_clone_intbc_sets.py +234 -0
- nova_clone/qc/_compare_clone_calls.py +218 -0
- nova_clone/qc/_data_retention.py +175 -0
- nova_clone/qc/_homoplasy.py +81 -0
- nova_clone/qc/_inter_clonal_kinship.py +60 -0
- nova_clone/qc/_intra_clonal_kinship.py +172 -0
- nova_clone/qc/_multiplet_rate.py +158 -0
- nova_clone/qc/_number_of_clones.py +153 -0
- nova_clone/qc/_pre_qc.py +485 -0
- nova_clone/simulation/HDBSCAN_method_adjusted.py +68 -0
- nova_clone/simulation/__init__.py +0 -0
- nova_clone/simulation/_caching.py +40 -0
- nova_clone/simulation/benchmarking.py +1221 -0
- nova_clone/simulation/clone_to_sequences.py +408 -0
- nova_clone/simulation/creating_tree.py +416 -0
- nova_clone/simulation/evaluation.py +344 -0
- nova_clone/simulation/jaccard_hierarchical_by_intBC.py +78 -0
- nova_clone/simulation/plot_benchmark_lines.py +226 -0
- nova_clone/simulation/slice_benchmark.py +640 -0
- nova_clone/simulation/slice_benchmark_clone_calling.py +68 -0
- nova_clone-0.1.0.dist-info/METADATA +298 -0
- nova_clone-0.1.0.dist-info/RECORD +53 -0
- nova_clone-0.1.0.dist-info/WHEEL +5 -0
- nova_clone-0.1.0.dist-info/licenses/LICENSE +28 -0
- nova_clone-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module for computing the overlap (intersection) between intBC sets (of cellBCs)
|
|
3
|
+
and coresets.
|
|
4
|
+
|
|
5
|
+
The main function exposed by this module is `compute_cellbc_vs_coreset_overlap_matrix`.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
import sys
|
|
10
|
+
import time
|
|
11
|
+
from typing import *
|
|
12
|
+
|
|
13
|
+
from multiset import Multiset
|
|
14
|
+
import numpy as np
|
|
15
|
+
import tqdm
|
|
16
|
+
|
|
17
|
+
from ._types import *
|
|
18
|
+
from ._utils import _cell_intbc_sets_from_intbc_tables
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _init_logger():
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
logger.setLevel(logging.INFO)
|
|
24
|
+
fmt_str = "[%(asctime)s] - %(name)s - %(levelname)s - %(message)s"
|
|
25
|
+
formatter = logging.Formatter(fmt_str)
|
|
26
|
+
|
|
27
|
+
consoleHandler = logging.StreamHandler(sys.stdout)
|
|
28
|
+
consoleHandler.setFormatter(formatter)
|
|
29
|
+
logger.addHandler(consoleHandler)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
_init_logger()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ComputeCellBCvsCoresetOverlapMatrixReturnType(NamedTuple):
|
|
36
|
+
"""
|
|
37
|
+
Object returned by the `compute_cellbc_vs_coreset_overlap_matrix` function.
|
|
38
|
+
|
|
39
|
+
Attributes:
|
|
40
|
+
cellbc_vs_coreset_overlap_matrix: Of size #cellBC x #coresets, the
|
|
41
|
+
size of the intersection between the intBC set of each cellBC and
|
|
42
|
+
each coreset.
|
|
43
|
+
total_time: Total time taken.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
cellbc_vs_coreset_overlap_matrix: pd.DataFrame
|
|
47
|
+
total_time: float
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def compute_cellbc_vs_coreset_overlap_matrix(
|
|
51
|
+
cellbc_intbc_sets: Dict[IntBCType, Set[IntBCType]],
|
|
52
|
+
coresets: List[Coreset[IntBCType]],
|
|
53
|
+
) -> ComputeCellBCvsCoresetOverlapMatrixReturnType:
|
|
54
|
+
"""
|
|
55
|
+
Pandas dataframe of cell vs coreset.
|
|
56
|
+
|
|
57
|
+
Entry (i, j) contains the overlap of cell i's intBC set with coreset j.
|
|
58
|
+
"""
|
|
59
|
+
st = time.time()
|
|
60
|
+
logger = logging.getLogger(__name__)
|
|
61
|
+
logger.info("Going to compute_cellbc_vs_coreset_overlap_matrix ...")
|
|
62
|
+
cells = sorted(cellbc_intbc_sets.keys())
|
|
63
|
+
res_array = np.zeros(shape=(len(cells), len(coresets)))
|
|
64
|
+
|
|
65
|
+
for cell_idx, cell in tqdm.tqdm(list(enumerate(cells))):
|
|
66
|
+
cell_intbc_set = cellbc_intbc_sets[cell]
|
|
67
|
+
for coreset_idx, coreset in enumerate(coresets):
|
|
68
|
+
overlap = len([intbc for intbc in coreset if intbc in cell_intbc_set]) # Handles multiset coresets (for single-intBC support)
|
|
69
|
+
res_array[cell_idx, coreset_idx] = overlap
|
|
70
|
+
|
|
71
|
+
cellbc_vs_coreset_overlap_matrix = pd.DataFrame(
|
|
72
|
+
res_array,
|
|
73
|
+
index=cells,
|
|
74
|
+
columns=list(range(len(coresets))),
|
|
75
|
+
)
|
|
76
|
+
total_time = time.time() - st
|
|
77
|
+
res = ComputeCellBCvsCoresetOverlapMatrixReturnType(
|
|
78
|
+
cellbc_vs_coreset_overlap_matrix=cellbc_vs_coreset_overlap_matrix,
|
|
79
|
+
total_time=total_time,
|
|
80
|
+
)
|
|
81
|
+
logger.info(
|
|
82
|
+
f"Done with compute_cellbc_vs_coreset_overlap_matrix! Total time: {total_time}"
|
|
83
|
+
)
|
|
84
|
+
return res
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def test_compute_cell_vs_coreset_overlap_matrix():
|
|
88
|
+
cellbc_intbc_sets = {
|
|
89
|
+
"cell_1": {"1", "2", "3"},
|
|
90
|
+
"cell_2": {"4", "5", "6"},
|
|
91
|
+
"cell_3": {"1", "2", "3", "4", "5", "6"},
|
|
92
|
+
"cell_4": {"1", "2", "4"},
|
|
93
|
+
}
|
|
94
|
+
coresets = [
|
|
95
|
+
{"1", "2", "3"},
|
|
96
|
+
{"4", "5", "6"},
|
|
97
|
+
]
|
|
98
|
+
mat = compute_cellbc_vs_coreset_overlap_matrix(
|
|
99
|
+
cellbc_intbc_sets=cellbc_intbc_sets,
|
|
100
|
+
coresets=coresets,
|
|
101
|
+
).cellbc_vs_coreset_overlap_matrix
|
|
102
|
+
np.testing.assert_equal(
|
|
103
|
+
mat,
|
|
104
|
+
np.array(
|
|
105
|
+
[
|
|
106
|
+
[3, 0],
|
|
107
|
+
[0, 3],
|
|
108
|
+
[3, 3],
|
|
109
|
+
[2, 1],
|
|
110
|
+
]
|
|
111
|
+
),
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def test_compute_cell_vs_coreset_overlap_matrix_with_multisets():
|
|
116
|
+
cellbc_intbc_sets = {
|
|
117
|
+
"cell_1": {"1", "2"},
|
|
118
|
+
"cell_2": {"1", "3"},
|
|
119
|
+
"cell_3": {"1", "2", "3"},
|
|
120
|
+
"cell_4": {"1", "2", "4"},
|
|
121
|
+
"cell_5": {"4"},
|
|
122
|
+
}
|
|
123
|
+
coresets = [
|
|
124
|
+
{"1", "2"},
|
|
125
|
+
{"1", "3"},
|
|
126
|
+
Multiset(["4"]) + Multiset(["4"]),
|
|
127
|
+
]
|
|
128
|
+
mat = compute_cellbc_vs_coreset_overlap_matrix(
|
|
129
|
+
cellbc_intbc_sets=cellbc_intbc_sets,
|
|
130
|
+
coresets=coresets,
|
|
131
|
+
).cellbc_vs_coreset_overlap_matrix
|
|
132
|
+
np.testing.assert_equal(
|
|
133
|
+
mat,
|
|
134
|
+
np.array(
|
|
135
|
+
[
|
|
136
|
+
[2, 1, 0],
|
|
137
|
+
[1, 2, 0],
|
|
138
|
+
[2, 2, 0],
|
|
139
|
+
[2, 1, 2],
|
|
140
|
+
[0, 0, 2],
|
|
141
|
+
]
|
|
142
|
+
),
|
|
143
|
+
)
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module for computing the number of cellBCs assigned to two coresets.
|
|
3
|
+
|
|
4
|
+
The main function exposed by this module is `compute_coreset_co_assignment_matrix`.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
import sys
|
|
9
|
+
import time
|
|
10
|
+
from typing import *
|
|
11
|
+
from multiset import Multiset
|
|
12
|
+
|
|
13
|
+
import numpy as np
|
|
14
|
+
import tqdm
|
|
15
|
+
|
|
16
|
+
from ._types import *
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _init_logger():
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
logger.setLevel(logging.INFO)
|
|
22
|
+
fmt_str = "[%(asctime)s] - %(name)s - %(levelname)s - %(message)s"
|
|
23
|
+
formatter = logging.Formatter(fmt_str)
|
|
24
|
+
|
|
25
|
+
consoleHandler = logging.StreamHandler(sys.stdout)
|
|
26
|
+
consoleHandler.setFormatter(formatter)
|
|
27
|
+
logger.addHandler(consoleHandler)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
_init_logger()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ComputeCoresetCoAssignmentMatrixReturnType(NamedTuple):
|
|
34
|
+
"""
|
|
35
|
+
Object returned by the `compute_coreset_co_assignment_matrix` function.
|
|
36
|
+
|
|
37
|
+
Attributes:
|
|
38
|
+
coreset_co_assignment_matrix: #coresets x #coresets, a numpy array
|
|
39
|
+
containing the number of cellBCs mapping to those two coresets.
|
|
40
|
+
(In particular, the diagonal contains the number of cellBC mapping
|
|
41
|
+
to that coerset).
|
|
42
|
+
total_time: Total time taken.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
coreset_co_assignment_matrix: pd.DataFrame
|
|
46
|
+
total_time: float
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def compute_coreset_co_assignment_matrix(
|
|
50
|
+
cellbc_intbc_sets: Dict[CellBCType, Set[IntBCType]],
|
|
51
|
+
coresets: List[Coreset[IntBCType]],
|
|
52
|
+
min_overlap_for_assigning_cellbc: int,
|
|
53
|
+
) -> ComputeCoresetCoAssignmentMatrixReturnType:
|
|
54
|
+
"""
|
|
55
|
+
Map cells to coresets to build the coreset co-assignment matrix.
|
|
56
|
+
|
|
57
|
+
The coreset co-assignment matrix M contains the statistics:
|
|
58
|
+
M_{i,j} = #(cell assigned to coresets i and j)
|
|
59
|
+
"""
|
|
60
|
+
st = time.time()
|
|
61
|
+
logger = logging.getLogger(__name__)
|
|
62
|
+
logger.info("Going to compute_coreset_co_assignment_matrix ...")
|
|
63
|
+
num_coresets = len(coresets)
|
|
64
|
+
res = np.zeros(shape=(num_coresets, num_coresets))
|
|
65
|
+
for cell, cell_intbc_set in tqdm.tqdm(cellbc_intbc_sets.items()):
|
|
66
|
+
coresets_assigned = []
|
|
67
|
+
for coreset_idx, coreset in enumerate(coresets):
|
|
68
|
+
overlap = len([intbc for intbc in coreset if intbc in cell_intbc_set]) # Handles multiset coresets
|
|
69
|
+
if overlap >= min_overlap_for_assigning_cellbc:
|
|
70
|
+
coresets_assigned.append(coreset_idx)
|
|
71
|
+
for coreset_idx_1 in coresets_assigned:
|
|
72
|
+
for coreset_idx_2 in coresets_assigned:
|
|
73
|
+
if coreset_idx_1 < coreset_idx_2:
|
|
74
|
+
res[coreset_idx_1, coreset_idx_2] += 1
|
|
75
|
+
res[coreset_idx_2, coreset_idx_1] += 1
|
|
76
|
+
elif coreset_idx_1 == coreset_idx_2:
|
|
77
|
+
res[coreset_idx_1, coreset_idx_2] += 1
|
|
78
|
+
total_time = time.time() - st
|
|
79
|
+
res = ComputeCoresetCoAssignmentMatrixReturnType(
|
|
80
|
+
coreset_co_assignment_matrix=res,
|
|
81
|
+
total_time=total_time,
|
|
82
|
+
)
|
|
83
|
+
logger.info(
|
|
84
|
+
f"Done with compute_coreset_co_assignment_matrix! Total time: {total_time}"
|
|
85
|
+
)
|
|
86
|
+
return res
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def test_compute_coreset_co_assignment_matrix():
|
|
90
|
+
cellbc_intbc_sets = {
|
|
91
|
+
"cell_1": {"1", "2", "3"},
|
|
92
|
+
"cell_2": {"4", "5", "6"},
|
|
93
|
+
"cell_3": {"1", "2", "3", "4", "5", "6"},
|
|
94
|
+
"cell_4": {"1", "2", "4"},
|
|
95
|
+
}
|
|
96
|
+
coresets = [
|
|
97
|
+
{"1", "2", "3"},
|
|
98
|
+
{"4", "5", "6"},
|
|
99
|
+
]
|
|
100
|
+
mat = compute_coreset_co_assignment_matrix(
|
|
101
|
+
cellbc_intbc_sets=cellbc_intbc_sets,
|
|
102
|
+
coresets=coresets,
|
|
103
|
+
min_overlap_for_assigning_cellbc=3,
|
|
104
|
+
).coreset_co_assignment_matrix
|
|
105
|
+
np.testing.assert_equal(
|
|
106
|
+
mat,
|
|
107
|
+
np.array(
|
|
108
|
+
[
|
|
109
|
+
[2, 1],
|
|
110
|
+
[1, 2],
|
|
111
|
+
]
|
|
112
|
+
),
|
|
113
|
+
)
|
|
114
|
+
mat = compute_coreset_co_assignment_matrix(
|
|
115
|
+
cellbc_intbc_sets=cellbc_intbc_sets,
|
|
116
|
+
coresets=coresets,
|
|
117
|
+
min_overlap_for_assigning_cellbc=2,
|
|
118
|
+
).coreset_co_assignment_matrix
|
|
119
|
+
np.testing.assert_equal(
|
|
120
|
+
mat,
|
|
121
|
+
np.array(
|
|
122
|
+
[
|
|
123
|
+
[3, 1],
|
|
124
|
+
[1, 2],
|
|
125
|
+
]
|
|
126
|
+
),
|
|
127
|
+
)
|
|
128
|
+
mat = compute_coreset_co_assignment_matrix(
|
|
129
|
+
cellbc_intbc_sets=cellbc_intbc_sets,
|
|
130
|
+
coresets=coresets,
|
|
131
|
+
min_overlap_for_assigning_cellbc=1,
|
|
132
|
+
).coreset_co_assignment_matrix
|
|
133
|
+
np.testing.assert_equal(
|
|
134
|
+
mat,
|
|
135
|
+
np.array(
|
|
136
|
+
[
|
|
137
|
+
[3, 2],
|
|
138
|
+
[2, 3],
|
|
139
|
+
]
|
|
140
|
+
),
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def test_compute_coreset_co_assignment_matrix_multisets():
|
|
145
|
+
cellbc_intbc_sets = {
|
|
146
|
+
"cell_1": {"1", "2"},
|
|
147
|
+
"cell_2": {"1", "3"},
|
|
148
|
+
"cell_3": {"1", "2", "3"},
|
|
149
|
+
"cell_4": {"1", "2", "4"},
|
|
150
|
+
}
|
|
151
|
+
coresets = [
|
|
152
|
+
{"1", "2"},
|
|
153
|
+
{"1", "3"},
|
|
154
|
+
Multiset(["4"]) + Multiset(["4"]),
|
|
155
|
+
]
|
|
156
|
+
mat = compute_coreset_co_assignment_matrix(
|
|
157
|
+
cellbc_intbc_sets=cellbc_intbc_sets,
|
|
158
|
+
coresets=coresets,
|
|
159
|
+
min_overlap_for_assigning_cellbc=2,
|
|
160
|
+
).coreset_co_assignment_matrix
|
|
161
|
+
np.testing.assert_equal(
|
|
162
|
+
mat,
|
|
163
|
+
np.array(
|
|
164
|
+
[
|
|
165
|
+
[3, 1, 1],
|
|
166
|
+
[1, 2, 0],
|
|
167
|
+
[1, 0, 1],
|
|
168
|
+
]
|
|
169
|
+
),
|
|
170
|
+
)
|