#!/usr/bin/perl -w

use strict;
use Data::Dumper;
##########################################################################################################################################

################################################   DECLARACION DE VARIABLES   ###########################################################

##CONTADORES##

my $j;
my $i;
my $r;
my $c;
my $ll;
my $t;
my $n;

my $sequencies;         #donde entramos las secuencias
my @sequencies;
my $entrada;
my @matseq;             #matriz con: columna 0 (secuencias); columna 1 (identificadores)


my $m;                  #entrada longitud del motivo
my $l;                  #longitud de las secuencias
my $p;                  #posicion random
my @motius;             #donde iran los motivos

my @matriuM;            #matriz de pesos
my @total;              #numero total de cada  nucleotido en los motivos

my @back;               #matriz con el numero total de cada nt en el background sin tener en cuenta los nt de loa motivos
my @backc;              #matriz con el numero total de cada nucleotido en el background

my @lletres;            #vector con los 4 posibles nucleotidos
my @matriufreq;         #matriu de freq de los nt en los motivos y en cada posicion
my @matriufreq2;        #matriu de freq dels nt al background

my @scorein;            #matriz con los scores iniciales

my $w;                  #cuenta el numero de iteraciones
my%motiuE;              #hash con todos los motivos 


my @seq;                #secuencias
my %matriuE;            #puntuacion para cada candidato
my @motiuE;             #matriz con todos los motivos candidatos
my @posiciones;         #posiciones ordenadas por valores
my @best;               #posicion donde se encuentra el motivo con mayor puntuacion
my @matriuEtotal;       #matriz suma de los scores
my @matriuEnorm;        #matriz Etotal normalizada
my @scorein2;           #scores de la nueva iteracion 
my $sq;                 #numero de secuencias
my @totalE;             #normalizacion 
my $convergencia;       #contador 0/1
my @diferencies;        #nuevas diferencias
my @diferencies2;       #diferencias acomuladas
my $max;                #diferencia maxima entre dos iteraciones consecutivas
my $limit;              #similitud minima escogida para convergncia

#########################################################################################################################################
#######################################   PASO 0  :   LEYENDO SECUENCIAS DESDE EL FICHERO   #############################################
#########################################################################################################################################



if (scalar(@ARGV) < 1) {
    
    print STDERR "Para que el programa se ejecute correctamente escribe :./em.pl <nombre del fichero>\n";
    
    exit(1);
}


if(!open(FITXERSEQ,"<$ARGV[0]")){
    
    print STDERR "El programa no puede abrir el fichero. Asegurese que ambos se encuentran en el mismo directorio.";
    
    exit(1);
    
}else{
    
    print STDERR "Leyendo fichero: $ARGV[0]\n";
    
}

open(FITXERSEQ,"<$ARGV[0]");


$sequencies = "";

$i = 0;

