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.
@@ -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