Programa:
#!/usr/bin/perl -w
use strict;
my $entrada;
my $nom;
my $comptar;
my $num;
my $i;
my @claus;
my @factors;
my $factors;
my $f;
my %matriu;
my $p;
my @total;
my $suma;
my $x;
my $s;
$f = 0;
$s = 0;
$suma =0;
my @sequencia;
my @linia;
my $linia;
my $n;
my $A = 0;
my $C = 0;
my $G = 0;
my $T = 0;
my $N;
my $y=0;
my @logs;
my $k;
my $l;
my $m;
my $g;
my $d;
my $z;
my @lloc;
my $max;
my $imax;
my $fmax;
my @v;
my $c;
my $j;
my $b;
my $tmp;
my $maxrandom;
my $w;
my $cops;
my $pvalue;
my $majuscules;
open (FITXER,"< $ARGV[1]"); #obtindrem la seqüència promotora del gen que volem estudiar
while (){
$linia = $_;
chomp($linia);
if ($linia =~m/([ACGTacgt]*)/){
@linia = split(//,$1);
push(@sequencia,@linia); #@sequencia serà un vector amb tota la seqüència promotora del gen
}
}
close (FITXER);
$N = scalar(@sequencia);
$majuscules = 0;
while ($majuscules < $N){ #fem això per tal que el programa ens canviï totes les minúscules per majúscules del promotor
if ($sequencia[$majuscules] eq "a"){
$sequencia[$majuscules] = "A";
}
if ($sequencia[$majuscules] eq "c"){
$sequencia[$majuscules] = "C";
}
if ($sequencia[$majuscules] eq "g"){
$sequencia[$majuscules] = "G";
}
if ($sequencia[$majuscules] eq "t"){
$sequencia[$majuscules] = "T";
}
$majuscules = $majuscules + 1;
}
@v = @sequencia; #el vector @v ens servirà per randomitzar la seqüència promotora, sense perdre aquesta seqüència
foreach $n (@sequencia){ #el que fem amb aquest foreach, és calcular el nombre d'ocurrències de cada nucleòtid
if ($n eq "A"){
$A = $A + 1;
}
elsif ($n eq "C"){
$C = $C + 1;
}
elsif ($n eq "G"){
$G = $G + 1;
}
elsif ($n eq "T"){
$T = $T + 1;
}
}
$A = log($A/$N)/log 10; #per fer el logaritme en base 10 de la freqüència relativa del nucleòtid en la seqüència promotora
$C = log($C/$N)/log 10;
$G = log($G/$N)/log 10;
$T = log($T/$N)/log 10;
@logs=($A,$C,$G,$T);
open (MATRIUS,"< $ARGV[0]");
while (){
$entrada = $_;
chomp ($entrada);
if ($entrada =~m/FA\s+(.+)\s+.\w./){ #agafarem tots els noms dels factors de transcripció
$nom=$1;
print "\nResultats obtinguts pel factor $nom:\n";
$factors[$f] = $nom;
$f = $f + 1;
$factors = scalar(@factors);
$comptar = 0;
}
elsif ($entrada =~m/(\/+)/ && $f != 0){
if ($entrada =~m/(\/+)\s+\w+/){ #per distingir entre canvis de matriu i el final de l'arxiu
print "\n\nFi de l'arxiu\n";
}
else {
$num = keys(%matriu);
@claus = keys(%matriu);
$i = 0;
while ($i < $num){
#print "\n$claus[$i]\t"; per imprimir les claus de la matriu de pesos
$p = 0;
while ($p < $comptar){
# print "$matriu{$claus[$i]}->[$p]\t"; #per imprimir la matriu de pesos
$p = $p + 1;
}
$i = $i + 1;
}
print "\n";
$k = 0; #inici del vector que conté la possible posició d'unió del FT
$max = -99999;
$m = 0; #final del vector que conté la possible posició d'unió del FT
$g = $N - 1; # últim nucleòtid que formarà part d'un lloc d'unió del FT
$l = $comptar; #llargada del FT
while ($m < $g){ #mentre l'últim nucleòtid no entre al vector del posible lloc d'unió del FT
$m = $k + $l - 1; #valor de l'última posició del nucleòtid en la seqüència total
@lloc = @sequencia[$k..$m]; #@lloc serà el vector que contindrà la possible posició d'unió del FT
#print "@lloc\n"; si vols veure tots els possibles llocs on es pot unir
my $v = 0; #posició de cada nucleòtid dins del possible lloc d'unió del FT
$d = 0; #ens anirà sumant els valors de la matriu de pesos (ens donarà l'score)
while ($v < $l){ #mentre la posició del nucleòtid del FT no sigue l'última
$z = $matriu{$lloc[$v]}->[$v]; #$z agafa el pes del nucleòtid de la posició $v del vector @lloc,
#print "valor $z\n"; només si volem veure els valors de la matriu de pesos
$d = $d + $z; #$d va sumant els pesos fins obtenir l'score
$v = $v + 1; #per avançar un lloc dins el vector @lloc
}
#print "suma $d \ $max\n"; si vols veure tots els scores
if ($d > $max){
$max = $d;
$imax = $k;
$fmax = $m;
}
$k = $k + 1;
}
$max = sprintf("%.4f",$max); #sprintf serveix per arrodonir a 4 decimals, el valor de score
print "L'score màxim és $max i el dóna la unió del FT a la seqüència ",@sequencia[$imax..$fmax]," situada entre els nucleòtids ",$imax+1," i ",$fmax+1,"\n";
#============================= PUNT 4 =================================================================================
$w = 0;
$cops = 0;
while ($w < 100) {
$b = $N -1;
while ($b >= 0){
$j = int(rand($b+1));
if ($i != $j){
$tmp = $v[$b];
$v[$b] = $v[$j];
$v[$j] = $tmp;
}
$b = $b - 1;
}
# print "seqüència random @v\n";
$k = 0; #inici del vector que conté la possible posició d'unió del FT
$maxrandom = -99999;
$m = 0; #final del vector que conté la possible posició d'unió del FT
$g = $N - 1; # últim nucleòtid que formarà part d'un lloc d'unió del FT
$l = $comptar; #llargada del FT
while ($m < $g){ #mentre l'últim nucleòtid no entre al vector del posible lloc d'unió del FT
$m = $k + $l - 1; #valor de l'última posició del nucleòtid en la seqüència total
@lloc = @v[$k..$m]; #@lloc serà el vector que contindrà la possible posició d'unió del FT
# print "@lloc\n"; #si vols veure tots els possibles llocs on es pot unir
my $v = 0; #posició de cada nucleòtid dins del possible lloc d'unió del FT
$d = 0; #ens anirà sumant els valors de la matriu de pesos (ens donarà l'score)
while ($v < $l){ #mentre la posició del nucleòtid del FT no sigue l'última
$z = $matriu{$lloc[$v]}->[$v]; #$z agafa el pes del nucleòtid de la posició $v del vector @lloc,
#print "valor $z\n"; només si volem veure els valors de la matriu de pesos
$d = $d + $z; #$d va sumant els pesos fins obtenir l'score
$v = $v + 1; #per avançar un lloc dins el vector @lloc
# print "$d\n";
}
#print "suma $d \t $maxrandom \t $max\n"; #si vols veure tots els scores
if ($d > $maxrandom){
$maxrandom = $d;
}
$k = $k + 1;
}
if ($maxrandom >= $max){
$cops = $cops + 1;
}
$w = $w +1;
} #tanca el while de les 100 vegades
$pvalue = $cops/100;
print "El p-value associat és $pvalue\n";
#=====================================================FI PUNT 4 ========================================================
}
}
elsif ($entrada =~m/\d+\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/){ #per crear la matriu de freqüències absolutes
@total = ($1,$2,$3,$4);
while ($s < 4){
$suma = $suma + $total[$s];
$s = $s + 1;
}
$s = 0;
while ($y < 4){
if ($total[$y] == 0){
$total[$y] = -999; #per evitar per logaritme d'un número negatiu
}
else{
$total[$y]=((log($total[$y]/$suma))/log 10) - ($logs[$y]); #per fer la matriu de pesos
}
$y = $y +1;
}
$y = 0;
$matriu{A}->[$comptar]=$total[0]; #anem ficant cada valor absolut al hash de vectors
$matriu{C}->[$comptar]=$total[1];
$matriu{G}->[$comptar]=$total[2];
$matriu{T}->[$comptar]=$total[3];
$comptar = $comptar + 1;
$suma = 0;
}
}
print "\n";
close (MATRIUS);