• Publicidad

Ayuda con matrices de 2 dimensiones

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Notapor Biokari » 2009-04-01 06:10 @299

Jajajaja, sí es verdad, ¡¡¡me descubriste!!! ¡¡¡¡Aun estoy en Windows!!!! ¡¡Lo siento!! Por favor, ¡¡¡perdóname!!! No me siento orgullosa pero es que traigo conmigo mi PC portátil y aun no he instalado Linux :oops:

Haré lo que me propones, gracias.

Bueno, hice un lindo esquema de lo que se supone que debe hacer este programa.
Imagen
Tengo un alineamiento de referencia que debe ser comparado con otros alineamientos, y su resultado ponerlos en una tabla o lo que sea, lo importante es que me muestra la similitud nucleótido por nucleótido de los diferentes alineamientos.

Entonces, como muestra la figura, tomo el primer nucleótido (o posición en rojo) y busco dónde está ese mismo elemento en el alineamiento que comparo; una vez encontrado debo comparar las columnas (en verde) de ambos alineamientos y ver su similitud. Por ejemplo en el esquema, para el primer elemento de ambos alineamientos hay una similitud de 1 (100%) y en el primer elemento de la segunda columna 0.8 (80%) y así sucesivamente.

La idea es ver cada elemento de los alineamientos y comparar cada vez las columnas donde se encuentran, y cuando hay un gap (A{3-4}, o una ausencia de elemento o nucleótido) en la tabla donde se recopilan los datos se pone un signo "-" y no se comparan las columnas. Pero cuando comparo las columnas si en los elementos hay gap, éstos deben tener el mismo valor de posición.

Luego vuelvo a tomar mi alineamiento de referencia y mi programa debería compararlo con cuantos alineamientos tenga y hacer una tabla para cada una de esas comparaciones.

Eso era para explicar bien. Ahora todo iba bien, hasta que me toca hacer la segunda matriz para un alineamiento siguiente, comparar y poner los datos en otra tabla, lista o lo que sea.


:cry:


¿¿¿¿ Alguna idea ???? jejeje :)

Otra cosa, explorer, eres demasiado bueno en Perl, ¡¡¡¡te has convertido en mi ídolo!!!!
Biokari
Perlero nuevo
Perlero nuevo
 
Mensajes: 13
Registrado: 2009-03-30 13:24 @600

Publicidad

Notapor explorer » 2009-04-01 07:05 @337

Biokari escribiste:Jajajaja, sí es verdad, ¡¡¡me descubriste!!! ¡¡¡¡Aun estoy en Windows!!!! ¡¡Lo siento!! Por favor, ¡¡¡perdóname!!! No me siento orgullosa pero es que traigo conmigo mi PC portátil y aun no he instalado Linux :oops:


Yo no tengo que perdonar nada. Cada uno se mortifica como quiere.

Biokari escribiste:La idea es ver cada elemento de los alineamientos y comparar cada vez las columnas donde se encuentran, y cuando hay un gap (A{3-4}, o una ausencia de elemento o nucleótido) en la tabla donde se recopilan los datos se poner un signo "-" y no se comparan las columnas. Pero cuando comparo las columnas si en los elementos hay gap, éstos deben tener el mismo valor de posición.

Luego vuelvo a tomar mi alineamiento de referencia y mi programa debería compararlo con cuantos alineamientos tenga y hacer una tabla para cada una de esas comparaciones.


Vaya, ¡qué casualidad!. El mismo problema que tiene Ponciano... ¿vais a pares?

Biokari escribiste:Otra cosa, explorer, eres demasiado bueno en Perl, ¡¡¡¡te has convertido en mi ídolo!!!!


Sí, pero de idolatría no se come...
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor Biokari » 2009-04-01 13:40 @611

Sí, tienes razón, mucha razón...
Biokari
Perlero nuevo
Perlero nuevo
 
Mensajes: 13
Registrado: 2009-03-30 13:24 @600

Notapor explorer » 2009-04-01 15:35 @691

