ModDotPlot 0.9.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.
- ModDotPlot-0.9.0.dist-info/LICENSE +21 -0
- ModDotPlot-0.9.0.dist-info/METADATA +421 -0
- ModDotPlot-0.9.0.dist-info/RECORD +14 -0
- ModDotPlot-0.9.0.dist-info/WHEEL +5 -0
- ModDotPlot-0.9.0.dist-info/entry_points.txt +2 -0
- ModDotPlot-0.9.0.dist-info/top_level.txt +1 -0
- moddotplot/__init__.py +1 -0
- moddotplot/__main__.py +11 -0
- moddotplot/const.py +293 -0
- moddotplot/estimate_identity.py +537 -0
- moddotplot/interactive.py +1755 -0
- moddotplot/moddotplot.py +1127 -0
- moddotplot/parse_fasta.py +156 -0
- moddotplot/static_plots.py +1264 -0
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import math
|
|
3
|
+
import numpy as np
|
|
4
|
+
from moddotplot.const import (
|
|
5
|
+
SEQUENTIAL_PALETTES,
|
|
6
|
+
DIVERGING_PALETTES,
|
|
7
|
+
QUALITATIVE_PALETTES,
|
|
8
|
+
)
|
|
9
|
+
from palettable import colorbrewer
|
|
10
|
+
from typing import List, Set, Dict, Tuple
|
|
11
|
+
import mmh3
|
|
12
|
+
|
|
13
|
+
from moddotplot.parse_fasta import printProgressBar
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def removeAmbiguousBases(mod_list, k):
|
|
17
|
+
# Ambiguous IUPAC codes
|
|
18
|
+
bases_to_remove = ["R", "Y", "M", "K", "S", "W", "H", "B", "V", "D", "N"]
|
|
19
|
+
kmers_to_remove = set()
|
|
20
|
+
for i in range(len(bases_to_remove)):
|
|
21
|
+
result_string = str(bases_to_remove[i]) * k
|
|
22
|
+
kmers_to_remove.add(mmh3.hash(result_string))
|
|
23
|
+
mod_set = set(mod_list)
|
|
24
|
+
# Remove homopolymers of ambiguous nucleotides
|
|
25
|
+
mod_set.difference_update(kmers_to_remove)
|
|
26
|
+
return mod_set
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def createSelfMatrix(
|
|
30
|
+
sequence_length,
|
|
31
|
+
sequence,
|
|
32
|
+
window_size,
|
|
33
|
+
sparsity,
|
|
34
|
+
delta,
|
|
35
|
+
k,
|
|
36
|
+
identity,
|
|
37
|
+
ambiguous,
|
|
38
|
+
sketch_size,
|
|
39
|
+
):
|
|
40
|
+
no_neighbors = partitionOverlaps(sequence, window_size, 0, sequence_length, k)
|
|
41
|
+
if delta > 0:
|
|
42
|
+
neighbors = partitionOverlaps(sequence, window_size, delta, sequence_length, k)
|
|
43
|
+
else:
|
|
44
|
+
neighbors = no_neighbors
|
|
45
|
+
|
|
46
|
+
neighbors_mods = convertToModimizers(neighbors, sparsity, ambiguous, k, sketch_size)
|
|
47
|
+
no_neighbors_mods = convertToModimizers(
|
|
48
|
+
no_neighbors, sparsity, ambiguous, k, sketch_size
|
|
49
|
+
)
|
|
50
|
+
matrix = selfContainmentMatrix(
|
|
51
|
+
no_neighbors_mods, neighbors_mods, k, identity, ambiguous
|
|
52
|
+
)
|
|
53
|
+
return matrix
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def createPairwiseMatrix(
|
|
57
|
+
larger_length,
|
|
58
|
+
smaller_length,
|
|
59
|
+
larger_seq,
|
|
60
|
+
smaller_seq,
|
|
61
|
+
window_size,
|
|
62
|
+
sparsity,
|
|
63
|
+
delta,
|
|
64
|
+
k,
|
|
65
|
+
identity,
|
|
66
|
+
ambiguous,
|
|
67
|
+
expectation,
|
|
68
|
+
):
|
|
69
|
+
no_neighbors_large = partitionOverlaps(larger_seq, window_size, 0, larger_length, k)
|
|
70
|
+
no_neighbors_small = partitionOverlaps(
|
|
71
|
+
smaller_seq, window_size, 0, smaller_length, k
|
|
72
|
+
)
|
|
73
|
+
if delta > 0:
|
|
74
|
+
neighbors_large = partitionOverlaps(
|
|
75
|
+
larger_seq, window_size, delta, larger_length, k
|
|
76
|
+
)
|
|
77
|
+
neighbors_small = partitionOverlaps(
|
|
78
|
+
smaller_seq, window_size, delta, smaller_length, k
|
|
79
|
+
)
|
|
80
|
+
else:
|
|
81
|
+
neighbors_large = no_neighbors_large
|
|
82
|
+
neighbors_small = no_neighbors_small
|
|
83
|
+
|
|
84
|
+
neighbors_mods_large = convertToModimizers(
|
|
85
|
+
neighbors_large, sparsity, ambiguous, k, expectation
|
|
86
|
+
)
|
|
87
|
+
no_neighbors_mods_large = convertToModimizers(
|
|
88
|
+
no_neighbors_large, sparsity, ambiguous, k, expectation
|
|
89
|
+
)
|
|
90
|
+
neighbors_mods_small = convertToModimizers(
|
|
91
|
+
neighbors_small, sparsity, ambiguous, k, expectation
|
|
92
|
+
)
|
|
93
|
+
no_neighbors_mods_small = convertToModimizers(
|
|
94
|
+
no_neighbors_small, sparsity, ambiguous, k, expectation
|
|
95
|
+
)
|
|
96
|
+
matrix = pairwiseContainmentMatrix(
|
|
97
|
+
no_neighbors_mods_large,
|
|
98
|
+
no_neighbors_mods_small,
|
|
99
|
+
neighbors_mods_large,
|
|
100
|
+
neighbors_mods_small,
|
|
101
|
+
identity,
|
|
102
|
+
k,
|
|
103
|
+
False,
|
|
104
|
+
)
|
|
105
|
+
return matrix
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def partitionOverlaps(
|
|
109
|
+
lst: List[int], win: int, delta: float, seq_len: int, k: int
|
|
110
|
+
) -> List[List[int]]:
|
|
111
|
+
kmer_list = []
|
|
112
|
+
kmer_to_genomic_coordinate_offset = win - k + 1
|
|
113
|
+
delta_offset = win * delta
|
|
114
|
+
|
|
115
|
+
# Set the first window to contain win - k + 1 kmers.
|
|
116
|
+
starting_end_index = int(round(kmer_to_genomic_coordinate_offset + delta_offset))
|
|
117
|
+
kmer_list.append(lst[0:starting_end_index])
|
|
118
|
+
counter = win - k + 1
|
|
119
|
+
|
|
120
|
+
# Set normal windows
|
|
121
|
+
while counter <= (seq_len - win):
|
|
122
|
+
start_index = counter + 1
|
|
123
|
+
end_index = win + counter + 1
|
|
124
|
+
delta_start_index = int(round(start_index - delta_offset))
|
|
125
|
+
delta_end_index = int(round(end_index + delta_offset))
|
|
126
|
+
if delta_end_index > seq_len:
|
|
127
|
+
delta_end_index = seq_len
|
|
128
|
+
try:
|
|
129
|
+
kmer_list.append(lst[delta_start_index:delta_end_index])
|
|
130
|
+
except Exception as e:
|
|
131
|
+
print("test")
|
|
132
|
+
print(e)
|
|
133
|
+
kmer_list.append(lst[delta_start_index:seq_len])
|
|
134
|
+
counter += win
|
|
135
|
+
|
|
136
|
+
# Set the last window to get the remainder
|
|
137
|
+
if counter <= seq_len - 2:
|
|
138
|
+
final_start_index = int(round(counter + 1 - delta_offset))
|
|
139
|
+
kmer_list.append(lst[final_start_index:seq_len])
|
|
140
|
+
|
|
141
|
+
# Test that last value was added on correctly
|
|
142
|
+
|
|
143
|
+
assert kmer_list[-1][-1] == lst[-1]
|
|
144
|
+
return kmer_list
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def populateModimizers(partition, sparsity, ambiguous, expectation, k):
|
|
148
|
+
mod_set = set()
|
|
149
|
+
for kmer in partition:
|
|
150
|
+
if kmer % sparsity == 0:
|
|
151
|
+
mod_set.add(kmer)
|
|
152
|
+
if not ambiguous:
|
|
153
|
+
mod_set = removeAmbiguousBases(mod_set, k)
|
|
154
|
+
if (len(mod_set) < round(expectation / 2)) and (sparsity > 1):
|
|
155
|
+
populateModimizers(partition, sparsity / 2, ambiguous, expectation, k)
|
|
156
|
+
return mod_set
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def convertToModimizers(
|
|
160
|
+
kmer_list: List[List[int]], sparsity: int, ambiguous: bool, k: int, expectation: int
|
|
161
|
+
) -> List[Set[int]]:
|
|
162
|
+
mod_total = []
|
|
163
|
+
for partition in kmer_list:
|
|
164
|
+
mod_set = populateModimizers(partition, sparsity, ambiguous, expectation, k)
|
|
165
|
+
mod_total.append(mod_set)
|
|
166
|
+
return mod_total
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def convertMatrixToBed(
|
|
170
|
+
matrix, window_size, id_threshold, x_name, y_name, self_identity
|
|
171
|
+
):
|
|
172
|
+
bed = [
|
|
173
|
+
(
|
|
174
|
+
"#query_name",
|
|
175
|
+
"query_start",
|
|
176
|
+
"query_end",
|
|
177
|
+
"reference_name",
|
|
178
|
+
"reference_start",
|
|
179
|
+
"reference_end",
|
|
180
|
+
"perID_by_events",
|
|
181
|
+
)
|
|
182
|
+
]
|
|
183
|
+
|
|
184
|
+
rows, cols = matrix.shape
|
|
185
|
+
for x in range(rows):
|
|
186
|
+
for y in range(cols):
|
|
187
|
+
value = matrix[x, y]
|
|
188
|
+
if (not self_identity) or (self_identity and x <= y):
|
|
189
|
+
if value >= id_threshold / 100:
|
|
190
|
+
start_x = x * window_size + 1
|
|
191
|
+
end_x = (x + 1) * window_size
|
|
192
|
+
start_y = y * window_size + 1
|
|
193
|
+
end_y = (y + 1) * window_size
|
|
194
|
+
|
|
195
|
+
bed.append(
|
|
196
|
+
(
|
|
197
|
+
x_name,
|
|
198
|
+
int(start_x),
|
|
199
|
+
int(end_x),
|
|
200
|
+
y_name,
|
|
201
|
+
int(start_y),
|
|
202
|
+
int(end_y),
|
|
203
|
+
float(value),
|
|
204
|
+
)
|
|
205
|
+
)
|
|
206
|
+
return bed
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def divide_into_chunks(lst: List[int], res: int) -> List[List[int]]:
|
|
210
|
+
"""
|
|
211
|
+
Divide a list into approximately equal-sized chunks.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
lst (List[int]): The input list to be divided.
|
|
215
|
+
res (int): The desired number of result chunks.
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
List[List[int]]: A list of lists, where each inner list contains elements from the input list.
|
|
219
|
+
"""
|
|
220
|
+
chunk_size = len(lst) // res # Calculate the target chunk size
|
|
221
|
+
remainder = len(lst) % res # Calculate the remainder
|
|
222
|
+
|
|
223
|
+
chunks = []
|
|
224
|
+
start = 0
|
|
225
|
+
|
|
226
|
+
for i in range(res):
|
|
227
|
+
end = (
|
|
228
|
+
start + chunk_size + (1 if i < remainder else 0)
|
|
229
|
+
) # Adjust chunk size for remainder
|
|
230
|
+
chunks.append(lst[start:end])
|
|
231
|
+
start = end
|
|
232
|
+
|
|
233
|
+
return chunks
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def binomial_distance(containment_value: float, kmer_value: int) -> float:
|
|
237
|
+
"""
|
|
238
|
+
Calculate the binomial distance based on containment and kmer values.
|
|
239
|
+
|
|
240
|
+
Args:
|
|
241
|
+
containment_value (float): The containment value.
|
|
242
|
+
kmer_value (int): The k-mer value.
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
float: The binomial distance.
|
|
246
|
+
"""
|
|
247
|
+
return math.pow(containment_value, 1.0 / kmer_value)
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def containment_neighbors(
|
|
251
|
+
set1: Set[int],
|
|
252
|
+
set2: Set[int],
|
|
253
|
+
set3: Set[int],
|
|
254
|
+
set4: Set[int],
|
|
255
|
+
identity: int,
|
|
256
|
+
k: int,
|
|
257
|
+
) -> float:
|
|
258
|
+
"""
|
|
259
|
+
Calculate the containment neighbors based on four sets and an identity threshold.
|
|
260
|
+
|
|
261
|
+
Args:
|
|
262
|
+
set1 (Set[int]): The first set.
|
|
263
|
+
set2 (Set[int]): The second set.
|
|
264
|
+
set3 (Set[int]): The third set.
|
|
265
|
+
set4 (Set[int]): The fourth set.
|
|
266
|
+
identity (int): The identity threshold.
|
|
267
|
+
k (int): Kmer value.
|
|
268
|
+
|
|
269
|
+
Returns:
|
|
270
|
+
float: The containment neighbors value.
|
|
271
|
+
"""
|
|
272
|
+
len_a = len(set1)
|
|
273
|
+
len_b = len(set2)
|
|
274
|
+
|
|
275
|
+
intersection_a_b_prime = len(set1 & set4)
|
|
276
|
+
if len_a != 0:
|
|
277
|
+
containment_a_b_prime = intersection_a_b_prime / len_a
|
|
278
|
+
else:
|
|
279
|
+
# If len_a is zero, handle it by setting containment_a_b_prime to a default value
|
|
280
|
+
containment_a_b_prime = 0
|
|
281
|
+
|
|
282
|
+
if binomial_distance(containment_a_b_prime, k) < identity / 100:
|
|
283
|
+
return 0.0
|
|
284
|
+
|
|
285
|
+
else:
|
|
286
|
+
intersection_a_prime_b = len(set2 & set3)
|
|
287
|
+
if len_b != 0:
|
|
288
|
+
containment_a_prime_b = intersection_a_prime_b / len_b
|
|
289
|
+
else:
|
|
290
|
+
# If len_a is zero, handle it by setting containment_a_b_prime to a default value
|
|
291
|
+
containment_a_prime_b = 0
|
|
292
|
+
|
|
293
|
+
return max(containment_a_b_prime, containment_a_prime_b)
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def selfContainmentMatrix(
|
|
297
|
+
mod_set: List[set],
|
|
298
|
+
mod_set_neighbors: List[set],
|
|
299
|
+
k: int,
|
|
300
|
+
identity: int,
|
|
301
|
+
ambiguous: bool,
|
|
302
|
+
) -> np.ndarray:
|
|
303
|
+
"""
|
|
304
|
+
Create a self-containment matrix based on containment similarity calculations.
|
|
305
|
+
|
|
306
|
+
Args:
|
|
307
|
+
mod_set (List[set]): A list of sets representing elements.
|
|
308
|
+
mod_set_neighbors (List[set]): A list of sets representing neighbors for each element.
|
|
309
|
+
k (int): A parameter for containment similarity calculation.
|
|
310
|
+
|
|
311
|
+
Returns:
|
|
312
|
+
np.ndarray: A NumPy array representing the self-containment matrix.
|
|
313
|
+
"""
|
|
314
|
+
n = len(mod_set)
|
|
315
|
+
progress_thresholds = round(n / 77)
|
|
316
|
+
|
|
317
|
+
printProgressBar(0, n, prefix="Progress:", suffix="Complete", length=40)
|
|
318
|
+
containment_matrix = np.empty((n, n))
|
|
319
|
+
|
|
320
|
+
for w in range(n):
|
|
321
|
+
if w % progress_thresholds == 0:
|
|
322
|
+
printProgressBar(w, n, prefix="Progress:", suffix="Complete", length=40)
|
|
323
|
+
containment_matrix[w, w] = 100.0
|
|
324
|
+
if len(mod_set[w]) == 0 and not ambiguous:
|
|
325
|
+
containment_matrix[w, w] = 0
|
|
326
|
+
|
|
327
|
+
for r in range(w + 1, n):
|
|
328
|
+
c_hat = binomial_distance(
|
|
329
|
+
containment_neighbors(
|
|
330
|
+
mod_set[w],
|
|
331
|
+
mod_set[r],
|
|
332
|
+
mod_set_neighbors[w],
|
|
333
|
+
mod_set_neighbors[r],
|
|
334
|
+
identity,
|
|
335
|
+
k,
|
|
336
|
+
),
|
|
337
|
+
k,
|
|
338
|
+
)
|
|
339
|
+
containment_matrix[r, w] = c_hat * 100.0
|
|
340
|
+
containment_matrix[w, r] = c_hat * 100.0
|
|
341
|
+
|
|
342
|
+
printProgressBar(
|
|
343
|
+
n, n, prefix="Progress:", suffix="Completed", length=40
|
|
344
|
+
) # show completed progress bar
|
|
345
|
+
print("\n")
|
|
346
|
+
return containment_matrix
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
def pairwiseContainmentMatrix(
|
|
350
|
+
mod_set_x: List[int],
|
|
351
|
+
mod_set_y: List[int],
|
|
352
|
+
mod_set_x_neighbors: List[List[int]],
|
|
353
|
+
mod_set_y_neighbors: List[List[int]],
|
|
354
|
+
identity: int,
|
|
355
|
+
k: int,
|
|
356
|
+
supress_progress: bool,
|
|
357
|
+
) -> np.ndarray:
|
|
358
|
+
"""
|
|
359
|
+
Calculate an updated identity matrix using specified parameters.
|
|
360
|
+
|
|
361
|
+
Args:
|
|
362
|
+
mod_set_x (List[int]): List of values for the x-axis.
|
|
363
|
+
mod_set_y (List[int]): List of values for the y-axis.
|
|
364
|
+
mod_set_x_neighbors (List[List[int]]): List of lists representing neighbors of mod_set_x values.
|
|
365
|
+
mod_set_y_neighbors (List[List[int]]): List of lists representing neighbors of mod_set_y values.
|
|
366
|
+
identity (int): Resolution parameter.
|
|
367
|
+
k (int): Value for the k parameter in the binomial_distance function.
|
|
368
|
+
supress_progress (bool): if true supresses the progress bar
|
|
369
|
+
|
|
370
|
+
Returns:
|
|
371
|
+
np.ndarray: An identity matrix containing containment values.
|
|
372
|
+
"""
|
|
373
|
+
n = max(len(mod_set_y), len(mod_set_x))
|
|
374
|
+
progress_thresholds = round(n / 77)
|
|
375
|
+
|
|
376
|
+
if not supress_progress:
|
|
377
|
+
printProgressBar(0, n, prefix="Progress:", suffix="Complete", length=40)
|
|
378
|
+
containment_matrix = np.zeros((n, n), dtype=float)
|
|
379
|
+
|
|
380
|
+
for w in range(len(mod_set_y)):
|
|
381
|
+
if not supress_progress:
|
|
382
|
+
if w % progress_thresholds == 0:
|
|
383
|
+
printProgressBar(w, n, prefix="Progress:", suffix="Complete", length=40)
|
|
384
|
+
for q in range(n):
|
|
385
|
+
try:
|
|
386
|
+
containment_matrix[w, q] = (
|
|
387
|
+
binomial_distance(
|
|
388
|
+
containment_neighbors(
|
|
389
|
+
mod_set_x[q],
|
|
390
|
+
mod_set_y[w],
|
|
391
|
+
mod_set_x_neighbors[q],
|
|
392
|
+
mod_set_y_neighbors[w],
|
|
393
|
+
identity,
|
|
394
|
+
k,
|
|
395
|
+
),
|
|
396
|
+
k,
|
|
397
|
+
)
|
|
398
|
+
* 100.0
|
|
399
|
+
)
|
|
400
|
+
# Bandaid solution for too sequences that are too small.
|
|
401
|
+
except IndexError as e:
|
|
402
|
+
pass
|
|
403
|
+
|
|
404
|
+
if not supress_progress:
|
|
405
|
+
printProgressBar(
|
|
406
|
+
n, n, prefix="Progress:", suffix="Completed", length=40
|
|
407
|
+
) # show completed progress bar
|
|
408
|
+
print("\n")
|
|
409
|
+
return containment_matrix
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
# Function used to find matching color palette to those available in const.py
|
|
413
|
+
def findElementsWithPrefix(lst, prefix):
|
|
414
|
+
matching_elements = []
|
|
415
|
+
for element in lst:
|
|
416
|
+
if element.startswith(prefix):
|
|
417
|
+
matching_elements.append(element)
|
|
418
|
+
return matching_elements
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
def getInteractiveColor(palette_name, palette_orientation):
|
|
422
|
+
palettes = colorbrewer.COLOR_MAPS
|
|
423
|
+
tmp_color = []
|
|
424
|
+
new_palette = palette_name.split("_")
|
|
425
|
+
if palette_name in DIVERGING_PALETTES:
|
|
426
|
+
tmp_color = palettes["Diverging"][new_palette[0]][new_palette[1]]["Colors"]
|
|
427
|
+
if palette_orientation == "+":
|
|
428
|
+
palette_orientation = "-"
|
|
429
|
+
else:
|
|
430
|
+
palette_orientation = "+"
|
|
431
|
+
elif palette_name in SEQUENTIAL_PALETTES:
|
|
432
|
+
tmp_color = palettes["Sequential"][new_palette[0]][new_palette[1]]["Colors"]
|
|
433
|
+
elif palette_name in QUALITATIVE_PALETTES:
|
|
434
|
+
tmp_color = palettes["Qualitative"][new_palette[0]][new_palette[1]]["Colors"]
|
|
435
|
+
else:
|
|
436
|
+
print("Unable to determine color palette. Selecting default \n")
|
|
437
|
+
tmp_color = palettes["Diverging"]["Spectral"]["11"]["Colors"]
|
|
438
|
+
palette_orientation = "-"
|
|
439
|
+
if palette_orientation == "-":
|
|
440
|
+
tmp_color = tmp_color[::-1]
|
|
441
|
+
tmp_color = [[255, 255, 255]] + tmp_color
|
|
442
|
+
total_values = len(tmp_color)
|
|
443
|
+
formatted_values = [
|
|
444
|
+
[i / (total_values - 1), f"rgb({r}, {g}, {b})"]
|
|
445
|
+
for i, (r, g, b) in enumerate(tmp_color)
|
|
446
|
+
]
|
|
447
|
+
return formatted_values
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
def getMatchingColors(color_name):
|
|
451
|
+
available_colors = [
|
|
452
|
+
element
|
|
453
|
+
for sublist in [DIVERGING_PALETTES, QUALITATIVE_PALETTES, SEQUENTIAL_PALETTES]
|
|
454
|
+
for element in sublist
|
|
455
|
+
]
|
|
456
|
+
matching_elements = findElementsWithPrefix(available_colors, color_name)
|
|
457
|
+
return matching_elements[-1]
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
def containment(set1, set2):
|
|
461
|
+
intersection = set1.intersection(set2)
|
|
462
|
+
try:
|
|
463
|
+
if len(set1) > 0 and len(set2) > 0:
|
|
464
|
+
if len(set1) > len(set2):
|
|
465
|
+
return float(len(intersection) / len(set1))
|
|
466
|
+
else:
|
|
467
|
+
return float(len(intersection) / len(set2))
|
|
468
|
+
else:
|
|
469
|
+
return 0.0
|
|
470
|
+
except ZeroDivisionError:
|
|
471
|
+
return 0.0
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
def verifyModimizers(sparsity, l):
|
|
475
|
+
# Get the next highest power of 2, if not provided
|
|
476
|
+
updated_sparsity = nextPowerOfTwo(sparsity)
|
|
477
|
+
|
|
478
|
+
sparsity_layers = [updated_sparsity]
|
|
479
|
+
while l > 0:
|
|
480
|
+
if sparsity_layers[-1] == 1:
|
|
481
|
+
return sparsity_layers
|
|
482
|
+
elif sparsity_layers[-1] % 2 == 1:
|
|
483
|
+
sparsity_layers[-1] = int(sparsity_layers[-1] + 1)
|
|
484
|
+
sparsity_layers.append(int(sparsity_layers[-1] / 2))
|
|
485
|
+
l -= 1
|
|
486
|
+
|
|
487
|
+
return sparsity_layers
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
def nextPowerOfTwo(n):
|
|
491
|
+
if n <= 0:
|
|
492
|
+
return 1
|
|
493
|
+
n -= 1
|
|
494
|
+
n |= n >> 1
|
|
495
|
+
n |= n >> 2
|
|
496
|
+
n |= n >> 4
|
|
497
|
+
n |= n >> 8
|
|
498
|
+
n |= n >> 16
|
|
499
|
+
return n + 1
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
def generateDictionaryFromList(lst: List[int]) -> Dict[Tuple[int, int], int]:
|
|
503
|
+
result = {}
|
|
504
|
+
for i in range(len(lst) - 1):
|
|
505
|
+
result[(lst[i], lst[i + 1])] = i
|
|
506
|
+
return result
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
def findValueInRange(integer: int, range_dict: dict) -> int:
|
|
510
|
+
if integer > max(key[0] for key in range_dict.keys()):
|
|
511
|
+
return 0
|
|
512
|
+
highest_value = max(range_dict.values()) + 1
|
|
513
|
+
for key, value in range_dict.items():
|
|
514
|
+
if key[0] >= integer >= key[1]:
|
|
515
|
+
return value
|
|
516
|
+
return highest_value
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
def setZoomLevels(axis_length, sparsity_layers):
|
|
520
|
+
zoom_levels = []
|
|
521
|
+
zoom_levels.append(axis_length)
|
|
522
|
+
for i in range(1, len(sparsity_layers)):
|
|
523
|
+
zoom_levels.append(round(axis_length / pow(2, i)))
|
|
524
|
+
return zoom_levels
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
def makeDifferencesEqual(x, x_prime, y, y_prime):
|
|
528
|
+
difference_x = abs(x_prime - x)
|
|
529
|
+
difference_y = abs(y_prime - y)
|
|
530
|
+
|
|
531
|
+
if difference_x != difference_y:
|
|
532
|
+
if difference_x < difference_y:
|
|
533
|
+
x_prime += difference_y - difference_x
|
|
534
|
+
else:
|
|
535
|
+
y_prime += difference_x - difference_y
|
|
536
|
+
|
|
537
|
+
return x_prime, y_prime
|