Generando secuencia de ADN sintético con tasa de sustitución
-
03-07-2019 - |
Pregunta
Dadas estas entradas:
my $init_seq = "AAAAAAAAAA" #length 10 bp
my $sub_rate = 0.003;
my $nof_tags = 1000;
my @dna = qw( A C G T );
Quiero generar:
-
Mil etiquetas de longitud 10
-
La tasa de sustitución para cada posición en una etiqueta es 0.003
Rendimiento de salida como:
AAAAAAAAAA
AATAACAAAA
.....
AAGGAAAAGA # 1000th tags
¿Hay una forma compacta de hacerlo en Perl?
Estoy atascado con la lógica de este script como núcleo:
#!/usr/bin/perl
my $init_seq = "AAAAAAAAAA" #length 10 bp
my $sub_rate = 0.003;
my $nof_tags = 1000;
my @dna = qw( A C G T );
$i = 0;
while ($i < length($init_seq)) {
$roll = int(rand 4) + 1; # $roll is now an integer between 1 and 4
if ($roll == 1) {$base = A;}
elsif ($roll == 2) {$base = T;}
elsif ($roll == 3) {$base = C;}
elsif ($roll == 4) {$base = G;};
print $base;
}
continue {
$i++;
}
Solución
Como pequeña optimización, reemplaza:
$roll = int(rand 4) + 1; # $roll is now an integer between 1 and 4
if ($roll == 1) {$base = A;}
elsif ($roll == 2) {$base = T;}
elsif ($roll == 3) {$base = C;}
elsif ($roll == 4) {$base = G;};
con
$base = $dna[int(rand 4)];
Otros consejos
EDITAR: asumiendo que la tasa de sustitución está en el rango de 0.001 a 1.000:
Además de $ roll
, genere otro (pseudo) número aleatorio en el rango [1..1000], si es menor o igual que (1000 * $ sub_rate) luego realice la sustitución, de lo contrario no hacer nada (es decir, salida 'A').
Tenga en cuenta que puede introducir un sesgo sutil a menos que se conozcan las propiedades de su generador de números aleatorios.
No es exactamente lo que está buscando, pero le sugiero que eche un vistazo a módulo Bio :: SeqEvolution :: DNAPoint . Sin embargo, no toma la tasa de mutación como parámetro. Más bien, pregunta cuál es el límite inferior de la identidad de secuencia con el original que desea.
use strict;
use warnings;
use Bio::Seq;
use Bio::SeqEvolution::Factory;
my $seq = Bio::Seq->new(-seq => 'AAAAAAAAAA', -alphabet => 'dna');
my $evolve = Bio::SeqEvolution::Factory->new (
-rate => 2, # transition/transversion rate
-seq => $seq
-identity => 50 # At least 50% identity with the original
);
my @mutated;
for (1..1000) { push @mutated, $evolve->next_seq }
Todas las 1000 secuencias mutadas se almacenarán en la matriz @mutada, se puede acceder a sus secuencias a través del método seq
.
En el caso de una sustitución, desea excluir la base actual de las posibilidades:
my @other_bases = grep { En el caso de una sustitución, desea excluir la base actual de las posibilidades:
<*>
También consulte Respuesta de Mitch Wheat para cómo implementar la tasa de sustitución.
ne substr($init_seq, $i, 1) } @dna;
$base = @other_bases[int(rand 3)];
También consulte Respuesta de Mitch Wheat para cómo implementar la tasa de sustitución.
No sé si lo comprendo correctamente, pero haría algo como esto (pseudocódigo):
digits = 'ATCG'
base = 'AAAAAAAAAA'
MAX = 1000
for i = 1 to len(base)
# check if we have to mutate
mutate = 1+rand(MAX) <= rate*MAX
if mutate then
# find current A:0 T:1 C:2 G:3
current = digits.find(base[i])
# get a new position
# but ensure that it is not current
new = (j+1+rand(3)) mod 4
base[i] = digits[new]
end if
end for