Biokari escribiste:Otra pregunta: ¿por qué pusiste al final del script el $print "@columnas\n"; en comentario?


Como diríais los biólogos, es ADN basura.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor explorer » 2009-04-01 18:48 @825

No entiendo porqué la segunda columna tiene un 80% de similitud. Y tampoco entiendo porqué eliges a los elementos A1, A2 y D3... Ni tampoco porqué la tercera columna del alineamiento de referencia se compara con la cuarta columna del alineamiento 1.

Necesito más detalle... imagínate que soy un ordenador... no puedo rellenar los espacios sin información ("gap").
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor Biokari » 2009-04-02 15:37 @692

Hola Explorer

No entiendo porqué la segunda columna tiene un 80% de similitud.

Por que:

Paso 1: tomo A2 de mi alineamiento de referencia, y luego busco dónde se encuentra en el segundo alineamiento, o alineamiento 1 (como muestra el esquema)

Paso 2: una vez encontrado éste comparo las columnas en donde se encuentran respectivamente (comparando los elementos de ésta), los primeros elementos son A2=A2 (iguales), luego B2=B2 (iguales), C2=C2 (iguales), D2 != D {1-2} (no iguales), E2=E2 (iguales). Entonces de los 5 elementos hay 4 iguales => 4/5 = 0.8.

Paso 3: tomo el siguiente elemento del alineamiento de referencia y lo busco en el alineamiento 1 que estoy comparando.

Paso 4: repito lo del paso 2 anterior, los elementos me dan 4 parecidos de 5, o sea 4/5 = 0.8.

Y así sucesivamente con cada elemento del alineamiento de referencia.

Y tampoco entiendo porqué eliges a los elementos A1, A2 y D3...


En realidad los elegí así para tener diferentes ejemplos, pero la realidad sería A1 A2 A3 y así sucesivamente y en orden, una vez terminado ese, sigo con B1 B2 B3... y luego con C1 C2... hasta el final y por cada uno de esos elementos hago los pasos descritos anteriormente.

Ni tampoco porqué la tercera columna del alineamiento de referencia se compara con la cuarta columna del alineamiento 1.


Esto porque, como digo anteriormente, primero me interesa buscar en el alineamiento 1 el elemento que estoy mirando en mi alineamiento de referencia, o sea si por ejemplo estoy en D3 (esto quiere decir que ya pase por todos los A...B....C....D1,D2) voy a buscar en qué columna del alineamiento 1 está este D3, y bueno, en este ejemplo está en la cuarta columna del alineamiento 1, lo que me interesa es el elemento, y no que éste en la misma columna, y una vez que lo encuentro comparo las columnas del alineamiento de referencia y del alineamiento 1 donde se encuentran el elemento común que estoy buscando.

Esto pasa porque con los gap los elementos se corren de posición.

Y en cuanto a los "gap" no es ni un valor nulo, ni un valor 0; en presencia de un gap se pone un signo "-" o carácter si quieres llamarlo así, porque es una información, pero no un valor.

Eso, espero que haya quedado mas claro.


SALUDOS

Anexo:

¿¿Qué es un alineamiento??

Las secuencias de ADN de cada especie (o de especies diferentes) son esquematizadas de la siguiente manera:

Código: Seleccionar todo
>random sequence 1 consisting of 10 bases.
gaatcttttt

>random sequence 2 consisting of 10 bases.
cggcccggat

>random sequence 3 consisting of 10 bases.
gtacccggac

>random sequence 4 consisting of 10 bases.
gaccttccag

>random sequence 5 consisting of 10 bases.
gtatcaggtt



Para ver si estas secuencias perteneces a la misma especie o si son familiares se hace lo que se llama un "alineamiento". Hoy en día estos alineamientos se hace gracias a programas informáticos como "clustal", entre otros. Sobre todo porque una secuencia tiene más de 10 pares de bases y más de 5 secuencias, como muestra el ejemplo...

