#!/usr/bin/perl -w use strict; ####################### PREDICCIO D'EXONS: PREDICTOR #################### # AUTORES: Ana Moreno, Roser Zaurin # DATA: 2 abril 2003 # CURS: 4art # ESTUDIS: Biologia Humana, Facultat de Ciencies de la Salut i de la Vida ######################################################################### # OBJECTIU: Prediccio dels possibles exons dins d'una sequencia d'ADN # donada en format FASTA, mostrant, en un document de sortida en format # GFF, la posicio de donnors i acceptors sites que limiten l'exo; la # puntuacio tenint en compte el biaix codificant; i la pauta de lectura # utilitzada. ####################### PRE-TRACTAMENT DE DADES ######################### # si el nombre d'arguments al programa es mes petit que 4 # el programa no es pot executar perque no te tots els fitxers # que necessita if (scalar(@ARGV) < 6) { print "predictor.pl sequencia matriu_d_donnors matriu_d_acceptors proporcionscodons llindar largada_min_exo\n"; exit(1); } # assignem els noms del vector d'arguments a variables # amb noms mes significatius my $fitxerseq = $ARGV[0]; my $matriu_d = $ARGV[1]; my $matriu_a = $ARGV[2]; my $fitxercod = $ARGV[3]; my $llindar = $ARGV[4]; my $llargada_min_exo = $ARGV[5]; # obrim el fitxer especificat al quart argument, que es on hi # ha les proporcions de cada codo en regio codificant, passat al # programa des del shell if (!open(PROPORCIONSCODONS,"< $fitxercod")) { print "predictor.pl: impossible obrir $fitxercod\n"; exit(1); } # llegim les proporcions de codons del fitxer i les enregistrem # al hash %proporcions_codons my %proporcions_codons; while () { # a la variable anonima tenim la linia llegida i l'encaixem amb # la seguent expressio regular m/(\w+) (\d+\.\d+)/; # l'expressio regular anterior encaixa amb dues paraules la primera # de les quals es alfabetica i la segona un numero amb decimals. # les dues paraules estan agrupades amb parentesis lo qual significa # que ens podem referir a la primera com $1 i a la segona com $2 $proporcions_codons{$1}=$2; } close(PROPORCIONSCODONS); # obrim el fitxer especificat al segon argument, on hi ha la # sequencia problema, passat al programa des del shell if (!open(SEQUENCIA,"< $fitxerseq")) { print "predictor.pl: impossible obrir $fitxerseq\n"; exit(1); } # el fitxer amb la sequencia esta en format FASTA. aixo implica que te # una primera linia amb el simbol '>' seguit d'un identificador, i despres # segueix un seguit de linies amb differents trossos de la sequencia my $iden = ; # llegim la primera linia del format FASTA ">XXXX" my @seql = ; # llegim les linies de la sequencia my $seq = ""; # declarem una variable on anira a parar tota la # sequencia seguida, i la inicialitzem amb la # paraula buida close(SEQUENCIA); # en la variable $seq posarem la sequencia sencera. aixo ho farem enganxant # els trossos de sequencia que tenim a cada posicio del vector @seql my $i=0; while ($i < scalar(@seql)) { chomp($seql[$i]); $seq = $seq . $seql[$i]; $i = $i + 1; } my $seq0 = "\U$seq"; # definim la mateixa variable per les altres dues pautes de lectura my $seq1=substr ($seq0, 1); my $seq2=substr ($seq1, 1); ##################### FI PRETRACTAMENT DE DADES ############################### #cridem la funcio per calcular stops my @matriu0 = &calcula_stops($seq0); my @matriu1 = &calcula_stops($seq1); my @matriu2 = &calcula_stops($seq2); #cridem la funcio que ens llegeix les matrius de donors i acceptors #per poder executar les dues funcions seguents my %matriu_1= &llegeix_matriu_pesos($matriu_d); my %matriu_2= &llegeix_matriu_pesos($matriu_a); #cridem una funcio que ens busca la posicio dels donors i els acceptors #i ho posem en dues matrius de dues dimensions i tres columnes -orf, #posicions donors/acceptors, puntuacio de cada donor/acceptor- my @matriu_puntuacio_donnors_0 = &calcula_donor_acceptor(\%matriu_1,\@matriu0,$llindar); my @matriu_puntuacio_donnors_1 = &calcula_donor_acceptor(\%matriu_1,\@matriu1,$llindar); my @matriu_puntuacio_donnors_2 = &calcula_donor_acceptor(\%matriu_1,\@matriu2,$llindar); my @matriu_puntuacio_acceptors_0 = &calcula_donor_acceptor(\%matriu_2,\@matriu0,$llindar); my @matriu_puntuacio_acceptors_1 = &calcula_donor_acceptor(\%matriu_2,\@matriu1,$llindar); my @matriu_puntuacio_acceptors_2 = &calcula_donor_acceptor(\%matriu_2,\@matriu2,$llindar); #afegim una columna que sera el frame @matriu_puntuacio_acceptors_0 = &calcula_frame(\@matriu_puntuacio_acceptors_0,\@matriu0); @matriu_puntuacio_acceptors_1 = &calcula_frame(\@matriu_puntuacio_acceptors_1,\@matriu1); @matriu_puntuacio_acceptors_2 = &calcula_frame(\@matriu_puntuacio_acceptors_2,\@matriu2); #cridem la funcio que ens faci totes les combinacions possibles en cada #orf entre donor i acceptor sites per aixi construir tots els exons #putatius my @donnor_acc_0 = &combi(\@matriu_puntuacio_donnors_0, \@matriu_puntuacio_acceptors_0,\@matriu0); my @donnor_acc_1 = &combi(\@matriu_puntuacio_donnors_1, \@matriu_puntuacio_acceptors_1,\@matriu1); my @donnor_acc_2 = &combi(\@matriu_puntuacio_donnors_2, \@matriu_puntuacio_acceptors_2,\@matriu2); #corretgim les posicions absolutes i relatives de les pautes 1 i 2 sumant #un i dos nucleotids respectivament my $da; for($da=0; $da ${$b}[3]}(@matriu_final); #print!!!! my $g; chomp ($iden); print "Resultados del análisis de la secuencia con identificador $iden:\n"; print "\n"; for ($g=0; $g=$ARGV[5]){ #per establir el #tamany minim de l'exo print "predictor\t$matriu_final[$g][8]\t$matriu_final[$g][3]\t$matriu_final[$g][4]\t"; printf "\t%.3f",$matriu_final[$g][6]; print "\t\t+\t$matriu_final[$g][7]\n"; } } ####################################################################### ####################################################################### ####################### FUNCIONS ################################## ####################################################################### ####################################################################### # NOM: calcula_stops # PROPOSIT: aquesta funcio ens busca els codons stop -TAA, TGA o TAG- # # PARAMETRES: primer - vector codons on tenim la sequencia sencera i ens # la llegeix de tres en tres nucleotids # RETORNA: el resultat s'enregistra en un matriu on la primera columna # son els marcs de lectura oberts i la segona la posicio absoluta # de l'stop que el limita sub calcula_stops { my $sequencia=$_[0]; #sequencia sencera on volem trobar els orfs my $iorfs=0; #numero d'orf my $posicio_codo=0; #numero de codo en cada orf my @codons = ($sequencia=~m/.../g); #dividim la seq en codons my $resultat = ""; #l'inicialitzem amb la paraula buida my @orfs; #vector de sortida amb tots els orfs while ($posicio_codo < scalar(@codons) ) { #busquem els codons stop que poden ser tres-TAA, TAG, TGA- if ($codons[$posicio_codo] ne "TAA" && $codons[$posicio_codo] ne "TGA" && $codons[$posicio_codo] ne "TAG") { $resultat=$resultat.$codons[$posicio_codo]; } else { $resultat=$resultat.$codons[$posicio_codo]; $orfs[$iorfs][0]=$resultat; $orfs[$iorfs][1]=$posicio_codo*3+3; $iorfs=$iorfs+1; $resultat=""; } $posicio_codo=$posicio_codo+1; } return @orfs; } #NOM: llegeix_matriu #PROPOSIT: aconseguir passar per totes les posicions de la matriu, # llegeix la matriu #PARAMETRES: nom del fitxer de matriu de pesos (de donnors o d'acceptors # respectivament) #RETORNA: un hash de vectors on les claus son els nucleotids A, C, T, # G i un vector amb els pesos de cada lletra a les diferents # posicions de la sequencia sub llegeix_matriu_pesos { my $nom_fitxer_matriu_pesos=$_[0]; my %matriu_pesos; if (!open(MATRIU_DA,"<$nom_fitxer_matriu_pesos")) { print "predictor.pl: impossible obrir $nom_fitxer_matriu_pesos\n"; exit (1); } my $nucleotids; my @nucleotids; my $llegir_matriu=0; my $linies=0; my $posicio; while () { if ($llegir_matriu==0 && m/\AP0\s+(\w+)\s+(\w+)\s+(\w+)\s+(\w+)/) { $nucleotids[0] = $1; $nucleotids[1] = $2; $nucleotids[2] = $3; $nucleotids[3] = $4; $llegir_matriu = 1; } if ($llegir_matriu == 1 && m/\A\d+\s+([\-\d\.]+)\s+([\-\d\.]+)\s+([\-\d\.]+)\s+([\-\d\.]+)/) { $matriu_pesos{$nucleotids[0]}[$linies]=$1; $matriu_pesos{$nucleotids[1]}[$linies]=$2; $matriu_pesos{$nucleotids[2]}[$linies]=$3; $matriu_pesos{$nucleotids[3]}[$linies]=$4; $linies = $linies + 1; } if ($llegir_matriu == 1 && m/\AXX\s+(\d+)/) { $matriu_pesos{punt_de_tall} = $1; $llegir_matriu = 0; } } close (MATRIU_DA); return %matriu_pesos; } #NOM: calcula_donor_acceptor #PROPOSIT: calcular la posicio i puntuacio de donnors i accepors #PARAMETRES: primer:matriu de pesos de donnors o d'acceptors # segon:matriu que compta els diferents orfs i la posicio # absoluta d'on acaben els STOPS #RETORNA: una matriu amb tres columnes:orf; posicio del donnor/acceptor; # pes del donnor/acceptor sub calcula_donor_acceptor { my %matriu_calcula = %{$_[0]}; #matriu de pesos my @matriu_alafuncio= @{$_[1]}; #matriu amb cada orf trobat i #posicio absoluta de cada stop my $llindar =$_[2]; #llindar my $llargada_finestra=scalar(@{$matriu_calcula{A}}); my $i; #em serveix per desplacar la finestra my $line=0; #desplaca la linia de la matriu de sortida on #guardo el resultat my $iorfs=0; #numero d'orfs my $nt_finestra; #subsequencia de nucleotids-->una finestra my @donor_acceptor_putative; my @matriu_puntuacio; #definim una finestra; i definim un vector on posarem totes les finestres #possibles, on cada posicio d'aquest vector sera un nucleotid while ($iorfs < scalar(@matriu_alafuncio)) { $i=0; while ($i < length($matriu_alafuncio[$iorfs][0])-$llargada_finestra) { $nt_finestra=substr($matriu_alafuncio[$iorfs][0], $i, $llargada_finestra); @donor_acceptor_putative=split(//,$nt_finestra); my $h; #recorrem els nucleotids dins d'un mateix parell #donnor-acceptor my $r=0; #pes de cada nucleotid en la finestra on treballem for ($h=0; $h < $llargada_finestra; $h++) { $r=$r+$matriu_calcula{$donor_acceptor_putative[$h]}[$h]; } if ($r > $llindar) { $matriu_puntuacio[$line][0]=$iorfs; $matriu_puntuacio[$line][1]=$i + $matriu_calcula{punt_de_tall}-1; $matriu_puntuacio[$line][2]=$r; $line=$line+1; } $i=$i+1; $r=0; } $iorfs=$iorfs + 1; } return @matriu_puntuacio; } #NOM: calcula_frame #PROPOSIT: calcular el frame real al que pertenyen els exons que predim #PARAMETRES: primer: matriu de puntuacio d'acceptors que hem construit anteriorment # segon: matriu on tenim els orfs i la posicio absoluta d'on acaben els STOPS # #RETORNA: la matriu de puntuacio d'acceptors pero amb una columna mes (el frame) sub calcula_frame{ my @matriu_puntuacio_acceptors = @{$_[0]}; my @matriu = @{$_[1]}; my $w; for ($w=0; $w