13 de febrero de 2016

Expresión regular de la familia de las O-fucosiltransferasas



Hola, 
el pasado 8 de febrero se publicó en la revista Nature Chemical Biology  (http://dx.doi.org/10.1038/nchembio.2019) un artículo donde se  describen las bases moleculares de la reacción de O-fucosilación. Ésta es una modificación postraduccional poco frecuente, que realizan las enzimas O-fucosiltransferasas, como nos explica la investigadora de nuestro grupo Inmaculada Yruela, una de las autoras del trabajo [reseña completa en www.eead.csic.es]:

"Esta reacción resulta esencial en algunas rutas metabólicas de los organismos eucariotas, incluidas las plantas, para mantener las funciones básicas de las células. El artículo describe el mecanismo por el cual la enzima O-fucosiltransferasa 2 (POFUT2) reconoce sin errores una secuencia de aminoácidos (TSR) de la proteína receptora y le transfiere una molécula de azúcar tipo fucosa –así resulta fucosilada–. Hasta la fecha no se conocía cómo estas enzimas reconocen y se unen a sus sustratos proteicos. La O-fucosilación es esencial para el correcto plegamiento y estabilidad del dominio TSR y el reconocimiento molecular de POFUT2."
Como se ve en el alineamiento, el dominio TSR contiene tres puentes disulfuro y una secuencia consenso en torno a los dos primeras cisteínas CX{2,3}[S|T]CX{2}G , lo que se llama un motivo, como los del repositorio Prosite:
Fragmento de un alineamiento múltiple de dominios TSR, tomado de http://dx.doi.org/10.1038/nchembio.2019

Tras alinear algunas secuencias de ejemplo y perfeccionar la expresión regular, ésta se empleó para identificar todas las secuencias con dominios TSR en los proteomas de Homo sapiens y Caenorhabditis elegans. Más generalmente, el siguiente trozo de código permite localizar dentro de un fichero FASTA todas las secuencias reconocidas por una expresión regular:
 #!/usr/bin/perl  
 use strict;  
   
 # script that takes a FASTA file(s) and scans all protein sequences   
 # looking for matches of a chosen motif expressed as a regular expression  
 # 11042015: edited following comments by JF
   
 # constant as indices to access read_FASTA_file arrays  
 use constant NAME => 0;   
 use constant SEQ => 1;  
   
 #my $motifRE = '.*C[^C]{0,21}.C[^C]{2,6}[S|T].C[^C]{4,75}C[^C]C[^C]{4,15}C.*'; 
 my $motifRE = 'C[^C]{0,21}.C[^C]{2,6}[ST].C[^C]{4,75}C[^C]C[^C]{4,15}C';
   
 if(!@ARGV){ die "# usage: $0  ... \n"; }  
 else{ print "# motif: $motifRE\n"; }  
   
 my ($n_of_matches,@matches) = (0);  
 foreach my $infile (@ARGV)  
 {  
   next if($infile !~ /.fa/);  
   my (@FASTA,$start,$end,$l);  
   my $n_of_sequences = -1;  
   open(FASTA,"<$infile") || die "# cannot read $infile $!:\n";  
   while()  
   {  
    next if(/^$/);  
    if(/^\>(.*?)[\n\r]/)  
    {  
      $n_of_sequences++;   
      $FASTA[$n_of_sequences][NAME] = $1;  
    }                
    else  
    {  
      s/[-\s\n.]//g; #s/[\s|\n|\-|\.]//g;  
      $FASTA[$n_of_sequences][SEQ] .= $_;  
    }  
   }  
   close(FASTA);  
   
   foreach my $seq ( 0 .. $n_of_sequences )  
   {  
    while($FASTA[$seq][SEQ] =~ m/($motifRE)/gi)   
    {  
      #$start=length($`);  
      #$l=length($1);  
      #$end=$start+$l;  

      $start = $-[1];
      $end   = $+[1];
      $l     = $end - $start + 1;

      print ">$FASTA[$seq][NAME] match=($start,$end,$l)\n$1\n";           
    }  
   }  
 }  

Un saludo,
Inma y Bruno

1 comentario:

  1. Hola, copio aquí comentarios de Joaquín Ferrero:

    Recuerdo que las clases de caracteres solo contienen caracteres o rangos de caracteres. No son expresiones. Por lo tanto, el carácter '|' dentro de ellas no "funciona" como el operador 'or', sino que está como él mismo.

    Por lo tanto, la sentencia

    $_ =~ s/[\s|\n|\-|\.]//g;

    es igual a esta otra:

    $_ =~ s/[\s\n\|\-\.]//g;

    lo cual puede dar problemas si en el texto apareciese ese carácter. Tampoco es necesario "escapar" ciertos caracteres, como el punto o el guión (este último si se coloca al principio de la clase de caracteres). La expresión se puede entonces reducir a

    s/[-\s\n.]//g;

    Observar que también se ha quitado la primera parte '$_ =~' porque esa es la operación que por defecto realizará el operador s///.

    En cuanto a la primera exp. reg., creo que pasa lo mismo con la clase '[S|T]', que quedaría en '[ST]'.

    Un detalle importante: hay que tener cuidado con los comodines avariciosos '.*' del principio y del final. Pueden hacer desaparecer de la búsqueda algunas coincidencias, o peor: enlentecer la búsqueda.

    Como estamos buscando un patrón de forma repetida (con la opción '/g'), en este caso, esos comodines son completamente innecesarios. La línea quedaría así:

    my $motifRE = 'C[^C]{0,21}.C[^C]{2,6}[ST].C[^C]{4,75}C[^C]C[^C]{4,15}C';

    Otro detalle muy, muy importante: siempre que se puede, NO hay que usar las variables $`, $& y $', ya que enlentece esa expresión regular y todas las demás del programa. Si se está usando un Perl igual o superior a v5.10.0 es mejor usar las equivalentes "${^PREMATCH}", "${^MATCH}" y "${^POSTMATCH}", y poniendo además la opción '/p' en la exp. reg. (más información en perldoc perlre).

    En vuestro caso, es fácil solventarlo. Si se trata de saber la posición inicial de la secuencia encontrada, sería así:

    $l = length($1);
    $end = pos($FASTA[$seq][SEQ]);
    $start = $end - $l;

    (bueno, habría que sumar o restar 1 -o no hacer nada- según queramos que las posiciones estén basadas en 0 o 1).

    De forma más moderna:

    $start = $-[1];
    $end = $+[1];
    $l = $end - $start + 1;

    Más información en perldoc perlvar (buscar por @+ y @-).

    Un último consejo: los Perl más modernos (a partir de v5.20) han aumentado mucho la velocidad de procesamiento de exp. reg.

    Saludos,
    JF

    ResponderEliminar