¿¿Y en qué consiste este alineamiento?? Bueno, en tratar de poner los pares de bases (atcg) alineados para tratar de hacerlos los más similares posibles (obviamente si las secuencias lo permiten). Entonces estos programas alinean lo más posible, con ciertas reglas, claro está, y hay veces que el programa considera que se parecen pero que quizás, en el transcurso de la evolución, hay uno de estos pares de bases (agct) que se suprimió o que se insertó, y el programa pone un "gap" que se ve con un signo "-". Bueno, entonces, por ejemplo ClustalW hace el alineamiento de la secuencia siguiente de esta manera:

Código: Seleccionar todo
random_sequence_2      CGGCCCGGAT-
random_sequence_3      GTACCCGGAC-
random_sequence_5      GTATCAGGTT-
random_sequence_1      GAATCTTTTT-
random_sequence_4      -GACCTTCCAG


Lo que yo pretendo hacer es un programa de fiabilidad de alineamientos, por ello cojo un alineamiento de referencia y lo comparo con otros alineamientos hechos con otros programas para ver la fiabilidad de estos.
Biokari
Perlero nuevo
Perlero nuevo
 
Mensajes: 13
Registrado: 2009-03-30 13:24 @600

Notapor Biokari » 2009-04-03 02:50 @159

Me di cuenta que en el script, las secuencias fueron convertidas en columnas, mmm y en realidad es el primer elemento de la primera secuencia que es el primer elemento de la primera columna, y es el primer elemento de la segunda secuencia que hace el segundo elemento de la primera columna y así sucesivamente, como en el esquema.

Trato de poner las columnas como describo anteriormente pero, no me sale (que raro, ¿no?) trato de hacer split() a una nueva variable $seq, pero no funciona... mmm.
Biokari
Perlero nuevo
Perlero nuevo
 
Mensajes: 13
Registrado: 2009-03-30 13:24 @600

Notapor explorer » 2009-04-10 14:30 @645

Bueno, creo que ya lo tengo.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
#
# Comparación de alineamientos
# Joaquín Ferrero, abril 2009
#
#   Informa de la fiabilidad entre el alineamiento de referencia y los pasados
#   como argumentos al programa.
#   Muestra una matriz de fiabilidad por cada alineamiento a comparar.

# Entrada
#   Pasamos como argumentos al programa los ficheros que contienen los
#   alineamientos a comparar, siendo el primero el alineamiento de referencia.
#
# Salida
#   Matriz de fiabilidad
#

## Comprobamos los argumentos o informamos al usuario
@ARGV > 1 or die
    "Uso: $0 <alineación de referencia> <alineación1> [<alineación2> ...]\n";

## Proceso:
# Leer los alineamientos
# Para todos los nucleótidos del alineamiento de referencia
#   Para todos los alineamientos a comparar
#       Buscar la columna del alineamiento donde se encuentra el nucleótido de
#           referencia
#       Calcular la fiabilidad entre la columna del alineamiento de referencia
#           y la encontrada
#       Guardar el valor en la matriz fiabilidad, según posición y número
#           alineamiento
#   Fin Para
# Fin Para
# Imprimir matriz de fiabilidad

my @alineamientos;          # Alineamientos leídos (todos)
my @alineamiento_ref;       # Alineamiento de referencia
my @fiabilidad;             # Matriz de fiabilidad
my $filas;                  # Número de secuencias del alineamiento de referencia

