Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added DNA features — копия.pptx
Binary file not shown.
136 changes: 95 additions & 41 deletions DNA_feature_server.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@

from flask import Flask, render_template, request, redirect, url_for, flash
from random import randint, choice
from homopol_tract import polytract_finder # поиск однобуквенных повторов
from homopol_tract import polytract_finder, format_homopol # поиск однобуквенных повторов
import gc_graphic as gc
import random_seq as rs
from verification_seq import InputDNA
import tandem_search as ts
import genebank


app = Flask(__name__)
Expand All @@ -11,8 +13,13 @@
'remove_count': -1,
'random_seq':None,
'is_random': 0,
'tandem_test':0,
'redirect_test':None,
'genbank_seq_id': None,
'genebank_name': None,
'genebank_length': None,
'genebank_seq': None,
'genebank_error':None,
'is_genebank': 0,
'tandem_list': None,
'homopol_tract': None,
'homopol_tract_number': 0,
'gc_frame_length': 0,
Expand All @@ -22,18 +29,22 @@
@app.route("/")
def index(): #обрабатываем главную страницу
title = "DNA feature finder"
return render_template('index.html', page_title=title, querry_length = '', remove_count = test_querry['remove_count'], is_random=test_querry['is_random'] )
return render_template('index.html', page_title=title, querry_length = '', remove_count = 0,
is_random=test_querry['is_random'], is_rna = 0,
non_identified = 0, is_genebank = test_querry['is_genebank'],
genebank_error = test_querry['genebank_error'] )


@app.route("/", methods=['POST'])
def input_seq(): #запрос последовательности из окна
try:
dna_query = request.form.get('dna_querry')
test_querry['input_seq'] = dna_query.strip() #здесь будет применена функция форматирования, запись в словарь
dna_query_lengh = len(test_querry['input_seq'])
return render_template('index.html', querry_length = dna_query_lengh, remove_count = test_querry['remove_count'])
dna_query = InputDNA(request.form.get('dna_querry'))
test_querry['input_seq'] = dna_query.formated_sequence #сохраняем в словарь
return render_template('index.html', querry_length = dna_query.input_lenth, remove_count = dna_query.counter,
is_rna = dna_query.is_uracil, non_identified = dna_query.is_non_identified)
except (TypeError, IndexError):
return render_template('index.html', remove_count = test_querry['remove_count'], querry_length = '')
return render_template('index.html', remove_count = dna_query.counter, querry_length = '')


@app.route("/input_report", methods=['POST'])
def input_report(): #обрабатываем кнопку показа введенной последоваьельности после ввода и форматирования
Expand All @@ -43,22 +54,26 @@ def input_report(): #обрабатываем кнопку показа введ
else:
return 'No DNA sequence input' #почему то не работает, хотя когда ничего не вводится там сотит пробел (ord=32)


@app.route("/random_gen", methods=['POST'])
def input_random(): #симуляция рандомной генерации, далее нужно подключать модуль
try:
random_length = int(request.form.get('random_length'))
if random_length > 0:
test_output = ''.join([choice('atgc') for nucleotide in range(random_length)])
test_querry['random_seq'] = test_output #запись в словарь
test_querry['is_random'] = 1 #для вывода сообщения что прошла генерация
return redirect(url_for('index'))
else:
test_querry['is_random'] = 0 #убираем сообщение о генерации когда 0
return redirect(url_for('index'))
#if random_length > 10:
test_output = rs.random_seq(random_length)
print(test_output)
test_querry['random_seq'] = test_output #запись в словарь
test_querry['is_random'] = 1 #для вывода сообщения что прошла генерация
test_querry['genebank_error'] = None
return redirect(url_for('index'))
except rs.LengthError:
test_querry ['is_random'] = -1 #значит неправильное значение
return redirect(url_for('index'))
except (TypeError, IndexError, ValueError):
test_querry['is_random'] = 0 #убираем сообщение о генерации если кликнули с пустым полем
return redirect(url_for('index'))


