annotate dante.py @ 0:77d9f2ecb28a draft

Uploaded
author petr-novak
date Wed, 03 Jul 2019 02:45:00 -0400
parents
children a38efa4937d7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
1 #!/usr/bin/env python3
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
2
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
3 import numpy as np
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
4 import subprocess
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
5 import math
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
6 import time
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
7 from operator import itemgetter
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
8 from collections import Counter
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
9 from itertools import groupby
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
10 import os
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
11 import configuration
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
12 from tempfile import NamedTemporaryFile
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
13 import sys
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
14 import warnings
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
15 import shutil
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
16 from collections import defaultdict
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
17
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
18 np.set_printoptions(threshold=sys.maxsize)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
19
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
20
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
21 def alignment_scoring():
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
22 ''' Create hash table for alignment similarity counting: for every
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
23 combination of aminoacids in alignment assign score from protein
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
24 scoring matrix defined in configuration file '''
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
25 score_dict = {}
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
26 with open(configuration.SC_MATRIX) as smatrix:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
27 count = 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
28 for line in smatrix:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
29 if not line.startswith("#"):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
30 if count == 1:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
31 aa_all = line.rstrip().replace(" ", "")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
32 else:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
33 count_aa = 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
34 line = list(filter(None, line.rstrip().split(" ")))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
35 for aa in aa_all:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
36 score_dict["{}{}".format(line[0], aa)] = line[count_aa]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
37 count_aa += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
38 count += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
39 return score_dict
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
40
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
41
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
42 def characterize_fasta(QUERY, WIN_DOM):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
43 ''' Find the sequences, their lengths, starts, ends and if
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
44 they exceed the window '''
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
45 with open(QUERY) as query:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
46 headers = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
47 fasta_lengths = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
48 seq_starts = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
49 seq_ends = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
50 fasta_chunk_len = 0
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
51 count_line = 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
52 for line in query:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
53 line = line.rstrip()
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
54 if line.startswith(">"):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
55 headers.append(line.rstrip())
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
56 fasta_lengths.append(fasta_chunk_len)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
57 fasta_chunk_len = 0
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
58 seq_starts.append(count_line + 1)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
59 seq_ends.append(count_line - 1)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
60 else:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
61 fasta_chunk_len += len(line)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
62 count_line += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
63 seq_ends.append(count_line)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
64 seq_ends = seq_ends[1:]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
65 fasta_lengths.append(fasta_chunk_len)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
66 fasta_lengths = fasta_lengths[1:]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
67 # control if there are correct (unique) names for individual seqs:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
68 # LASTAL takes seqs IDs till the first space which can then create problems with ambiguous records
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
69 if len(headers) > len(set([header.split(" ")[0] for header in headers
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
70 ])):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
71 raise NameError(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
72 '''Sequences in multifasta format are not named correctly:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
73 seq IDs (before the first space) are the same''')
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
74
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
75 above_win = [idx
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
76 for idx, value in enumerate(fasta_lengths) if value > WIN_DOM]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
77 below_win = [idx
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
78 for idx, value in enumerate(fasta_lengths)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
79 if value <= WIN_DOM]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
80 lens_above_win = np.array(fasta_lengths)[above_win]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
81 return headers, above_win, below_win, lens_above_win, seq_starts, seq_ends
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
82
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
83
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
84 def split_fasta(QUERY, WIN_DOM, step, headers, above_win, below_win,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
85 lens_above_win, seq_starts, seq_ends):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
86 ''' Create temporary file containing all sequences - the ones that exceed
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
87 the window are cut with a set overlap (greater than domain size with a reserve) '''
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
88 with open(QUERY, "r") as query:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
89 count_fasta_divided = 0
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
90 count_fasta_not_divided = 0
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
91 ntf = NamedTemporaryFile(delete=False)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
92 divided = np.array(headers)[above_win]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
93 row_length = configuration.FASTA_LINE
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
94 for line in query:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
95 line = line.rstrip()
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
96 if line.startswith(">") and line in divided:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
97 stop_line = seq_ends[above_win[
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
98 count_fasta_divided]] - seq_starts[above_win[
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
99 count_fasta_divided]] + 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
100 count_line = 0
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
101 whole_seq = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
102 for line2 in query:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
103 whole_seq.append(line2.rstrip())
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
104 count_line += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
105 if count_line == stop_line:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
106 break
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
107 whole_seq = "".join(whole_seq)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
108 ## create list of starting positions for individual parts of a seq with a step given by a window and overlap
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
109 windows_starts = list(range(0, lens_above_win[
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
110 count_fasta_divided], step))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
111 ## create list of ending positions (starting pos + window), the last element is the whole seq length
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
112 windows_ends = [
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
113 x + WIN_DOM
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
114 if x + WIN_DOM < lens_above_win[count_fasta_divided] else
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
115 lens_above_win[count_fasta_divided] for x in windows_starts
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
116 ]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
117 count_part = 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
118 for start_part, end_part in zip(windows_starts, windows_ends):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
119 seq_part = whole_seq[start_part:end_part]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
120 if count_part == len(windows_starts):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
121 ntf.write("{}_DANTE_PART{}_LAST:{}-{}\n{}\n".format(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
122 line.split(" ")[0], count_part, start_part + 1,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
123 end_part, "\n".join([seq_part[i:i + row_length]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
124 for i in range(0, len(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
125 seq_part), row_length)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
126 ])).encode("utf-8"))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
127 else:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
128 ntf.write("{}_DANTE_PART{}:{}-{}\n{}\n".format(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
129 line.split(" ")[0], count_part, start_part + 1,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
130 end_part, "\n".join([seq_part[i:i + row_length]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
131 for i in range(0, len(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
132 seq_part), row_length)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
133 ])).encode("utf-8"))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
134 count_part += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
135 count_fasta_divided += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
136 elif line.startswith(">") and line not in divided:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
137 length_seq = seq_ends[below_win[
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
138 count_fasta_not_divided]] - seq_starts[below_win[
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
139 count_fasta_not_divided]] + 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
140 ntf.write("{}\n{}".format(line, "".join([query.readline(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
141 ) for x in range(length_seq)])).encode("utf-8"))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
142 count_fasta_not_divided += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
143 query_temp = ntf.name
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
144 ntf.close()
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
145 return query_temp
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
146
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
147
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
148 def domain_annotation(elements, CLASSIFICATION):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
149 ''' Assign protein domain to each hit from protein database '''
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
150 domains = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
151 annotations = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
152 with open(CLASSIFICATION, "r") as cl_tbl:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
153 annotation = {}
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
154 for line in cl_tbl:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
155 record = line.rstrip().split("\t")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
156 annotation[record[0]] = record[1:]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
157 for i in range(len(elements)):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
158 domains.append(elements[i].split("__")[0].split("-")[1])
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
159 element_name = "__".join(elements[i].split("__")[1:])
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
160 if element_name in annotation.keys():
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
161 annotations.append("|".join([elements[i].split("__")[0].split("-")[
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
162 1], ("|".join(annotation[element_name]))]))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
163 else:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
164 annotations.append("unknown|unknown")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
165 return annotations
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
166
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
167
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
168 def hits_processing(seq_len, start, end, strand):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
169 ''' Gain hits intervals separately for forward and reverse strand '''
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
170 reverse_strand_idx = np.where(strand == "-")[0]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
171 if not reverse_strand_idx.any():
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
172 start_pos_plus = start + 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
173 end_pos_plus = end
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
174 regions_plus = list(zip(start_pos_plus, end_pos_plus))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
175 regions_minus = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
176 else:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
177 reverse_strand_idx = reverse_strand_idx[0]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
178 start_pos_plus = start[0:reverse_strand_idx] + 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
179 end_pos_plus = end[0:reverse_strand_idx]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
180 start_pos_minus = seq_len[0] - end[reverse_strand_idx:] + 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
181 end_pos_minus = seq_len[0] - start[reverse_strand_idx:]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
182 regions_plus = list(zip(start_pos_plus, end_pos_plus))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
183 regions_minus = list(zip(start_pos_minus, end_pos_minus))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
184 return reverse_strand_idx, regions_plus, regions_minus
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
185
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
186
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
187 def overlapping_regions(input_data):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
188 ''' Join all overlapping intervals(hits) to clusters (potential domains),
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
189 get list of start-end positions of individual hits within the interval,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
190 list of minimus and maximums as well as the indices in the original
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
191 sequence_hits structure for the hits belonging to the same clusters '''
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
192 if input_data:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
193 sorted_idx, sorted_data = zip(*sorted(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
194 [(index, data) for index, data in enumerate(input_data)],
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
195 key=itemgetter(1)))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
196 merged_ends = input_data[sorted_idx[0]][1]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
197 intervals = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
198 data = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
199 output_intervals = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
200 output_data = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
201 for i, j in zip(sorted_idx, sorted_data):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
202 if input_data[i][0] < merged_ends:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
203 merged_ends = max(input_data[i][1], merged_ends)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
204 intervals.append(i)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
205 data.append(j)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
206 else:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
207 output_intervals.append(intervals)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
208 output_data.append(data)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
209 intervals = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
210 data = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
211 intervals.append(i)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
212 data.append(j)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
213 merged_ends = input_data[i][1]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
214 output_intervals.append(intervals)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
215 output_data.append(data)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
216 mins = [x[0][0] for x in output_data]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
217 maxs = [max(x, key=itemgetter(1))[1] for x in output_data]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
218 else:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
219 mins = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
220 maxs = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
221 output_intervals = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
222 output_data = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
223 return mins, maxs, output_data, output_intervals
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
224
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
225
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
226 def annotations_dict(annotations):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
227 ''' Hash table where annotations of the hits within a clusters are the keys.
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
228 Each annotation has serial number assigned which indexes the row in the score_table '''
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
229 classes_dict = {classes: idx
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
230 for idx, classes in enumerate(set(annotations))}
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
231 return classes_dict
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
232
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
233
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
234 def score_table(mins, maxs, data, annotations, scores, CLASSIFICATION):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
235 ''' Score table is created based on the annotations occurance in the cluster.
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
236 Matrix axis y corresponds to individual annotations (indexed according to classes_dict),
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
237 axis x represents positions of analyzed seq in a given cluster.
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
238 For every hit within cluster, array of scores on the corresponding position
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
239 is recorded to the table in case if the score on certain position is so far the highest
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
240 for the certain position and certain annotation '''
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
241 classes_dict = annotations_dict(annotations)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
242 score_matrix = np.zeros((len(classes_dict), maxs - mins + 1), dtype=int)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
243 count = 0
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
244 for item in annotations:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
245 saved_scores = score_matrix[classes_dict[item], data[count][0] - mins:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
246 data[count][1] - mins + 1]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
247 new_scores = [scores[count]] * len(saved_scores)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
248 score_matrix[classes_dict[item], data[count][0] - mins:data[count][
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
249 1] - mins + 1] = [max(*pos_score)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
250 for pos_score in zip(saved_scores, new_scores)]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
251 count += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
252 return score_matrix, classes_dict
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
253
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
254
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
255 def score_matrix_evaluation(score_matrix, classes_dict, THRESHOLD_SCORE):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
256 ''' Score matrix is evaluated based on each position.
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
257 For every position the list of annotations with a score which reaches
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
258 certain percentage of the overal best score of the cluster are stored '''
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
259 ann_per_reg = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
260 overal_best_score_reg = max((score_matrix.max(axis=1)))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
261 for position in score_matrix.T:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
262 ## score threshold calculated as a percentage of the OVERALL best score in the cluster
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
263 threshold = overal_best_score_reg * THRESHOLD_SCORE / 100
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
264 above_th = [idx
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
265 for idx, score in enumerate(position)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
266 if position[idx] >= threshold]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
267 ## select unique annotations in one position that are above threshold
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
268 ann_per_pos = list(set(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
269 [key for key, value in classes_dict.items() if value in above_th]))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
270 ann_per_reg.append(ann_per_pos)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
271 return ann_per_reg
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
272
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
273
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
274 def group_annot_regs(ann_per_reg):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
275 ''' Get list of domains, annotations, longest common annotations and
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
276 counts of positions with certain annotation per regions '''
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
277 ## tranform list of lists (potential multiple annotations for every position ) to flat list of all annotations
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
278 all_annotations = [item for sublist in ann_per_reg for item in sublist]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
279 unique_annotations = list(set(all_annotations))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
280 ann_pos_counts = [all_annotations.count(x) for x in unique_annotations]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
281 unique_annotations = list(set(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
282 [item for sublist in ann_per_reg for item in sublist]))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
283 domain_type = list(set([annotation.split("|")[0]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
284 for annotation in unique_annotations]))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
285 classification_list = [annotation.split("|")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
286 for annotation in unique_annotations]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
287 ann_substring = "|".join(os.path.commonprefix(classification_list))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
288 domain_type = "/".join(domain_type)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
289 return domain_type, ann_substring, unique_annotations, ann_pos_counts
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
290
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
291
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
292 def best_score(scores, region):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
293 ''' From overlapping intervals take the one with the highest score '''
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
294 ## if more hits have the same best score take only the first one
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
295 best_idx = region[np.where(scores == max(scores))[0][0]]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
296 best_idx_reg = np.where(scores == max(scores))[0][0]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
297 return best_idx, best_idx_reg
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
298
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
299
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
300 def create_gff3(domain_type, ann_substring, unique_annotations, ann_pos_counts,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
301 dom_start, dom_end, step, best_idx, annotation_best,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
302 db_name_best, db_starts_best, db_ends_best, strand, score,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
303 seq_id, db_seq, query_seq, domain_size, positions, gff):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
304 ''' Record obtained information about domain corresponding to individual cluster to common gff file '''
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
305 best_start = positions[best_idx][0]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
306 best_end = positions[best_idx][1]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
307 best_score = score[best_idx]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
308 ## proportion of length of the best hit to the whole region length found by base
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
309 length_proportion = int((best_end - best_start + 1) /
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
310 (dom_end - dom_start + 1) * 100)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
311 db_seq_best = db_seq[best_idx]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
312 query_seq_best = query_seq[best_idx]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
313 domain_size_best = domain_size[best_idx]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
314 [percent_ident, align_similarity, relat_align_len, relat_interrupt,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
315 db_len_proportion
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
316 ] = filter_params(db_seq_best, query_seq_best, domain_size_best)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
317 ann_substring = "|".join(ann_substring.split("|")[1:])
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
318 annotation_best = "|".join([db_name_best] + annotation_best.split("|")[1:])
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
319 if "DANTE_PART" in seq_id:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
320 part = int(seq_id.split("DANTE_PART")[1].split(":")[0].split("_")[0])
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
321 dom_start = dom_start + (part - 1) * step
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
322 dom_end = dom_end + (part - 1) * step
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
323 best_start = best_start + (part - 1) * step
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
324 best_end = best_end + (part - 1) * step
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
325 if ann_substring is '':
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
326 ann_substring = "NONE(Annotations from different classes)"
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
327 if len(unique_annotations) > 1:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
328 unique_annotations = ",".join(["{}[{}bp]".format(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
329 ann, pos) for ann, pos in zip(unique_annotations, ann_pos_counts)])
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
330 else:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
331 unique_annotations = unique_annotations[0]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
332 if __name__ == '__main__':
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
333 SOURCE = configuration.SOURCE_DANTE
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
334 else:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
335 SOURCE = configuration.SOURCE_PROFREP
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
336 if "/" in domain_type:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
337 gff.write(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
338 "{}\t{}\t{}\t{}\t{}\t.\t{}\t{}\tName={};Final_Classification=Ambiguous_domain;Region_Hits_Classifications_={}\n".format(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
339 seq_id, SOURCE, configuration.DOMAINS_FEATURE, dom_start,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
340 dom_end, strand, configuration.PHASE, domain_type,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
341 unique_annotations))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
342 else:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
343 gff.write(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
344 "{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\tName={};Final_Classification={};Region_Hits_Classifications={};Best_Hit={}:{}-{}[{}percent];Best_Hit_DB_Pos={}:{}of{};DB_Seq={};Query_Seq={};Identity={};Similarity={};Relat_Length={};Relat_Interruptions={};Hit_to_DB_Length={}\n".format(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
345 seq_id, SOURCE, configuration.DOMAINS_FEATURE, dom_start,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
346 dom_end, best_score, strand, configuration.PHASE, domain_type,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
347 ann_substring, unique_annotations, annotation_best, best_start,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
348 best_end, length_proportion, db_starts_best, db_ends_best,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
349 domain_size_best, db_seq_best, query_seq_best, percent_ident,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
350 align_similarity, relat_align_len, relat_interrupt,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
351 db_len_proportion))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
352
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
353
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
354 def filter_params(db, query, protein_len):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
355 ''' Calculate basic statistics of the quality of the alignment '''
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
356 score_dict = alignment_scoring()
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
357 num_ident = 0
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
358 count_interrupt = 0
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
359 count_similarity = 0
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
360 alignment_len = 0
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
361 for i, j in zip(db.upper(), query.upper()):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
362 if i == j and i != "X":
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
363 num_ident += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
364 if j == "/" or j == "\\" or j == "*":
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
365 count_interrupt += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
366 if (i.isalpha() or i == "*") and (j.isalpha() or j == "*"):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
367 if int(score_dict["{}{}".format(i, j)]) > 0:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
368 count_similarity += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
369 ## gapless alignment length proportional to the domain protein length
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
370 relat_align_len = round((len(db) - db.count("-")) / protein_len, 3)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
371 ## proportional identical bases (except of X) to al.length
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
372 align_identity = round(num_ident / len(db), 2)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
373 ## proportional count of positive scores from scoring matrix to al. length
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
374 align_similarity = round(count_similarity / len(db), 2)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
375 ## number of interruptions per 100 bp
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
376 relat_interrupt = round(count_interrupt / math.ceil((len(query) / 100)), 2)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
377 ## Proportion of alignment to the original length of protein domain from database (indels included)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
378 db_len_proportion = round(len(db) / protein_len, 2)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
379 return align_identity, align_similarity, relat_align_len, relat_interrupt, db_len_proportion
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
380
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
381
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
382 def line_generator(tab_pipe, maf_pipe, start):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
383 ''' Yield individual lines of LASTAL stdout for single sequence '''
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
384 if hasattr(line_generator, "dom"):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
385 seq_id = line_generator.dom.split("\t")[6]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
386 yield line_generator.dom.encode("utf-8")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
387 del line_generator.dom
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
388 line_tab = ""
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
389 for line_tab in tab_pipe:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
390 line_tab = line_tab.decode("utf-8")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
391 if not line_tab.startswith('#'):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
392 if start:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
393 if not ('seq_id' in locals() and
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
394 seq_id != line_tab.split("\t")[6]):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
395 seq_id = line_tab.split("\t")[6]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
396 start = False
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
397 line_maf = [maf_pipe.readline() for line_count in range(4)]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
398 db_seq = line_maf[1].decode("utf-8").rstrip().split(" ")[-1]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
399 alignment_seq = line_maf[2].decode("utf-8").rstrip().split(" ")[-1]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
400 line = "{}\t{}\t{}".format(line_tab, db_seq, alignment_seq)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
401 line_id = line.split("\t")[6]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
402 if seq_id != line_id:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
403 line_generator.dom = line
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
404 return
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
405 else:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
406 yield line.encode("utf-8")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
407 else:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
408 maf_pipe.readline()
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
409 if line_tab == "":
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
410 raise RuntimeError
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
411 else:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
412 return
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
413
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
414
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
415 def get_version(path, LAST_DB):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
416 branch = subprocess.check_output("git rev-parse --abbrev-ref HEAD",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
417 shell=True,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
418 cwd=path).decode('ascii').strip()
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
419 shorthash = subprocess.check_output("git log --pretty=format:'%h' -n 1 ",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
420 shell=True,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
421 cwd=path).decode('ascii').strip()
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
422 revcount = len(subprocess.check_output("git log --oneline",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
423 shell=True,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
424 cwd=path).decode('ascii').split())
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
425 version_string = (
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
426 "##-----------------------------------------------\n"
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
427 "##PIPELINE VERSION : "
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
428 "{branch}-rv-{revcount}({shorthash})\n"
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
429 "##PROTEIN DATABASE VERSION : {PD}\n"
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
430 "##-----------------------------------------------\n").format(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
431 branch=branch,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
432 shorthash=shorthash,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
433 revcount=revcount,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
434 PD=os.path.basename(LAST_DB))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
435 return version_string
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
436
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
437
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
438 def write_info(dom_gff_tmp, version_string):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
439 dom_gff_tmp.write("{}\n".format(configuration.HEADER_GFF))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
440 dom_gff_tmp.write(version_string)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
441
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
442
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
443 def domain_search(QUERY, LAST_DB, CLASSIFICATION, OUTPUT_DOMAIN,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
444 THRESHOLD_SCORE, WIN_DOM, OVERLAP_DOM):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
445 ''' Search for protein domains using our protein database and external tool LAST,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
446 stdout is parsed in real time and hits for a single sequence undergo further processing
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
447 - tabular format(TAB) to get info about position, score, orientation
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
448 - MAF format to gain alignment and original sequence
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
449 '''
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
450
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
451 step = WIN_DOM - OVERLAP_DOM
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
452 [headers, above_win, below_win, lens_above_win, seq_starts, seq_ends
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
453 ] = characterize_fasta(QUERY, WIN_DOM)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
454 query_temp = split_fasta(QUERY, WIN_DOM, step, headers, above_win,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
455 below_win, lens_above_win, seq_starts, seq_ends)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
456
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
457 ## TAB output contains all the alignment scores, positions, strands...
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
458 tab = subprocess.Popen(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
459 "lastal -F15 {} {} -L 10 -m 70 -p BL80 -f TAB".format(LAST_DB,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
460 query_temp),
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
461 stdout=subprocess.PIPE,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
462 shell=True)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
463 ## MAF output contains alignment sequences
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
464 maf = subprocess.Popen(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
465 "lastal -F15 {} {} -L 10 -m 70 -p BL80 -f MAF".format(LAST_DB,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
466 query_temp),
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
467 stdout=subprocess.PIPE,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
468 shell=True)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
469
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
470 tab_pipe = tab.stdout
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
471 maf_pipe = maf.stdout
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
472 maf_pipe.readline()
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
473
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
474 seq_ids = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
475 dom_tmp = NamedTemporaryFile(delete=False)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
476 with open(dom_tmp.name, "w") as dom_gff_tmp:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
477 path = os.path.dirname(os.path.realpath(__file__))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
478 version_string = get_version(path, LAST_DB)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
479 write_info(dom_gff_tmp, version_string)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
480 gff = open(dom_tmp.name, "a")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
481 start = True
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
482 while True:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
483 try:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
484 with warnings.catch_warnings():
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
485 warnings.simplefilter("ignore")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
486 sequence_hits = np.genfromtxt(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
487 line_generator(tab_pipe, maf_pipe, start),
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
488 names=
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
489 "score, name_db, start_db, al_size_db, strand_db, seq_size_db, name_q, start_q, al_size_q, strand_q, seq_size_q, block1, block2, block3, db_seq, q_seq",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
490 usecols=
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
491 "score, name_q, start_q, al_size_q, strand_q, seq_size_q, name_db, db_seq, q_seq, seq_size_db, start_db, al_size_db",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
492 dtype=None,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
493 comments=None)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
494 except RuntimeError:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
495 break
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
496 ## if there are no domains found
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
497 if sequence_hits.size is 0:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
498 gff.write("##NO DOMAINS")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
499 return [], [], [], []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
500
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
501 ############# PARSING LASTAL OUTPUT ############################
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
502 sequence_hits = np.atleast_1d(sequence_hits)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
503 score = sequence_hits['score'].astype("int")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
504 seq_id = sequence_hits['name_q'][0].astype("str")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
505 start_hit = sequence_hits['start_q'].astype("int")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
506 end_hit = start_hit + sequence_hits['al_size_q'].astype("int")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
507 strand = sequence_hits['strand_q'].astype("str")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
508 seq_len = sequence_hits['seq_size_q'].astype("int")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
509 domain_db = sequence_hits['name_db'].astype("str")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
510 db_seq = sequence_hits['db_seq'].astype("str")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
511 query_seq = sequence_hits['q_seq'].astype("str")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
512 domain_size = sequence_hits['seq_size_db'].astype("int")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
513 db_start = sequence_hits['start_db'].astype("int") + 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
514 db_end = sequence_hits['start_db'].astype("int") + sequence_hits[
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
515 'al_size_db'].astype("int")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
516
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
517 [reverse_strand_idx, positions_plus, positions_minus
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
518 ] = hits_processing(seq_len, start_hit, end_hit, strand)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
519 strand_gff = "+"
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
520 [mins_plus, maxs_plus, data_plus, indices_plus
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
521 ] = overlapping_regions(positions_plus)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
522 [mins_minus, maxs_minus, data_minus, indices_minus
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
523 ] = overlapping_regions(positions_minus)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
524 positions = positions_plus + positions_minus
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
525 indices_overal = indices_plus + [x + reverse_strand_idx
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
526 for x in indices_minus]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
527 mins = mins_plus + mins_minus
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
528 maxs = maxs_plus + maxs_minus
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
529 data = data_plus + data_minus
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
530 ## process every region (cluster) of overlapping hits sequentially
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
531 count_region = 0
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
532 for region in indices_overal:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
533 db_names = domain_db[np.array(region)]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
534 db_starts = db_start[np.array(region)]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
535 db_ends = db_end[np.array(region)]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
536 scores = score[np.array(region)]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
537 annotations = domain_annotation(db_names, CLASSIFICATION)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
538 [score_matrix, classes_dict] = score_table(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
539 mins[count_region], maxs[count_region], data[count_region],
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
540 annotations, scores, CLASSIFICATION)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
541 ann_per_reg = score_matrix_evaluation(score_matrix, classes_dict,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
542 THRESHOLD_SCORE)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
543 [domain_type, ann_substring, unique_annotations, ann_pos_counts
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
544 ] = group_annot_regs(ann_per_reg)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
545 [best_idx, best_idx_reg] = best_score(scores, region)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
546 annotation_best = annotations[best_idx_reg]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
547 db_name_best = db_names[best_idx_reg]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
548 db_starts_best = db_starts[best_idx_reg]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
549 db_ends_best = db_ends[best_idx_reg]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
550 if count_region == len(indices_plus):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
551 strand_gff = "-"
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
552 create_gff3(domain_type, ann_substring, unique_annotations,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
553 ann_pos_counts, mins[count_region], maxs[count_region],
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
554 step, best_idx, annotation_best, db_name_best,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
555 db_starts_best, db_ends_best, strand_gff, score,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
556 seq_id, db_seq, query_seq, domain_size, positions, gff)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
557 count_region += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
558 seq_ids.append(seq_id)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
559 os.unlink(query_temp)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
560 gff.close()
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
561 dom_tmp.close()
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
562 ## if any sequence from input data was split into windows, merge and adjust the data from individual windows
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
563 if any("DANTE_PART" in x for x in seq_ids):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
564 adjust_gff(OUTPUT_DOMAIN, dom_tmp.name, WIN_DOM, OVERLAP_DOM, step)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
565 ## otherwise use the temporary output as the final domains gff
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
566 else:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
567 shutil.copy2(dom_tmp.name, OUTPUT_DOMAIN)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
568 os.unlink(dom_tmp.name)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
569
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
570
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
571 def adjust_gff(OUTPUT_DOMAIN, gff, WIN_DOM, OVERLAP_DOM, step):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
572 ''' Original gff file is adjusted in case of containing cut parts
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
573 - for consecutive sequences overlap is divided to half with first half
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
574 of records(domains) belonging to the first sequence and second to the following one.
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
575 Duplicate domains going through the middle of the overlap are removed.
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
576 First and the last part (marked as LAST) of a certain sequence are
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
577 handled separately as the are overlapped from one side only '''
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
578
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
579 seq_id_all = []
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
580 class_dict = defaultdict(int)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
581 seen = set()
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
582 with open(OUTPUT_DOMAIN, "w") as adjusted_gff:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
583 with open(gff, "r") as primary_gff:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
584 start = True
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
585 for line in primary_gff:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
586 if line.startswith("#"):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
587 adjusted_gff.write(line)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
588 else:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
589 split_line = line.split("\t")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
590 classification = split_line[-1].split(";")[1].split("=")[1]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
591 if start:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
592 seq_id_all.append(split_line[0].split("_DANTE_PART")[
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
593 0])
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
594 start = False
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
595 seq_id = split_line[0].split("_DANTE_PART")[0]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
596 if "DANTE_PART" in line:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
597 line_without_id = "\t".join(split_line[1:])
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
598 part = int(split_line[0].split("_DANTE_PART")[1].split(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
599 ":")[0].split("_")[0])
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
600 if seq_id != seq_id_all[-1]:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
601 seq_id_all.append(seq_id)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
602
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
603 ## first part of the sequence
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
604 if part == 1:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
605 cut_end = WIN_DOM - OVERLAP_DOM / 2
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
606 if int(split_line[3]) <= cut_end <= int(split_line[
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
607 4]):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
608 if line_without_id not in seen:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
609 adjusted_gff.write("{}\t{}".format(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
610 seq_id, line_without_id))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
611 class_dict[classification] += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
612 seen.add(line_without_id)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
613 elif int(split_line[4]) < cut_end:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
614 adjusted_gff.write("{}\t{}".format(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
615 seq_id, line_without_id))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
616 class_dict[classification] += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
617
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
618 ## last part of the sequence
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
619 elif "LAST" in split_line[0]:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
620 cut_start = OVERLAP_DOM / 2 + (part - 1) * step
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
621 if int(split_line[3]) <= cut_start <= int(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
622 split_line[4]):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
623 if line_without_id not in seen:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
624 adjusted_gff.write("{}\t{}".format(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
625 seq_id, line_without_id))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
626 class_dict[classification] += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
627 seen.add(line_without_id)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
628 elif int(split_line[3]) > cut_start:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
629 adjusted_gff.write("{}\t{}".format(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
630 seq_id, line_without_id))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
631 class_dict[classification] += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
632
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
633 ## middle part of the sequence
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
634 else:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
635 cut_start = OVERLAP_DOM / 2 + (part - 1) * step
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
636 cut_end = WIN_DOM - OVERLAP_DOM / 2 + (part -
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
637 1) * step
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
638 if int(split_line[3]) <= cut_start <= int(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
639 split_line[4]) or int(split_line[
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
640 3]) <= cut_end <= int(split_line[4]):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
641 if line_without_id not in seen:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
642 adjusted_gff.write("{}\t{}".format(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
643 seq_id, line_without_id))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
644 class_dict[classification] += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
645 seen.add(line_without_id)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
646 elif int(split_line[3]) > cut_start and int(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
647 split_line[4]) < cut_end:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
648 adjusted_gff.write("{}\t{}".format(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
649 seq_id, line_without_id))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
650 class_dict[classification] += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
651 ## not divived
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
652 else:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
653 if seq_id != seq_id_all[-1]:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
654 seq_id_all.append(seq_id)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
655 adjusted_gff.write(line)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
656 class_dict[classification] += 1
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
657
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
658
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
659 def main(args):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
660
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
661 t = time.time()
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
662
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
663 QUERY = args.query
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
664 LAST_DB = args.protein_database
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
665 CLASSIFICATION = args.classification
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
666 OUTPUT_DOMAIN = args.domain_gff
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
667 NEW_LDB = args.new_ldb
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
668 OUTPUT_DIR = args.output_dir
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
669 THRESHOLD_SCORE = args.threshold_score
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
670 WIN_DOM = args.win_dom
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
671 OVERLAP_DOM = args.overlap_dom
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
672
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
673 if OUTPUT_DOMAIN is None:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
674 OUTPUT_DOMAIN = configuration.DOMAINS_GFF
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
675 if os.path.isdir(LAST_DB):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
676 LAST_DB = os.path.join(LAST_DB, configuration.LAST_DB_FILE)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
677 if os.path.isdir(CLASSIFICATION):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
678 CLASSIFICATION = os.path.join(CLASSIFICATION, configuration.CLASS_FILE)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
679
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
680 if NEW_LDB:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
681 subprocess.call("lastdb -p -cR01 {} {}".format(LAST_DB, LAST_DB),
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
682 shell=True)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
683
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
684 if OUTPUT_DIR and not os.path.exists(OUTPUT_DIR):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
685 os.makedirs(OUTPUT_DIR)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
686
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
687 if not os.path.isabs(OUTPUT_DOMAIN):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
688 if OUTPUT_DIR is None:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
689 OUTPUT_DIR = configuration.TMP
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
690 if not os.path.exists(OUTPUT_DIR):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
691 os.makedirs(OUTPUT_DIR)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
692 OUTPUT_DOMAIN = os.path.join(OUTPUT_DIR,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
693 os.path.basename(OUTPUT_DOMAIN))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
694 domain_search(QUERY, LAST_DB, CLASSIFICATION, OUTPUT_DOMAIN,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
695 THRESHOLD_SCORE, WIN_DOM, OVERLAP_DOM)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
696
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
697 print("ELAPSED_TIME_DOMAINS = {} s".format(time.time() - t))
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
698
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
699
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
700 if __name__ == "__main__":
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
701 import argparse
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
702 from argparse import RawDescriptionHelpFormatter
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
703
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
704 class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
705 argparse.RawDescriptionHelpFormatter):
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
706 pass
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
707
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
708 parser = argparse.ArgumentParser(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
709 description=
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
710 '''Script performs similarity search on given DNA sequence(s) in (multi)fasta against our protein domains database of all Transposable element for certain group of organisms (Viridiplantae or Metazoans). Domains are subsequently annotated and classified - in case certain domain has multiple annotations assigned, classifation is derived from the common classification level of all of them. Domains search is accomplished engaging LASTAL alignment tool.
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
711
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
712 DEPENDENCIES:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
713 - python 3.4 or higher with packages:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
714 -numpy
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
715 - lastal 744 or higher [http://last.cbrc.jp/]
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
716 - configuration.py module
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
717
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
718 EXAMPLE OF USAGE:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
719
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
720 ./protein_domains_pd.py -q PATH_TO_INPUT_SEQ -pdb PATH_TO_PROTEIN_DB -cs PATH_TO_CLASSIFICATION_FILE
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
721
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
722 When running for the first time with a new database use -nld option allowing lastal to create indexed database files:
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
723
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
724 -nld True
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
725
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
726 ''',
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
727 epilog="""""",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
728 formatter_class=CustomFormatter)
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
729
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
730 requiredNamed = parser.add_argument_group('required named arguments')
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
731 requiredNamed.add_argument(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
732 "-q",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
733 "--query",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
734 type=str,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
735 required=True,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
736 help=
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
737 'input DNA sequence to search for protein domains in a fasta format. Multifasta format allowed.')
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
738 requiredNamed.add_argument('-pdb',
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
739 "--protein_database",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
740 type=str,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
741 required=True,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
742 help='protein domains database file')
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
743 requiredNamed.add_argument('-cs',
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
744 '--classification',
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
745 type=str,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
746 required=True,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
747 help='protein domains classification file')
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
748 parser.add_argument("-oug",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
749 "--domain_gff",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
750 type=str,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
751 help="output domains gff format")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
752 parser.add_argument(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
753 "-nld",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
754 "--new_ldb",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
755 type=str,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
756 default=False,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
757 help=
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
758 "create indexed database files for lastal in case of working with new protein db")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
759 parser.add_argument(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
760 "-dir",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
761 "--output_dir",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
762 type=str,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
763 help="specify if you want to change the output directory")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
764 parser.add_argument(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
765 "-thsc",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
766 "--threshold_score",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
767 type=int,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
768 default=80,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
769 help=
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
770 "percentage of the best score in the cluster to be tolerated when assigning annotations per base")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
771 parser.add_argument(
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
772 "-wd",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
773 "--win_dom",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
774 type=int,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
775 default=10000000,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
776 help="window to process large input sequences sequentially")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
777 parser.add_argument("-od",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
778 "--overlap_dom",
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
779 type=int,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
780 default=10000,
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
781 help="overlap of sequences in two consecutive windows")
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
782
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
783 args = parser.parse_args()
77d9f2ecb28a Uploaded
petr-novak
parents:
diff changeset
784 main(args)