if (@alineamientos    = lee_alineamientos()) {
    @alineamiento_ref =  @{$alineamientos[0]};
    $filas = @alineamiento_ref;

    ## Recorremos el alineamiento de referencia
    for (my $seq_ref = 0; $seq_ref < $filas; $seq_ref++) {
    for (my $col_ref = 0; $col_ref < @{$alineamiento_ref[$seq_ref]}; $col_ref++) {

        ## Nucleótido a buscar
        my $nucleo_ref = $alineamiento_ref[$seq_ref]->[$col_ref];

        for (my $i_alinea = 1; $i_alinea < @alineamientos; $i_alinea++) {
            ## Busca en qué columna del alineamiento $i_alinea se encuentra
            ## el nucleótido $nucleo_ref
            my $fiabilidad = 0;

            if ($nucleo_ref =~ /-/) {
                $fiabilidad = '-';
            }
            else {
                my $columna = busca_columna($nucleo_ref, $i_alinea);
                if ($columna > -1) {
                    $fiabilidad = compara_columnas($col_ref, $i_alinea, $columna);
                }
                else {
                    # TODO No definido qué hay que hacer
                }
            }

            $fiabilidad[$i_alinea-1]->[$seq_ref]->[$col_ref] = $fiabilidad;
        }
    }}

    ## Salida de la matriz de fiabilidad
    for (my $i_fiable = 0; $i_fiable < @fiabilidad; $i_fiable++) {
        print "Matrice de fiabilité (Alineamiento ref. vs Alineamiento ", $i_fiable+1, ")\n";

        # para todas las filas
        for (my $seq = 0; $seq < $filas; $seq++) {

            # para todas las columnas, las juntamos
            print join("\t", @{$fiabilidad[$i_fiable]->[$seq]}), "\n";
        }
        print "\n";
    }
}


## Subrutinas
sub compara_columnas {
    my ($col_ref, $i_alinea, $columna) = @_;

    my $igualdades = 0;

    for (my $seq = 0; $seq < @alineamiento_ref; $seq++) {
        $igualdades++
           if $alineamientos[        0]->[$seq]->[$col_ref]
           eq $alineamientos[$i_alinea]->[$seq]->[$columna]
        ;
    }

    return $igualdades / @alineamiento_ref;
}

sub busca_columna {
    my $nucleo_ref = shift;
    my $i_alinea   = shift;

    ## Buscamos el nucleótido en el alineamiento
    for my $seq (@{$alineamientos[$i_alinea]}) {
        for my $i (0 .. $#{$seq}) {
            return $i if $seq->[$i] eq $nucleo_ref;
        }
    }
    return -1;
}

sub lee_alineamientos {
    # Lee los alineamientos pasados por el usuario como argumentos y los
    # devuelve como un arreglo de arreglos
    my @matrices;

    for my $fichero (@ARGV) {

        open FASTA, '<', $fichero
            or warn "No pude leer el fichero $fichero: $!\n"
            and next;


        chomp(my @fichero_fasta = <FASTA>);
        close FASTA;

        my @matriz;

        ## Bucle por las filas
        my $nombre_seq;
        for my $linea (@fichero_fasta) {
            if ($linea =~ /^>(.+)/) {
                $nombre_seq = $1;
                next;
            }
            if ($linea =~ /^([atcg-]+)/i) {
                ## Bucle por las columnas
                my $contador;
                my @columnas;
                for my $columna (split //, $1) {
                    if ($columna =~ /[atcg]/i) {
                        $contador++;
                        push @columnas, "$nombre_seq$contador";
                    }
                    else {
                        push @columnas, "$nombre_seq\{$contador-@{[$contador+1]}\}";
                    }
                }
                push @matriz, \@columnas;
            }
        }
        push @matrices, \@matriz;
    }

    return @matrices;
}

__END__
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4

Con los ficheros de ejemplo que has puesto, la salida es:
Código: Seleccionar todo
Matrice de fiabilité (Alineamiento ref. vs Alineamiento 1)
1       0.8     0.8     -       -       -       1       1       1       1
1       0.8     0.8     -       -       -       1       1       1       1
1       0.8     0.8     0.8     1       1       1       1       1       1
1       0.2     0.2     -       -       -       -       -       -       1
1       0.8     0.8     0.8     1       1       1       1       1       1
Última edición por explorer el 2009-04-10 21:59 @957, editado 1 vez en total
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Añadido...

Notapor explorer » 2009-04-10 21:57 @956

La forma de ver la "fiabilidad" me ha parecido curiosa, porque no veo normal que se comparen las proximidades entre secuencias simplemente mirando las zonas en las que hay nucleótidos de las zonas que no hay (gap).

Es decir, que no se mira la coincidencia posicional de cada una de las letras, para ver su similitud... solo la presencia o no de nucleótidos.