@app.route("/random_report", methods=['POST'])
def random_report(): #обработки кнопки что за последоватльность сгенерировалася
if test_querry['random_seq'] is not None:
Expand All @@ -67,33 +82,73 @@ def random_report(): #обработки кнопки что за последо
return 'No DNA generated'


@app.route('/genebank_download', methods=['POST'])
def genebank_download(): #запрос для поиска в genbank
try:
genebank_querry = str(request.form.get('genebank_id')).strip()
nucleotide_querry = genebank.Nucleotide(genebank_querry)
test_querry['genebank_length'] = nucleotide_querry.length
test_querry['genbank_seq_id'] = genebank_querry
test_querry['genebank_name'] = nucleotide_querry.dna_name
test_querry['genebank_seq'] = nucleotide_querry.sequence
test_querry['is_genebank'] = 1
try:
nucleotide_querry.type_check()
return redirect(url_for('index'))
except genebank.NonDNAError:
test_querry['genebank_error'] = 'NonDNAError'
return redirect(url_for('index'))
except genebank.NoIDError:
test_querry['is_genebank'] = 0
test_querry['genebank_error'] = 'NoIDError'
return redirect(url_for('index'))
except genebank.DNALengthError:
test_querry['is_genebank'] = 0
test_querry['genebank_error'] = 'DNALenghtError'
return redirect(url_for('index'))
except genebank.NonDNAError:
test_querry['genebank_error'] = 'NonDNAError'
return redirect(url_for('index'))



@app.route("/repeats")
def repeat_page(): #страница работы с повторами
return render_template('repeats.html', tandem_found = test_querry['tandem_test'], tract_number = test_querry['homopol_tract_number'])
return render_template('repeats.html', tandem_found = '', tract_number = test_querry['homopol_tract_number'])


@app.route("/repeats", methods=['POST'])
def input_tandem(): #ввод длины повтора, его обработка и вывод
try:
tandem_length = request.form.get('tandem_length')
test_querry['tandem_test'] = int(tandem_length)*10 #переменная для тестирвоания кнопки
return render_template('repeats.html', tandem_found = test_querry['tandem_test'])
tandem_length = int(request.form.get('tandem_length'))
sequence_fold = ts.fold(test_querry['input_seq'], tandem_length)
test_querry['tandem_list'] = ts.tandem_repeat(sequence_fold)
return render_template('repeats.html', tandem_found = len(test_querry['tandem_list']))
except (TypeError, IndexError, ValueError):
return render_template('repeats.html', tandem_found = '')

'''


@app. route("/tandem_report")
def tandem_report_page(): #заготовка странциы с описание найдленых повторов в упододавимой форме
return redirect(url_for('repeats'))
'''
formated_repeats = []
return render_template('tandem_report.html', repeats = formated_repeats)



@app.route("/tandem_report", methods=['POST'])
def tandem_report(): #обработка кнопки для показа найденых повторов (отчет уже готов когда произведен поиск
if test_querry['tandem_test'] > 0:
test_querry['redirect_test'] = test_querry['tandem_test']*10 #тестовый вывод обработки
return f"{test_querry['redirect_test']}" #пока примитивный вывод
if test_querry['tandem_list'] is not None and test_querry['tandem_list'] != []:
formated_repeats = []
for (count, repeat) in enumerate(test_querry['tandem_list']):
formated_repeats.append(ts.format_seq(repeat, count+1))
#return f"{test_querry['tandem_list']}" #пока примитивный вывод
return render_template('tandem_report.html', repeats=formated_repeats, homopol_tracts = test_querry['homopol_tract'])
else:
return 'No repeats found'

return render_template('tandem_report.html', repeats=['No repeats found'], homopol_tracts = test_querry['homopol_tract'])



