-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchapter16.txt
239 lines (193 loc) · 10.2 KB
/
chapter16.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
{:: encoding="UTF-8" /}
#Aplicación web para filtrar contaminación de vectores
## DESCRIPCIÓN DEL PROBLEMA
Comúnmente las secuencias de ADN se insertan en un vector de clonado para su manipulación. Al secuenciar estas construcciones frecuentemente se producen secuencias que incluyen segmentos derivados del vector. Si la parte del vector de la secuencia en crudo no se elimina la secuencia curada estará contaminada, arruinando el análisis posterior. Existen múltiples fuentes de contaminación de ADN como: transposones, secuencias de inserción, organismos que infectan nuestras muestras y otros organismos utilizados en el mismo laboratorio (por ejemplo, contaminación cruzada producto de equipos sucios).
La contaminación de la secuencia no es un problema menor pudiendo ocasionar otros:[^nota16-1]
* Tiempo y esfuerzo desperdiciado en análisis sin sentido.
* Ensamblado erróneo de contigs y agrupamiento falso de secuencias.
* Conclusiones erróneas extraídas sobre el significado biológico de la secuencia.
* Contaminación de bases de datos públicas.
* Retraso en el lanzamiento de la secuencia en una base de datos pública.
[^nota16-1]: Para obtener información sobre cada artículo, consulte el programa NCBI VecScreen en <http://www.ncbi.nlm.nih.gov/VecScreen/contam.html>.
Para identificar la parte del vector en una secuencia se puede hacer un BLAST contra una base de datos de secuencias de vectores (o contra cualquier otra base de datos que se crea que pueda contaminar tu secuencia). Para ayudar a eliminar esas secuencias, este programa toma una secuencia o un grupo de secuencias en formato FASTA y hace el BLAST contra una base de datos seleccionada por el usuario. Identifica la coincidencia (match) y la contaminación se enmascara utilizando el carácter “N” en la secuencia suministrada por el usuario.
Este programa funciona como una aplicación web, por lo tanto hay un formulario en HTML para que el usuario ingrese los datos y un archivo Python para procesarlos. Este programa usa BLAST+, por lo que hay que tener instalado el BLAST+ del NCBI [^nota16-blast].
[^nota16-blast]: Hay que bajar el BLAST adecuado para tu sistema operativo desde esta página: <https://ftp.ncbi.nlm.nih.gov/blast/executables/blast+/LATEST/>
En las imagenes podemos ver el formulario de entrada y cual es el resultado que obtenemos luego de apretar el botón de **Send**.
![**Figura 16.1** Formulario de HTML para el filtrado de secuencias.](images/vectorfilterindex.png)
![**Figura 16.2** Resultado del filtrado de vectores.](images/vectorfilterresultcolor.png)
### Código fuente comentado
** Código HTML del formulario de entrada **
**Listado 16.1:** `index.html`: Formulario para filtrar un vector.
{line-numbers=on,lang=html}
```
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8">
<title>Vector Filter</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
</head>
<body style="background-color:#e7f5f5;">
<div class="container"><h2>Vector Filter</h2>
<form action='/vector_result' method='post'>
<div class="row">
<div class="col-sm-8">
<div class="form-group">
<label for="seqs">Paste sequence in FASTA format:</label>
<p><textarea name="seqs" rows="15" cols="80"></textarea></p>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-8">
<div class="form-group">
<label for="prop">Filter by: </label>
<div class="radio">
<label>
<input type="radio" name="vector" value="customdb">Custom Vectors
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="vector" value="ncbivector">NCBI Vector DB
</label>
</div>
<br>
<button type="submit" class="btn btn-primary">Send </button>
</div>
</div>
</div>
</form>
</div>
</body>
</html>
```
Este código produce, cuando se procesa mediante un navegador web, una página como la que se muestra en la Figura 16.1.
En la línea 4 hay una llamada al script de Python que procesa el formulario. Este script se muestra en el listado 16.3.
**Plantilla de salida del HTML**
**Listado 16.2:** `vector_result.tpl`: Archivo de plantilla.
```
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8">
<title>Vector Filter</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
</head>
<body style="background-color:#e7f5f5;">
<div class="container">
<h2>Vector Filter Result</h2>
<pre>{{finalout}}</pre>
</div>
</body>
</html>
```
**Código del server**
**Listado 16.3:** `vector.py`: Script web para filtrar una secuencia de ADN.
```
import os, io
from Bio import SeqIO
from Bio.SeqRecord import SeqRecord
from Bio.Blast import NCBIXML
from Bio.Blast.Applications import NcbiblastnCommandline as blastn
from bottle import route, post, run, static_file, request, view
from tempfile import NamedTemporaryFile
BLAST_EXE = '/home/sbassi/opt/ncbi-blast-2.6.0+/bin/blastn'
DB_BASE_PATH = '/home/sbassi/opt/ncbi-blast-2.6.0+/db/'
MASK = 'N'
def create_rel(XMLin):
"""
Create a dictionary that relate the sequence name
with the region to mask
"""
bat1 = {}
output = io.StringIO()
output.write(XMLin)
output.seek(0)
b_records = NCBIXML.parse(output)
for b_record in b_records:
for alin in b_record.alignments:
for hsp in alin.hsps:
qs = hsp.query_start
qe = hsp.query_end
if qs > qe:
qe, qs = qs, qe
record_id = b_record.query.split(' ')[0]
if record_id not in bat1:
bat1[record_id] = [(qs,qe)]
else:
bat1[record_id].append((qs,qe))
return bat1
def maskseqs(ffh, bat1):
"""
Take a FASTA file and apply the mask using the
positions in the dictionary
"""
outseqs = []
for record in SeqIO.parse(ffh, 'fasta'):
if record.id in bat1:
# Generate a mutable sequence object to store
# the sequence with the "mask".
mutable_seq = record.seq.tomutable()
coords = bat1[record.id]
for x in coords:
mutable_seq[x[0]:x[1]] = MASK*(x[1]-x[0])
seq_rec = SeqRecord(mutable_seq, record.id, '', '')
outseqs.append(seq_rec)
else:
# Leave the sequence as found
outseqs.append(record)
return outseqs
@route('/')
def index():
return static_file('index.html', root='views/')
@post('/vector_result')
@view('vector_result')
def result():
seqs = request.forms.get('seqs')
db = os.path.join(DB_BASE_PATH, 'UniVec_Core')
if request.forms.get('vector','customdb') == 'customdb':
db = os.path.join(DB_BASE_PATH, 'custom')
# Create a temporary file
with NamedTemporaryFile(mode='w') as fasta_in_fh:
# Write the user entered sequence into this temporary file
fasta_in_fh.write(seqs)
# Flush data to disk without closing and deleting the file,
# since that closing a temporary file also deletes it
fasta_in_fh.flush()
# Get the name of the temporary file
file_in = fasta_in_fh.name
# Run the BLAST query
blastn_cline = blastn(cmd=BLAST_EXE, query=file_in, db=db,
evalue=.0005, outfmt=5)
rh, eh = blastn_cline()
# Create contamination position and store it in a dictionary
bat1 = create_rel(rh)
# Get the sequences masked
newseqs = maskseqs(file_in, bat1)
with io.StringIO() as fasta_out_fh:
SeqIO.write(newseqs, fasta_out_fh, 'fasta')
fasta_out_fh.seek(0)
finalout = fasta_out_fh.read()
return {'finalout':finalout}
@route('/css/<filename>')
def css_static(filename):
return static_file(filename, root='css/')
run(host='localhost', port=8080)
```
Este código asume que hay dos bases de datos con formato BLAST (de la línea 67 a la 69). Una base se llama *UniVec_Core* y la otra, *custom*. *UniVec_Core* está incluida en el repositorio del libro en el directorio *samples* (<https://github.com/ToyokoLabs/Py4Bio/tree/master/samples>). Está compuesta por tres archivos: *UniVec_Core.nhr*, *UniVec_Core.nin* y *UniVec_Core.nsq*. Hay que copiarlos a un directorio y este directorio debe estar indicado en la constante *DB_BASE_PATH* (ver línea 11). En el caso de la base *custom*, es una base que hay que crear con datos nuestros. Si uno no la quiere crear, puede no seleccionarla en el momento de ejecutar el programa y este va a usar la base *UniVec_Core* que es la que está seleccionada por defecto. Si uno quiere crear la base *custom*, debe ejecutar el utilitario *makeblastdb* que se incluye en el BLAST+ del NCBI. Si nuestro archivo de secuencia se llama `custom`, un comando *makeblastdb* puede verse así:
{line-numbers=off,lang=text}
```
$ ./makeblastdb -dbtype nucl -in custom -title custom
Building a new DB, current time: 03/04/2017 19:04:07
New DB name: /home/sb/custom
New DB title: custom
Sequence type: Nucleotide
Keep MBits: T
Maximum file size: 1000000000B
Adding sequences from FASTA; added 2822 sequences in 0.1253 seconds.
```
Donde **-in** significa "archivo de entrada", `-dbtype nucl` significa que es una base de nucleótidos (`-dbtype prot` es para proteína). El manual de **makeblastdb** está disponible desde la línea de comandos con la opción `-h`. Luego de crear la base, hay que mover los archivos generados (*custom.nhr*, *custom.nin* y *custom.nsq*) al mismo directorio donde está la base *UniVec_Core* (ver línea 11 en *vector.py*).
## RECURSOS ADICIONALES
* K. W. Liao, Y. W. Chang, and S. R. Roffler, Presence of cloning vector sequences in the untranslated region of some genes in GenBank, J. Biomed. Sci., 7(6):529-30, 2000.
* C. Miller, J. Gurd, and A. Brass, A RAPID algorithm for sequence database comparisons: Application to the identification of vector contamination in the EMBL databases, Bioinformatics, 15(2):111-21, 1999.
* G. A. Seluja, A. Farmer, M. McLeod, C. Harger, and P. A. Schad, Establishing a method of vector contamination identification in database sequences, Bioinformatics, 15(2):106-10, 1999.
* C. Savakis and R. Doelz, Contamination of cDNA sequences in databases, Science, 259(5102):1677-8, 1993.