while(<FITXERSEQ>){                        #Vamos leyendo el fichero linea por linea hasta encontrar un identificador (>), que lo colocara                                            en la columna 1. Todo lo que no es identificador, lo ira juntando hasta encontrar el siguiente                                            > y todo lo concatenado ira a la columna 0 en la fila correspondiente a su identificador.
    
    if($_=~/\A\>(\w+)/){
	
        if ($i > 0) {
	    
	    $matseq[$i-1][0]= [split(//,$sequencies)];      
	}
	$matseq[$i][1]= $1;
	
	$i++;
	
	$sequencies = "";
	
    }else{
	
	chomp($_);
	
	$sequencies= $sequencies.$_;
    }
    
}
if(!<FITXERSEQ>){                          #Cuando acaba de leer el fichero todavía queda secuencia que tendra que colocar en su posicion
    
    $matseq[$i-1][0]= [split(//,$sequencies)];
}


close(FITXERSEQ);

########################################################################################################################################
###############################################    PASO 1  : STARTING     ##############################################################
########################################################################################################################################


######################################### A )   eleccion de la posicion random    ######################################################


print "Escribe la longitud del motivo\n";

$m=<STDIN>;  


print "Escribe la similitud minima entre las matrices de score para detener las iteracciones por convergencia\n";

$limit= <STDIN>;
$i=0;

 
while($i < scalar(@matseq)){
    
    $l=scalar(@{$matseq[$i][0]});              
      
     
    $p= int(rand($l-$m));                                   #Con esto evitamos que la posicion random este demasiado cerca del final de la                                                             secuencia.
    
    $j = $p;
    
    
    if(($m+$p) <= $l){                                      #Con este paso también nos aseguramos de que el motivo solicitado no sea mas                                                              largo que la secuencia.    
	
	
	$motius[$i] = [];                      
	
	while($j <($m+$p)){                    
	    
	    push @{$motius[$i]}, $matseq[$i][0][$j];         #Concatenamos cada nuevo nt al final del anterior
	    
	    $j++;
	    
	    
	}
	
    }else{
	
	print "el motiu es massa llarg\n";
    }
    
    
    
    $i++;
}

            #################     Hacemos hash con todos los candidatos de todas las secuencies    ########################

$c=0;
$j=0;
$i=0;

while($matseq[$i][0]){
    
    
    
    @seq= @{$matseq[$i][0]};
    

    
    while(scalar(@seq)>= $m){


	while ($j<$m){
	    
	    
	 push @{$motiuE{$i}{$c}}, $seq[$j];
	
	    $j++;
	    	    
	}


	splice(@seq,0,1);

	$j=0;
	
	$c++;   
    }
    
    $j=0;
    $c=0;
    $i++;
}




	    

########################################### B ) construccion de la matriz de pesos inicial   ############################################



          ###########@@@####################   Inicializacion a cero   #####################################


@matriuM=[];                  
$i= 0;
$j =0;



while($i < 4){
    
    while( $j < $m){
	
	$matriuM[$i][$j]= 0;
	
	$j++;
    }
    $j=0;
    
    $i++; 
}


           ###########################    Llenamos la matriz con valores absolutos      ######################


$i=0;
$j=0;


while($motius[$i][$j]){
    
    
    
    @_=@{$motius[$i]};
    
    print @_,"\n";
    
    while ($j < scalar(@_)){                                     # leemos cada nt individualmente y lo colocamos en una matriz con tantas                                                                    columnnas como posiciones tenga el motivo y cuatro filas (cada fila                                                                       corresponde a uno de los nt posibles, ATCG).
	
	
	if(uc$_[$j]eq "A" || $_[$j] eq "a" ){              
	    
	    
	    $matriuM[0][$j]++;                            
	    
	}
	
	if (uc$_[$j]eq "T" || $_[$j] eq "t" ){
	    
	    $matriuM[1][$j]++;
	}
	
	if (uc$_[$j]eq "C" || $_[$j] eq "c" ){
	    
	    $matriuM[2][$j]++;
	    
	}
	if (uc$_[$j]eq "G" || $_[$j] eq "g" ){
	    
	    $matriuM[3][$j]++;    
	}
	
	
	$j= $j+1;
    }
    
    $j=0;
    $i=$i +1;
}


          ################    creamos un vector con el numero total de cada nucleotido en los motivos     ###############

$j =0;
@total = ();

while($j<4){
    
    $total[$j]=0;
    $j++;
}
$j=0;

while($j<$m){
    
    $total[0]= $total[0]+ $matriuM[0][$j];    
    $total[1]= $total[1]+ $matriuM[1][$j]; 
    $total[2]= $total[2]+ $matriuM[2][$j];
    $total[3]= $total[3]+ $matriuM[3][$j];
    
    $j++;
    
}

####################################  C )  Construccion de la matriz de background     #############################################

               ############################      Inicializacion a cero      ######################################



@back=();  
$i= 0;


while($i < 4){
    
    $back[$i] = 0;
    $i++; 

}

            
              ########################      Matriz de background  en números absolutos       #######################



$j = 0;
$i = 0;

while($i < scalar(@matseq)){
    
    @_= @{$matseq[$i]}; 
    
    
    while($_[0][$j]){ 
	
	
	if($_[0][$j]eq "A" || $_[0][$j] eq "a" ){              
	    
	    
	    $back[0]++;                            
	    
	}
	
	if ($_[0][$j]eq "T" || $_[0][$j] eq "t" ){
	    
	    $back[1]++;
        }
	
	if ($_[0][$j]eq "C" || $_[0][$j] eq "c" ){
	    
	    $back[2]++;
	    
        }
	if ($_[0][$j]eq "G" || $_[0][$j] eq "g" ){
	    
	    $back[3]++;    
        }
	
	$j++;
    }   
    
    $j=0;
    $i++;
}

$sq= $i-1;



          ###############  Restamos el numero de nt de los motivos pera no tenerlos en cuenta en el background     ############


@backc = restav( \@back,\@total);


##############################    D )   Matriz de frecuencias relativas de los  motivos     ##############################################
open(TXT,">resultat.txt");
open(HTML,">resultat.html");

print TXT "\nFichero analizado: ",$ARGV[0],"\n";
print TXT "La longitud del motivo seleccionado es: ",$m,;
print TXT "La similitud minima seleccionada es: ", $limit;
print TXT "\n";
print TXT "###########################################################################################################################\n";print TXT "\n";


print HTML '<html><title><EXPECTATION MAXIMIZATION ALGORITHM></title><head><font color= "#990066"><center><h1> EXPECTATION MAXIMIZATION ALGORITHM</head></center><body><h1><p align="center"><font color="990066">RESULTADOS</p></h1><br><p align="center"><br></body><ul><ul><table><tr><td><h2> El fichero analizado es: ',$ARGV[0],'</h2></td></tr></table></ul></ul><ul><ul><table><tr><td><h2> La longitud del motivo seleccionado es: ',$m,'</h2></td></tr></table></ul></ul><ul><ul><table><tr><td><h2> La similitud m&iacute;nima seleccionada es: ',$limit,"</h2></td></tr></table></ul></ul>\n";

@lletres=("A","T","C","G");

$ll=0;

print TXT "Matriz con la frecuencia de cada nucleotido segun su posicion en los motivos:\n";
print TXT "\n";


$i=0;
$j=0;

print HTML '<br><hr><h3><br><p><center><font color="990066">Matriz con la frecuencia de cada nucle&oacute;tido seg&uacute;n su posici&oacute;n en los motivos</h3><br><p></center><br>';

print HTML '<table align="center" border="2" BGCOLOR=#D3E8FF>';


while($i < 4){
      print HTML '<tr>';
    if ($i==0){print HTML '<td><color="990066"><b>A</td>'}
    if ($i==1){print HTML '<td><color="990066"><b>T</td>'}
    if ($i==2){print HTML '<td><color="990066"><b>C</td>'}
    if ($i==3){print HTML '<td><color="990066"><b>G</td>'}
    print TXT $lletres[$ll]," ";
     
     while( $j < $m){
	
	$matriufreq[$i][$j]= ($matriuM[$i][$j])/$sq;
	
	printf TXT "%.3f",$matriufreq[$i][$j];
	printf TXT " ";

	print HTML '<td>';
	printf HTML "%1.3f\t", $matriufreq[$i][$j];
	print HTML '</td>';

	
	$j++;
    }
     print TXT "\n";
     $ll++;    
    $i++; 
    $j=0;
}

print TXT "\n";
print TXT "\n";
print TXT "\n";



###############################      E )  Matriz de frecuencias relativas  del background      ##########################################

$j=0;
@matriufreq2 = ();


@matriufreq2 = media(@backc);



#########################################   F  )  Calculo final de la matriz de pesos inicial   #########################################

#Normalizamos la matriz haciendo el log en base 2 de la division de las frecuencias relativas de cada nucleotido en cada posicion del motivo  entre la frecuencia relativa de ese nucleotido en el background

$i=0;
$j=0;

while($i<4){
    
    while($j<$m){

	$scorein[$i][$j] = $matriufreq[$i][$j]/ $matriufreq2[$i];

	if($scorein[$i][$j] != 0){
	    
	    $scorein [$i][$j]= log2($scorein[$i][$j]);

	}else{
	    
	    $scorein [$i][$j]= -9999;
	}

	$j++;
    }

    $j=0;
    $i++;
}




###########################################################################################################################################################################################      PASO 2  :   E-STEP     ######################################################################################################################################################################################################

######################################     A  )  Asignacion de un score a cada motivo candidato    ###################################### 

        ##################################       Inicializacion matriz a cero       #########################################
$w=0;
$convergencia=0;


while($w<50 && $convergencia<1){
    
    print "Iniciando paso E. Iteracion: ", $w,"\n";
    $j = 0;
    $i = 0;
    
    $c=0;
    %matriuE= ();
    @seq=();
    
    
    
    while($motiuE{$i}{$j}){ 
	
	
	while($motiuE{$i}{$j}){
	    
	    $matriuE{$i}{$j} = 0;
	    
	    $j++;
	}
	$j=0;	 
	$i++;
    }
    
    ###################################          Asignacion scores           #########################################
    
    
    $i = 0;
    
    
    while($matseq[$i][0]){
	$matriuEtotal[$i]= 0;
	
	
	$i++;
    }
    
    @best =();
    $j = 0;
    $i = 0;
    $c=0;
    
    while($motiuE{$i}{$c}){
	
	
	
	
	while($motiuE{$i}{$c}){
	    
	    
	    while($j<scalar(@{$motiuE{$i}{$c}})){
		
		
		
		if(uc$motiuE{$i}{$c}[$j]eq "A" ){             
		    
		    
		    $matriuE{$i}{$c} = $matriuE{$i}{$c} + $scorein[0][$j];         
		}
		
		if(uc$motiuE{$i}{$c}[$j]eq "T" ){             
		    
		    
		    $matriuE{$i}{$c}= $matriuE{$i}{$c} + $scorein[1][$j];         
		}
		
		if(uc$motiuE{$i}{$c}[$j]eq "C" ){             
		    
		    
		    $matriuE{$i}{$c}= $matriuE{$i}{$c} + $scorein[2][$j];         
		}
		if(uc$motiuE{$i}{$c}[$j]eq "G" ){             
		    
		    
		    $matriuE{$i}{$c}= $matriuE{$i}{$c} + $scorein[3][$j];         
		}
		
		
		
		
		
		$j++;
		
	    }
	    if($matriuE{$i}{$c} < 0){
		
		$matriuE{$i}{$c}= 0.0000001;
	    }
	    $matriuEtotal[$i]= $matriuEtotal[$i] + $matriuE{$i}{$c};
	    $c++;   
	    $j=0;
	}
	
	@posiciones = sort { $matriuE{$i}{$b} <=> $matriuE{$i}{$a} } keys ( %{$matriuE{$i}} );
	
	$best[$i] = $posiciones[0];
	
	
	$j=0;
	$c=0;
	$i++;
	
    }
####
####
$i=0;

print TXT "#############################################\n";
print TXT "#############################################\n";

 if($w >0){   
    print TXT "Motivos encontrados en la iteracion"," ", $w;
    print TXT "\n";

print TXT "SECUENCIA\t";
print TXT "POSICION\t";
print TXT "SCORE\t";
print TXT "\t";
print TXT "MOTIVO\n";


while($i<$sq){

    if($matriuE{$i}{$best[$i]}>1){



	print TXT"\n";

	print TXT "   ";
	print TXT " $i\t"; 


	print TXT "\t";
	print TXT $best[$i],"\t";
	print TXT "\t";
	printf TXT "%.3f\t", $matriuE{$i}{$best[$i]};
	print TXT "\t";
	print TXT "\t";
	print TXT @{$motiuE{$i}{$best[$i]}},"\n";
	


 }else{
	print TXT "la sequencia $i no tiene este motivo consenso\n";
    }
    $i++;

}

print TXT "\n";
print TXT "\n";
print TXT "\n";





print TXT "Matriz de scores:\n";
print TXT "\n";
$i=0;
$j=0;
$ll=0;

while($i<(scalar(@scorein2))){
    
    print TXT $lletres[$ll]," ";
   
    
    while($j<scalar(@{$scorein2[$i]})){
	

	
	if ($scorein2[$i][$j]!=-9999){
	    print TXT "  ";  
	    printf TXT "%.3f", $scorein2[$i][$j],"   ";
	    
	    print TXT "  ";
	}else{
	    print TXT "  ";	
	    print TXT "-9999  ";
	}      

	$j++;
    }
    print TXT "\n";
    $j=0;
    $i++;
    $ll++;
   
}
    print TXT"\n";


}

####
####
          ###############     calculamos numero de cada nt en los motivos para restarselo al backgroun    ####################
    
    $j=0;
    
    while($j<4){
	
	$total[$j]=0;
	$j++;
    }
    $i=0;
    $j=0;
    while($motiuE{$i}{$best[$i]}){
	while($j<scalar(@{$motiuE{$i}{$best[$i]}})){
	    
	    if($motiuE{$i}{$best[$i]}[$j] eq "A"){
		$total[0]++;
	    }
	    if($motiuE{$i}{$best[$i]}[$j] eq "T"){
		$total[1]++;
	    }
	    if($motiuE{$i}{$best[$i]}[$j] eq "C"){
		$total[2]++;
	    }
	    if($motiuE{$i}{$best[$i]}[$j] eq "G"){
		$total[3]++;
	    }
	    $j++;
	}
	$j=0;
	$i++;
    }
    
    
    
           ##################     normalizamos la matriz con los scores de todos los candidatos     #####################
    
    $i=0;
    $c=0;
    
    while($matriuE{$i}{$c}){
	
	while($matriuE{$i}{$c}){
	    
	    $matriuEnorm[$i][$c] = $matriuE{$i}{$c}/$matriuEtotal[$i];
	    
	    
	    $c++;
	}
	$c=0;
	$i++;
    }
    
############################################################################################################################################################################################         PASO 3 :  M-STEP         ###############################################################################################################################################################################################
    
####  hacemos otra vez matriz de scores, primero guardamos la anterior para poder compararla con la nueva y despues inicializamos la nueva matriz de scores a 0
    
    print "Iniciando paso M. Iteracion: ", $w,"\n";
    
    $i=0;   
    
    while( $i < scalar(@scorein) ){
	$j=0; 
	
	while( $j < scalar(@{ $scorein[$i] }) ){
	    
	    $scorein2[$i][$j] = $scorein[$i][$j];
	    $j++;
	}
	
	$i++;
    }
    
    
    @backc= restav(\@back,@total);
    
    @matriufreq2= media(@backc);
    
            ####################################       hacemos matriz scores       #########################################
    
    $i=0;
    $j=0;
    $c=0;
    
    while($motiuE{$i}){
	
	while($motiuE{$i}{$c}){
	    
	    
	    while($j<scalar(@{$motiuE{$i}{$c}})){
		
		if(uc$motiuE{$i}{$c}[$j]eq "A" ){             
		    
		    
		    $scorein[0][$j] = $scorein[0][$j] + $matriuEnorm[$i][$c];         
		}
		
		if(uc$motiuE{$i}{$c}[$j]eq "T" ){             
		    
		    $scorein[1][$j] = $scorein[1][$j] + $matriuEnorm[$i][$c];  
		    
		}
		
		if(uc$motiuE{$i}{$c}[$j]eq "C" ){             
		    
		    $scorein[2][$j] = $scorein[2][$j] + $matriuEnorm[$i][$c];  
		    
		}
		if(uc$motiuE{$i}{$c}[$j]eq "G" ){             
		    
		    $scorein[3][$j] = $scorein[3][$j] + $matriuEnorm[$i][$c];  
		    
		}
		
		
		
		$j++;
	    }
	    
	    $j=0;
	    $c++;
	    
	}
	$j=0;
	$c=0;
	$i++;
    }
    
   
    
             ####################################    normalizamos scorein        #################################
             #Normalizamos las posiciones


@totalE=();  
$j= 0;

  
while($j < $m){
    
    $totalE[$j] = 0;
    $j++; 

}

    $i=0;
    $j=0;
   
   while( $j < $m){ 
    
    while($i < 4){
	    
	   $totalE[$j]= $totalE[$j] + $scorein[$i][$j];
	    
	    
	    $i++;
	    }
	$j++;
	$i=0;
	
    }


    $i=0;
    $j=0;
    
    
    while($i < 4){
	
	
	
	while( $j < $m){
	    
	    $scorein[$i][$j]= ($scorein[$i][$j])/$totalE[$j];
	    
	    
	    
	    $j++;
	}
	
	$i++; 
	$j=0;
    }
   


         ########################################   log i back         #######################################
    
    $i=0;
    $j=0;
    
    while($i<4){
	
	while($j<$m){
	    
	    $scorein[$i][$j] = $scorein[$i][$j]/ $matriufreq2[$i];
	    
	    if($scorein[$i][$j] > 0){
		
		$scorein [$i][$j]= log2($scorein[$i][$j]);
		
	    }else{
		
		$scorein [$i][$j]= -9999;
	    }
	    
	    $j++;
	}
	
	$j=0;
	$i++;
    }
    @diferencies= ();
    $i=0;
    $j=0;
    
    @diferencies2=();
    
     

    while($i<(scalar(@scorein2))){
	
	while($j<scalar(@{$scorein2[$i]})){
	    
	    if($scorein2[$i][$j] !=-9999  && $scorein[$i][$j] != -9999){

		push @diferencies, abs($scorein2[$i][$j]-$scorein[$i][$j]);
	}
	    $j++;
	}
	$j=0;
	$i++;
    }
   
    $max= -9999;
    $i=0;
    while($i<scalar(@diferencies)){

	if($diferencies[$i]> $max){

	    $max= $diferencies[$i];
	}
	$i++;
    }
  
   

   
    if($max <= $limit ){
	
	$convergencia =1;
	print "Finalizada la busqueda por convergencia en la iteracion $w\n";
	
    }else{
	$convergencia =0;
    }
    

    
    
    $w++;
}
if($convergencia == 0){
print "El programa ha llegado a la iteraci&oacute;n 100";
}
$i=0;

print HTML '<br><br><table align="center" border="2" BGCOLOR=#D3E8FF>';




print TXT "SECUENCIA\t";
print TXT "POSICION\t";
print TXT "SCORE\t";
print TXT "\t";
print TXT "MOTIVO\n";

print HTML '<tr><td><color="990066" BGCOLOR #7CB0FF><b>SECUENCIA</td><td><color="990066" BGCOLOR #7CB0FF><b>POSICI&Oacute;N</td><td><color="990066" BGCOLOR #7CB0FF><b>SCORE</td><td><color="990066" BGCOLOR #7CB0FF><b>MOTIVO</td></tr></b>';
    
    while($i<$sq){
	print HTML '<tr>';
	if($matriuE{$i}{$best[$i]}>1){
	    
	    
	    
	    print TXT"\n";
	    
	    print TXT "   ";
	    print TXT " $i\t"; 
	    
	    
	    print TXT "\t";
	    print TXT $best[$i],"\t";
	    print TXT "\t";
	    printf TXT "%.3f\t", $matriuE{$i}{$best[$i]};
	    print TXT "\t";
	    print TXT "\t";
	    print TXT @{$motiuE{$i}{$best[$i]}},"\n";
	    
	    print HTML '<td>';
	    print HTML $i;
	    print HTML '</td>';
	    
	    print HTML '<td>';
	    print HTML $best[$i];
	    print HTML '</td>';
	    
	    print HTML '<td>';
	    printf HTML "%1.3f\t", $matriuE{$i}{$best[$i]};	
	    print HTML '</td>';
	    
	    print HTML '<td>';
	    print HTML @{$motiuE{$i}{$best[$i]}};
	    print HTML '</td>';
	}else{
	    print TXT "la sequencia $i no tiene este motivo consenso\n";
	}
	$i++;
	print HTML '</tr>';
    }

print TXT "\n";
print TXT "\n";
print TXT "\n";



print HTML '<br></table><hr><br><p><center><font color="990066">Matriz de scores</p></h1><br><p></center></p><br><table align="center" border="2" BGCOLOR=#D3E8FF>';


print TXT "Matriz de scores:\n";
print TXT "\n";
$i=0;
$j=0;
$ll=0;

while($i<(scalar(@scorein))){
    
    print TXT $lletres[$ll]," ";
    print HTML '<tr>';
    print HTML '<td>',$lletres[$ll],'</td>';
    
    while($j<scalar(@{$scorein[$i]})){
	
	
	if ($scorein[$i][$j]!=-9999){
	    print TXT "  ";  
	    printf TXT "%.3f", $scorein[$i][$j],"   ";
	    print TXT "  ";
	    print HTML '<td>';
	    printf HTML "%.3f", $scorein[$i][$j];
	    print HTML '</td>';
	}else{
	    print TXT "  ";	
	    print TXT "-9999  ";
	    
	    print HTML '<td>';
	    printf HTML "-9999", $scorein[$i][$j];
	    print HTML '</td>';
	}      
	
	$j++;
    }
    print TXT "\n";
    $j=0;
    $i++;
    $ll++;
    print HTML '</tr>';
}

print HTML '</table><hr><h3><center>Situacion en la secuencia</center></h3><p>';


$n=0;
$t=0;

$j=0;
$i=0;

while ($matseq[$n][0]){
    print HTML '<p>';
    print HTML '<table><tr>';
    $j=($best[$i]-15);
    print HTML $j, '-';
    print HTML '<td> &nbsp;';
    
    while ($t<15){ 
	
	print HTML '<td>',$matseq[$n][0][$j],'</td>';
	$t++;
	$j++;
    }
    
    $t=0;
    
    print HTML '<td bgcolor="#E679F0">',@{$motiuE{$n}{$best[$n]}},'</td>';
    $j=($best[$i]+15+ scalar $m);
    
    while ($t<15){ 
	
	print HTML '<td>', $matseq[$n][0][$j],'</td>';
	$t++;
	$j++;
    }
    
    $i++;
    $n++;
    $t=0;
    print  HTML '<br>';	   
    print HTML '</tr>';
    print HTML '</table>';
}

 


###########################################################################################################################################################################################          FUNCIONES                ###############################################################################################################################################################################################


    ###################################   funcion  :  resta de variables   ########################################

sub restav {
    my @v1 = @back; 
    my @v2 = @total; 
    
    
    my @resta;
    my $n = scalar(@v1); # los dos vectores tienen el mismo numero de elementos
    my $i;               # enregistra las posiciones que vamos mirando
    
    $i = 0;
    
    while ($i < $n) {
	$resta[$i] = $v1[$i] - $v2[$i];
	
	$i++;
    }
    
    return @resta;
}

####################################    funcion  :  calculo media       ###################################


sub media {
    
    my @media;
    my @v= @_;
    
    
    
    $j=0;
    
    while($j<4){
	
	$media[$j] = $v[$j] / ($v[0] + $v[1] + $v[2] + $v[3]);
	$j++;
    }
    return @media;
}



##########################      funcion  :  calculo de logaritmo en base 2    ################################



sub log2{
    
    my $n =shift;
    
    return log($n)/log(2);
}