@app. route("/poly_tract", methods=['POST'])
def poly_tract_finder(): #кнопка поиска поиск гомопимерных трактов
#пока последовательнотсь будет браться из input как разнести последовательности из дургих источнико я пока не знаю
Expand All @@ -102,24 +157,21 @@ def poly_tract_finder(): #кнопка поиска поиск гомопиме
return redirect(url_for('repeat_page'))


'''
@app. route("/poly_tract_report")
def poly_tract_report_page(): #заготовка странциы с описание найдленых гомополимероных участков в упододавимой форме
return render_template('homopolymer_report.html', page_title=title)
'''

@app. route("/poly_tract_report", methods=['POST'])
def poly_tract_report(): #кнопка показа найденых повторов
if test_querry['homopol_tract'] is not None and test_querry['homopol_tract'] != {}:
#вызопв тип тракта
return f'{test_querry["homopol_tract"]}'
formated_tracts = format_homopol(test_querry['homopol_tract'])
return render_template('tandem_report.html', homopol_tracts = formated_tracts)
else:
return f'No homopolymer tracts'

return render_template('tandem_report.html', homopol_tracts = ['No homopolymer tracts found'])


@app.route('/gc_content')
def gc_content():
return render_template('gc_content.html', total_GC_content = '')


@app.route('/gc_content', methods=['POST'])
def input_frame_gc(): #ввод длины окна поиска
try:
Expand All @@ -131,7 +183,8 @@ def input_frame_gc(): #ввод длины окна поиска
return render_template('gc_content.html', total_GC_content=total_gc)
except (TypeError, IndexError, ValueError):
return render_template('gc_content.html', total_GC_content = '')



@app.route('/gc_content_min', methods=['POST'])
def gc_min_report(): #ввод участков с минимальными GC
if test_querry['gc_content'] is not None:
Expand All @@ -140,6 +193,7 @@ def gc_min_report(): #ввод участков с минимальными GC
else:
return 'Please calculate content before'


@app.route('/gc_content_max', methods=['POST'])
def gc_max_report(): #ввод участков с минимальными GC
if test_querry['gc_content'] is not None:
Expand Down
4 changes: 2 additions & 2 deletions GC_graphic.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ def draw_gc_content(sequence, frame):
ax.plot(current_plot[0], current_plot[1])
ax.yaxis.set_major_locator(ticker.MultipleLocator(10))
ax.yaxis.set_minor_locator(ticker.MultipleLocator(5))
ax.set_xlabel('GC content, %', fontsize = 15)
ax.set_ylabel('DNA positnion, bp', fontsize = 15)
ax.set_xlabel('DNA positnion, bp', fontsize = 15)
ax.set_ylabel('GC content, %', fontsize = 15)
gc_fig_clearance()
fig.savefig(os.path.join(fig_path, 'gc_fig.jpg'), dpi=150)