Ahora bien... si pensamos que cada secuencia fuera una simple cadena de caracteres, podríamos pensar en qué tanto por ciento son similares entre el fichero de referencia y el resto de alineamientos. Y mirando letra por letra.

En CPAN hay varios módulos dedicados a medir esas diferencias: String::Approx, String::Compare, String::Diff, y alguno más.

Por ejemplo. Supongamos que leemos los ficheros de alineamientos, pero no miramos cada nucleótido por separado, sino que comparamos cada secuencia del alineamiento de referencia con la secuencia correspondiente del resto de alineamientos.

El código queda mucho más corto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
#
# Comparación de alineamientos
# Joaquín Ferrero, abril 2009
#

use strict;
use warnings;

use String::Approx 'adistr';


## Comprobamos los argumentos o informamos al usuario
@ARGV > 1 or
    die "Uso: $0 <alineación de referencia> <alineación1> [<alineación2> ...]\n";

## Variables globales
my @nombres_secuencias;     # Nombres de las secuencias de referencia

## Proceso general
if (my @alineamientos = lee_alineamientos()) {

    print 'Matrice de fiabilité (Alineamiento ref. vs Alineamientos)', "\n";

    # Recorremos el alineamiento de referencia, por filas
    for my $seq (0 .. @{$alineamientos[0]}-1) {

        print $nombres_secuencias[$seq];

        # Para todos los alineamientos a comparar
        for my $i_alinea (1 .. @alineamientos-1) {

            my $fiabilidad
                = 1
                - adistr(
                    $alineamientos[0        ]->[$seq],
                    $alineamientos[$i_alinea]->[$seq]
            );

            print "\t$fiabilidad";
        }

        print "\n";
    }
}

## Subrutinas
sub lee_alineamientos {
    my @matrices;

    for my $fichero (@ARGV) {

        open FASTA, '<', $fichero
            or  warn "No pude leer el fichero $fichero: $!\n"
            and next;
        chomp(my @fichero_fasta = <FASTA>);
        close FASTA;

        my @matriz;

        ## Bucle por las filas
        for (@fichero_fasta) {
            if (/^>(.+)/) {
                push @nombres_secuencias, $1;
                next;
            }
            if (/^([atcg-]+)/i) {
                push @matriz, $_;
            }
        }
        push @matrices, \@matriz;
    }

    return @matrices;
}

__END__
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
El resultado es:
Código: Seleccionar todo
Matrice de fiabilité (Alineamiento ref. vs Alineamientos)
A       1
B       1
C       1
D       0.8
E       1
con lo que vemos que todas las secuencias son iguales, excepto la cuarta, que tiene una similitud del 80%.

Afinando un poco más el programa, y mirando aún más el módulo String::Approx, se podría deducir incluso que esa cuarta secuencia tiene aún más similitud, ya que solo hay un espacio de diferencia.

Naturalmente, como no soy biólogo, no sé si es correcto este planteamiento.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor Biokari » 2009-05-29 04:14 @218

Hola

Bueno, finalmente resolví mi problema. Quiero agradecer por la ayuda otorgada en este foro, y luego (porque no lo tengo acá) pondré el código final que utilicé para ver si le sirve a alguien más, que es la idea de esta comunidad.

Por otra parte quisiera sugerir que se hiciera un tema o subforo para bioinformáticos, que siempre caemos en el mismo problema; llegamos a programar con una base nula en informática y además nuestros programas son bien precisos, siempre trabajando con números y letras que corresponden a alineamientos de secuencias de ADN y proteínas. Además de la utilización de formatos especiales como FASTA y programas en bioinformática. Quizás todos estos conocimientos podrían dejarse en un solo lugar para futuros bioinformáticos u otras ciencias básicas ligadas a la programación.

Bueno eso, gracias una vez más por la ayuda otorgada.

Biokari
Biokari
Perlero nuevo
Perlero nuevo
 
Mensajes: 13
Registrado: 2009-03-30 13:24 @600

AnteriorSiguiente

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 2 invitados