geney 1.4.21__py2.py3-none-any.whl → 1.4.22__py2.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.
geney/utils/SeqMats.py
CHANGED
|
@@ -89,6 +89,25 @@ class SeqMat:
|
|
|
89
89
|
|
|
90
90
|
self.insertion_counters = defaultdict(int)
|
|
91
91
|
|
|
92
|
+
|
|
93
|
+
def __len__(self) -> int:
|
|
94
|
+
return int(self.seq_array["valid_mask"].sum())
|
|
95
|
+
|
|
96
|
+
def __repr__(self):
|
|
97
|
+
return f"<SeqMat: {self.seq}>"
|
|
98
|
+
|
|
99
|
+
def __str__(self):
|
|
100
|
+
return self.seq
|
|
101
|
+
|
|
102
|
+
def get_metadata(self) -> dict:
|
|
103
|
+
"""Retrieve all metadata as a dictionary."""
|
|
104
|
+
return {
|
|
105
|
+
"name": self.name,
|
|
106
|
+
"source": self.source,
|
|
107
|
+
"version": self.version,
|
|
108
|
+
"notes": self.notes
|
|
109
|
+
}
|
|
110
|
+
|
|
92
111
|
@property
|
|
93
112
|
def seq(self) -> str:
|
|
94
113
|
return self.seq_array['nt'][self.seq_array['valid_mask']].tobytes().decode()
|
|
@@ -101,6 +120,26 @@ class SeqMat:
|
|
|
101
120
|
def conservation(self) -> np.ndarray:
|
|
102
121
|
return self.seq_array['cons'][self.seq_array['valid_mask']]
|
|
103
122
|
|
|
123
|
+
@property
|
|
124
|
+
def max_index(self) -> float:
|
|
125
|
+
return self.seq_array["index"].max()
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
def min_index(self) -> float:
|
|
129
|
+
return self.seq_array["index"].min()
|
|
130
|
+
|
|
131
|
+
@property
|
|
132
|
+
def start(self) -> float:
|
|
133
|
+
return self.min_index
|
|
134
|
+
|
|
135
|
+
@property
|
|
136
|
+
def end(self) -> float:
|
|
137
|
+
return self.max_index
|
|
138
|
+
|
|
139
|
+
@property
|
|
140
|
+
def mutated_positions(self) -> np.ndarray:
|
|
141
|
+
return (self.seq_array["ref"] != self.seq_array["nt"])[self.seq_array["valid_mask"]].astype(int)
|
|
142
|
+
|
|
104
143
|
def clone(self, start: Optional[float] = None, end: Optional[float] = None) -> SeqMat:
|
|
105
144
|
new = SeqMat.__new__(SeqMat)
|
|
106
145
|
new.name = self.name
|
|
@@ -225,3 +264,137 @@ class SeqMat:
|
|
|
225
264
|
mask = (coords >= start) & (coords <= stop)
|
|
226
265
|
return self.seq_array[mask]
|
|
227
266
|
raise TypeError("Invalid index type.")
|
|
267
|
+
|
|
268
|
+
def cut_out(self, introns: List[Tuple[int, int]]) -> "SeqMat":
|
|
269
|
+
"""
|
|
270
|
+
Splices out regions from the sequence corresponding to the given intron boundaries.
|
|
271
|
+
|
|
272
|
+
Handles reverse-complemented sequences by interpreting introns in reverse as well.
|
|
273
|
+
|
|
274
|
+
Args:
|
|
275
|
+
introns (List[Tuple[int, int]]): List of (start, end) intron boundaries.
|
|
276
|
+
These are always genomic (absolute) coordinates,
|
|
277
|
+
regardless of strand direction.
|
|
278
|
+
|
|
279
|
+
Returns:
|
|
280
|
+
SeqMat: A new instance with the intron regions removed.
|
|
281
|
+
"""
|
|
282
|
+
# In reverse orientation, flip intron direction for comparison
|
|
283
|
+
if self.rev:
|
|
284
|
+
introns = [(end, start) if start > end else (start, end) for (start, end) in introns]
|
|
285
|
+
|
|
286
|
+
mask = np.ones(len(self.seq_array), dtype=bool)
|
|
287
|
+
|
|
288
|
+
for start, end in introns:
|
|
289
|
+
lo, hi = min(start, end) + 1, max(start, end) - 1
|
|
290
|
+
mask &= ~((self.seq_array["index"] >= lo) & (self.seq_array["index"] <= hi))
|
|
291
|
+
|
|
292
|
+
new_instance = self.clone()
|
|
293
|
+
new_instance.seq_array = self.seq_array[mask].copy()
|
|
294
|
+
return new_instance
|
|
295
|
+
|
|
296
|
+
def open_reading_frame(self, tis: int) -> "SeqMat":
|
|
297
|
+
"""
|
|
298
|
+
Extracts the open reading frame starting from the translation initiation site (TIS)
|
|
299
|
+
until the first in-frame stop codon.
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
tis (int): Genomic position of the translation initiation site (start codon).
|
|
303
|
+
|
|
304
|
+
Returns:
|
|
305
|
+
SeqMat: A new SeqMat instance containing the ORF (from TIS to stop codon inclusive).
|
|
306
|
+
"""
|
|
307
|
+
if tis not in self.seq_array["index"]:
|
|
308
|
+
print(f"Warning: TIS position {tis} not found, returning default.")
|
|
309
|
+
return self.clone(start=0, end=3)
|
|
310
|
+
|
|
311
|
+
# Extract nucleotide sequence and indices starting from TIS
|
|
312
|
+
mask = self.seq_array["index"] >= tis if not self.rev else self.seq_array["index"] <= tis
|
|
313
|
+
coding_part = self.seq_array[mask]
|
|
314
|
+
coding_seq = coding_part["nt"].tobytes().decode()
|
|
315
|
+
|
|
316
|
+
# Read codons in-frame
|
|
317
|
+
for i in range(0, len(coding_seq) - 2, 3):
|
|
318
|
+
codon = coding_seq[i:i + 3]
|
|
319
|
+
if codon in {"TAA", "TAG", "TGA"}:
|
|
320
|
+
# Determine index range for this ORF
|
|
321
|
+
start = coding_part["index"][0]
|
|
322
|
+
stop = coding_part["index"][i + 2]
|
|
323
|
+
lo, hi = sorted((start, stop))
|
|
324
|
+
return self.clone(start=lo, end=hi)
|
|
325
|
+
|
|
326
|
+
raise ValueError("No in-frame stop codon found after the TIS.")
|
|
327
|
+
|
|
328
|
+
def predict_splicing(self, position: int, engine='spliceai', context=7500, inplace=False): #, reference_donors=None, reference_acceptors=None) -> pd.DataFrame:
|
|
329
|
+
"""
|
|
330
|
+
Predict splicing probabilities at a given position using the specified engine.
|
|
331
|
+
|
|
332
|
+
Args:
|
|
333
|
+
position (int): The genomic position to predict splicing probabilities for.
|
|
334
|
+
engine (str): The prediction engine to use. Supported: 'spliceai', 'pangolin'.
|
|
335
|
+
context (int): The length of the target central region (default: 7500).
|
|
336
|
+
format (str): Output format for the splicing engine results.
|
|
337
|
+
|
|
338
|
+
Returns:
|
|
339
|
+
pd.DataFrame: A DataFrame containing:
|
|
340
|
+
- position: The genomic position
|
|
341
|
+
- donor_prob: Probability of being a donor splice site
|
|
342
|
+
- acceptor_prob: Probability of being an acceptor splice site
|
|
343
|
+
- nucleotides: The nucleotide sequence at that position
|
|
344
|
+
|
|
345
|
+
Raises:
|
|
346
|
+
ValueError: If an unsupported engine is provided.
|
|
347
|
+
IndexError: If the position is not found in the sequence.
|
|
348
|
+
"""
|
|
349
|
+
# Retrieve extended context (includes flanks) around the position.
|
|
350
|
+
# seq, indices = self.get_context(position, context=context, padding='N')
|
|
351
|
+
target = self.clone(position - context, position + context)
|
|
352
|
+
# print(len(target.seq))
|
|
353
|
+
seq, indices = target.seq, target.index
|
|
354
|
+
# print(len(seq))
|
|
355
|
+
# rel_pos = np.where(indices == position)[0][0]
|
|
356
|
+
# print(rel_pos)
|
|
357
|
+
rel_pos = np.abs(indices - position).argmin()
|
|
358
|
+
# print(rel_pos, len(seq))
|
|
359
|
+
left_missing, right_missing = max(0, context - rel_pos), max(0, context - (len(seq) - rel_pos))
|
|
360
|
+
# print(left_missing, right_missing)
|
|
361
|
+
if left_missing > 0 or right_missing > 0:
|
|
362
|
+
step = -1 if self.rev else 1
|
|
363
|
+
|
|
364
|
+
if left_missing > 0:
|
|
365
|
+
left_pad = np.arange(indices[0] - step * left_missing, indices[0], step)
|
|
366
|
+
else:
|
|
367
|
+
left_pad = np.array([], dtype=indices.dtype)
|
|
368
|
+
|
|
369
|
+
if right_missing > 0:
|
|
370
|
+
right_pad = np.arange(indices[-1] + step, indices[-1] + step * (right_missing + 1), step)
|
|
371
|
+
else:
|
|
372
|
+
right_pad = np.array([], dtype=indices.dtype)
|
|
373
|
+
|
|
374
|
+
seq = 'N' * left_missing + seq + 'N' * right_missing
|
|
375
|
+
indices = np.concatenate([left_pad, indices, right_pad])
|
|
376
|
+
|
|
377
|
+
# Run the splicing prediction engine (function assumed to be defined externally)
|
|
378
|
+
from .splicing_utils import run_splicing_engine
|
|
379
|
+
donor_probs, acceptor_probs = run_splicing_engine(seq, engine)
|
|
380
|
+
# Trim off the fixed flanks before returning results.
|
|
381
|
+
seq = seq[5000:-5000]
|
|
382
|
+
indices = indices[5000:-5000]
|
|
383
|
+
df = pd.DataFrame({
|
|
384
|
+
'position': indices,
|
|
385
|
+
'donor_prob': donor_probs,
|
|
386
|
+
'acceptor_prob': acceptor_probs,
|
|
387
|
+
'nucleotides': list(seq)
|
|
388
|
+
}).set_index('position').round(3)
|
|
389
|
+
# if reference_donors is not None:
|
|
390
|
+
# df['ref_donor'] = df.index.isin(reference_donors).astype(int)
|
|
391
|
+
# if reference_acceptors is not None:
|
|
392
|
+
# df['ref_acceptor'] = df.index.isin(reference_acceptors).astype(int)
|
|
393
|
+
|
|
394
|
+
df.attrs['name'] = self.name
|
|
395
|
+
if inplace:
|
|
396
|
+
self.predicted_splicing = df
|
|
397
|
+
return self
|
|
398
|
+
else:
|
|
399
|
+
return df
|
|
400
|
+
|
|
@@ -37,7 +37,7 @@ geney/translation_initiation/tis_utils.py,sha256=AF3siFjuQH-Rs44EV-80zHdbxRMvN4w
|
|
|
37
37
|
geney/translation_initiation/resources/kozak_pssm.json,sha256=pcd0Olziutq-6H3mFWDCD9cujQ_AlZO-iiOvBl82hqE,1165
|
|
38
38
|
geney/translation_initiation/resources/tis_regressor_model.joblib,sha256=IXb4DUDhJ5rBDKcqMk9zE3ECTZZcdj7Jixz3KpoZ7OA,2592025
|
|
39
39
|
geney/utils/Fasta_segment.py,sha256=weB5NJ65P0XiyAJCiCHx4T9sHC1pWLpuQeOy0B85gyg,11364
|
|
40
|
-
geney/utils/SeqMats.py,sha256=
|
|
40
|
+
geney/utils/SeqMats.py,sha256=Hneqxz92WFrHi0lyHs2ZwTd091TtFclgybcvtUCktJA,15689
|
|
41
41
|
geney/utils/SeqMatsOld.py,sha256=syRU5DAuTh3xUfGW_qP9wlcBO5pHsG_y5PlrfXTIxUY,18502
|
|
42
42
|
geney/utils/TranscriptLibrary.py,sha256=ma_ZVPgglxXDDneEvdqxxeqxG8eSFL-zgLUXyC6BqY8,2070
|
|
43
43
|
geney/utils/__init__.py,sha256=-nJ-DMx1JzP-ZCe_QuQCeM0ZYIT_16jxoXDhUaO_4Oc,714
|
|
@@ -46,7 +46,7 @@ geney/utils/pangolin_utils.py,sha256=JQSPbWxdzqGFYfWQktkfLMaMSGR28eGQhNzO7MLMe5M
|
|
|
46
46
|
geney/utils/spliceai_utils.py,sha256=VtrIbjyQxk_3lw86eWjftRYyal9OzxArJ0GV5u_ymTg,2721
|
|
47
47
|
geney/utils/splicing_utils.py,sha256=vPCGnCPR1ooEZEHR79yFHLmRQXEJHXEQjjxpBR-YWOs,20635
|
|
48
48
|
geney/utils/utils.py,sha256=m51Vd0cEbrcIHo6_8BAuI9YSPcKRs22e5LfVd2Qj6Is,2181
|
|
49
|
-
geney-1.4.
|
|
50
|
-
geney-1.4.
|
|
51
|
-
geney-1.4.
|
|
52
|
-
geney-1.4.
|
|
49
|
+
geney-1.4.22.dist-info/METADATA,sha256=OH6exXPW8_IdusLX5g-xeLBXyyQx1DQyfZeguHjvyQY,990
|
|
50
|
+
geney-1.4.22.dist-info/WHEEL,sha256=AHX6tWk3qWuce7vKLrj7lnulVHEdWoltgauo8bgCXgU,109
|
|
51
|
+
geney-1.4.22.dist-info/top_level.txt,sha256=O-FuNUMb5fn9dhZ-dYCgF0aZtfi1EslMstnzhc5IIVo,6
|
|
52
|
+
geney-1.4.22.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|