Expand Down
40 changes: 28 additions & 12 deletions genebank.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,27 @@
примеры ID :NM_018094, NM_001374734.1, NC_052532.1 (1 млн), CM021573.2 (170 млн - может долго грузить)
'''

from Bio import Entrez, SeqIO
from Bio import Entrez, SeqIO


class DNALengthError(ValueError): #сделал ошибки чтобы при их возникновении веб быстрее их обрабатывал
pass
class NonDNAError(TypeError):
pass
class NoIDError(NameError):
pass

class Nucleotide:
def __init__(self,id_seq):
self.id_seq = id_seq
self.dna_description = id_parsing(self.id_seq)
self.dna_description = id_parsing(self.id_seq)['description']
self.dna_name = id_parsing(self.id_seq)['name']
self.length = int(self.dna_description[2])
self.nuc_type = self.dna_description[4]
if self.length <= 100000:
if self.length <=1000000:
self.sequence = genebank_querry(self.id_seq)
else:
raise DNALengthError (f'The lengh of the query:{id_seq} is longer than 100 kb!')
raise DNALengthError (f'The lengh of the query:{self.id_seq} is longer than 100 kb!')

def __repr__(self):
return f'The query contains {self.nuc_type} with length {self.length}'
Expand All @@ -34,20 +38,32 @@ def type_check(self):

Entrez.email = 'somemailsomemail@gmail.cpm' #необходим любой email чтобы больше запросов длеать

def id_parsing(id_seq:str) -> str:
handle = Entrez.efetch(db="nucleotide", id=id_seq, rettype="gb", retmode="text") #хэндрел из другого типа описания, где содержится длин
dna_description = handle.readline().split() #первая строка опсиания гена из базы данных Gene bank где через знаки табуляции тип гена, id, длина, тип полимера, топология, дата обновления
return dna_description
def id_parsing(id_seq:str) -> dict:
try:
result = {'description': None, 'name': None}
handle = Entrez.efetch(db="nucleotide", id=id_seq, rettype="gb", retmode="text") #хэндрел из другого типа описания, где содержится длин
dna_description = handle.readline().split() #первая строка опсиания гена из базы данных Gene bank где через знаки табуляции тип гена, id, длина, тип полимера, топология, дата обновления
gene_name= handle.readline().split()[1:-1]
result['description'] = dna_description
result['name'] = ' '.join(gene_name).strip(',')
return result
except:
raise NoIDError

def genebank_querry(id_seq:str) -> str:
handle = Entrez.efetch(db="nucleotide", id=id_seq, rettype="fasta", retmode='text') #создается хэндлей который уже содержит информацию о последвоательности и с нип проводятся дальнейшие манипуляции
record = SeqIO.read(handle, 'fasta')
return str(record.seq)

try:
handle = Entrez.efetch(db="nucleotide", id=id_seq, rettype="fasta", retmode='text') #создается хэндлей который уже содержит информацию о последвоательности и с нип проводятся дальнейшие манипуляции
record = SeqIO.read(handle, 'fasta')
return str(record.seq)
except:
raise NoIDError


if __name__ == '__main__':
id = input()
dna_query = Nucleotide(id)
print(dna_query.dna_description)
print(dna_query.dna_name)
print(dna_query.length)
print(dna_query.sequence)
print(dna_query.type_check())
7 changes: 7 additions & 0 deletions homopol_tract.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ def polytract_finder(sequence: str) -> dict:
'hpt_type': sequence[-1]}
return tract_dict

def format_homopol(tract_dict):
format_seq = []
for item in tract_dict:
formated_tract = f'Tract #{item}: type: {tract_dict[item]["hpt_type"]}, length {tract_dict[item]["hpt_lenght"]}, start at {tract_dict[item]["hpt_start"]} nt, end at {tract_dict[item]["hpt_end"]} nt'
format_seq.append(formated_tract)
return format_seq

if __name__ == '__main__':
test_1 = 'aaaagct' #длина повтора <5, повтро в начале
test_2 = 'aaaaagct' #длина повтора >=5, повтор в начале
Expand Down
19 changes: 14 additions & 5 deletions random_seq.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import random

dna_symbols = ["a", "t", "g", "c"]
class LengthError(ValueError):
pass

def random_seq(size):
if size >= 100 and size <= 100000: # задаём ограничение длины последовательности
random_seq = "".join([random.choice(dna_symbols) for symbol in range(size)]) # рандомно набираем допустимые символы согласно требуемой длине
random.shuffle(random_seq) # перемешиваем ещё раз
dna_symbols = ["a", "t", "g", "c"]
if size >= 10 and size <= 100000: # задаём ограничение длины последовательности
random_seq_list = [random.choice(dna_symbols) for symbol in range(size)] # рандомно набираем допустимые символы согласно требуемой длине
random.shuffle(random_seq_list) # перемешиваем ещё раз
random_seq = ''.join(random_seq_list)
return random_seq
else:
raise ValueError("Недопустимая длина последовательности")
raise LengthError("Недопустимая длина последовательности")


if __name__ == '__main__':

size = int(input())
print(random_seq(size))
Binary file modified static/images/gc_fig.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading