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,156 @@
|
|
|
1
|
+
from enum import unique
|
|
2
|
+
from typing import Iterable, List, Sequence
|
|
3
|
+
import pysam
|
|
4
|
+
import sys
|
|
5
|
+
import mmh3
|
|
6
|
+
import os
|
|
7
|
+
import pickle
|
|
8
|
+
import re
|
|
9
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
tab_b = bytes.maketrans(b"ACTG", b"TGAC")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def generateKmersFromFasta(seq: Sequence[str], k: int, quiet: bool) -> Iterable[int]:
|
|
15
|
+
n = len(seq)
|
|
16
|
+
if not quiet:
|
|
17
|
+
progress_thresholds = round(n / 77)
|
|
18
|
+
printProgressBar(0, n - k + 1, prefix="Progress:", suffix="Complete", length=40)
|
|
19
|
+
|
|
20
|
+
for i in range(n - k + 1):
|
|
21
|
+
if not quiet:
|
|
22
|
+
if i % progress_thresholds == 0:
|
|
23
|
+
printProgressBar(
|
|
24
|
+
i, n - k + 1, prefix="Progress:", suffix="Complete", length=40
|
|
25
|
+
)
|
|
26
|
+
if i == n - k:
|
|
27
|
+
printProgressBar(
|
|
28
|
+
n - k + 1,
|
|
29
|
+
n - k + 1,
|
|
30
|
+
prefix="Progress:",
|
|
31
|
+
suffix="Completed",
|
|
32
|
+
length=40,
|
|
33
|
+
)
|
|
34
|
+
# Remove case sensitivity
|
|
35
|
+
kmer = seq[i : i + k].upper()
|
|
36
|
+
fh = mmh3.hash(kmer)
|
|
37
|
+
|
|
38
|
+
# Calculate reverse complement hash directly without the need for translation
|
|
39
|
+
rc = mmh3.hash(kmer[::-1].translate(tab_b))
|
|
40
|
+
|
|
41
|
+
yield fh if fh < rc else rc
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def isValidFasta(file_path):
|
|
45
|
+
try:
|
|
46
|
+
with open(file_path, "r") as file:
|
|
47
|
+
in_sequence = False
|
|
48
|
+
for line in file:
|
|
49
|
+
line = line.strip()
|
|
50
|
+
if line.startswith(">"):
|
|
51
|
+
in_sequence = True
|
|
52
|
+
elif in_sequence and not line:
|
|
53
|
+
# Empty line encountered after the sequence header
|
|
54
|
+
in_sequence = False
|
|
55
|
+
elif in_sequence:
|
|
56
|
+
pass
|
|
57
|
+
return in_sequence
|
|
58
|
+
except FileNotFoundError:
|
|
59
|
+
print(f"Unable to find fasta {file_path}. Check filename and/or directory!\n")
|
|
60
|
+
sys.exit(5)
|
|
61
|
+
except Exception as e:
|
|
62
|
+
print(f"An error occurred: {str(e)}")
|
|
63
|
+
sys.exit(6)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def extractFiles(folder_path):
|
|
67
|
+
# Check to see at least one compressed numpy matrix, and one metadata pickle are included
|
|
68
|
+
metadata = []
|
|
69
|
+
matrices = []
|
|
70
|
+
tmp = []
|
|
71
|
+
for filename in os.listdir(folder_path):
|
|
72
|
+
file_path = os.path.join(folder_path, filename) # Full path to the file
|
|
73
|
+
if filename.endswith(".pkl"):
|
|
74
|
+
with open(file_path, "rb") as f:
|
|
75
|
+
metadata = pickle.load(f) # Append loaded data to the metadata list
|
|
76
|
+
|
|
77
|
+
for filename in os.listdir(folder_path):
|
|
78
|
+
file_path = os.path.join(folder_path, filename)
|
|
79
|
+
if filename.endswith(".npz"):
|
|
80
|
+
pattern = rf"_(\d+)\.npz" # Using f-string to include the value of i in the regex pattern
|
|
81
|
+
tmp2 = re.split(pattern, filename, maxsplit=1)
|
|
82
|
+
ff = np.load(file_path, allow_pickle=True)
|
|
83
|
+
tmp.append((tmp2[0], tmp2[1], ff))
|
|
84
|
+
sorted_list = sorted(tmp, key=lambda x: (x[0], x[1]))
|
|
85
|
+
|
|
86
|
+
unique_lists = {}
|
|
87
|
+
|
|
88
|
+
# Iterate over the sorted list
|
|
89
|
+
for item in sorted_list:
|
|
90
|
+
key = item[0] # Get the first element of the tuple
|
|
91
|
+
if key in unique_lists:
|
|
92
|
+
unique_lists[key].append(item) # Append the item to the existing list
|
|
93
|
+
else:
|
|
94
|
+
unique_lists[key] = [item] # Create a new list with the item
|
|
95
|
+
|
|
96
|
+
# Convert dictionary values to lists
|
|
97
|
+
result_lists = list(unique_lists.values())
|
|
98
|
+
sorted_result_lists = [
|
|
99
|
+
lst for title in metadata for lst in result_lists if lst[0][0] == title["title"]
|
|
100
|
+
]
|
|
101
|
+
for unique_list in sorted_result_lists:
|
|
102
|
+
matrices.append([])
|
|
103
|
+
for val in unique_list:
|
|
104
|
+
matrices[-1].append(val[-1]["data"])
|
|
105
|
+
return matrices, metadata
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def printProgressBar(
|
|
109
|
+
iteration,
|
|
110
|
+
total,
|
|
111
|
+
prefix="",
|
|
112
|
+
suffix="",
|
|
113
|
+
decimals=1,
|
|
114
|
+
length=100,
|
|
115
|
+
fill="█",
|
|
116
|
+
printEnd="\r",
|
|
117
|
+
):
|
|
118
|
+
percent = f"{100 * (iteration / total):.{decimals}f}"
|
|
119
|
+
filledLength = int(length * iteration // total)
|
|
120
|
+
bar = [fill] * filledLength + ["-"] * (length - filledLength)
|
|
121
|
+
bar_str = "".join(bar)
|
|
122
|
+
print(f"\r{prefix} |{bar_str}| {percent}% {suffix}", end=printEnd)
|
|
123
|
+
if iteration == total:
|
|
124
|
+
print()
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def readKmersFromFile(filename: str, ksize: int, quiet: bool) -> List[List[int]]:
|
|
128
|
+
"""
|
|
129
|
+
Given a filename and an integer k, returns a list of all k-mers found in the sequences in the file.
|
|
130
|
+
"""
|
|
131
|
+
all_kmers = []
|
|
132
|
+
seq = pysam.FastaFile(filename)
|
|
133
|
+
|
|
134
|
+
for seq_id in seq.references:
|
|
135
|
+
print(f"Retrieving k-mers from {seq_id}.... \n")
|
|
136
|
+
kmers_for_seq = []
|
|
137
|
+
for kmer_hash in generateKmersFromFasta(seq.fetch(seq_id), ksize, quiet):
|
|
138
|
+
kmers_for_seq.append(kmer_hash)
|
|
139
|
+
all_kmers.append(kmers_for_seq)
|
|
140
|
+
print(f"\n{seq_id} k-mers retrieved! \n")
|
|
141
|
+
|
|
142
|
+
return all_kmers
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def getInputHeaders(filename: str) -> List[str]:
|
|
146
|
+
header_list = []
|
|
147
|
+
seq = pysam.FastaFile(filename)
|
|
148
|
+
for seq_id in seq.references:
|
|
149
|
+
header_list.append(seq_id)
|
|
150
|
+
|
|
151
|
+
return header_list
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def getInputSeqLength(filename: str) -> List[int]:
|
|
155
|
+
seq = pysam.FastaFile(filename)
|
|
156
|
+
return seq.lengths
|