Categorias
Introdução à Programação para Bioinformática com Perl

Estruturas de proteínas

Capítulo 12

Este conteúdo faz parte do livro “Introdução à Programação para Bioinformática com Perl“. Você pode adquirir a versão impressa desse livro aqui ou a versão para Kindle aqui. Para nos citar, consulte este link.

O Protein Data Bank (PDB) é um banco de dados que armazena estruturas tridimensionais de proteínas. O PDB é um banco de dados fundamental nas áreas de biologia estrutural, sendo o alicerce de uma subárea da Bioinformática conhecida como Bioinformática Estrutural.

O PDB é mantido por uma organização internacional chamada Worldwide Protein Data Bank (wwPDB) e pode ser acessado em: <http://www.wwpdb.org/>. A base de dados também pode ser acessada através das organizações PDBe (http://www.pdbe.org), PDBj (http://www.pdbj.org) ou RCSB (http://www.rcsb.org).

O formato de armazenamento PDB é um arquivo textual, o qual cada linha representa um determinado recurso, como por exemplo, linhas iniciadas com ATOM representam átomos específicos de uma proteína. Abaixo vemos como exemplo um fragmento de um arquivo PDB (código de identificação 1BGA).


HEADER    GLYCOSIDASE                04-APR-97   1BGA              
ATOM  1 N  THR A  2  61.990  84.851  70.908  1.00  32.14     N  
ATOM  2 CA THR A  2  62.828  85.531  69.934  1.00  20.14     C  
ATOM  3 C  THR A  2  62.799  85.087  68.476  1.00  17.99     C

Para mais informações acesse a documentação de formatos de arquivos PDB em: <http://www.wwpdb.org/documentation/file-format>.

Exemplo de arquivo PDB (código 1BGA) extraído do site PDBe http://pdbe.org/download/1bga.

Lendo arquivos PDB com BioPerl

BioPerl apresenta o Bio::Structure, que permite a análise de estruturas de proteínas. Esse namespace ainda apresenta os seguintes módulos: Atom (descreve átomos), Chain (descreve cadeias), Entry (descreve entradas inteiras), IO (permite leitura e gravação de arquivos de estruturas), Model (descreve modelos), Residue (descreve resíduos) e StructureI (interface abstrata para acesso para objetos de estrutura).

Através de Bio::Structure::IO é possível ter acesso a uma variedade de informações. No exemplo a seguir, vamos extrair informações do arquivo PDB da proteína 1BGA (arquivo5.txt). 

use Bio::Structure::IO;

my $pdb = Bio::Structure::IO->new(
-file => 'arquivo5.txt',
-format => 'PDB'
);

my $estrutura = $pdb->next_structure;

foreach my $cadeia ($estrutura->get_chains) {

   my $cadeia_id = $cadeia->id;

   foreach my $residuo ($estrutura->get_residues($cadeia)) {

      my $residuo_id = $residuo->id;

      foreach my $atomo ($estrutura->get_atoms($residuo)){

      	my $atomo_id = $atomo->id;
      	print "Cadeia: ".$cadeia_id."\tResiduo: ".$residuo_id."\tAtomo: ".$atomo_id."\n";
      }

   }

}

Ao executar esse script obteremos como resultado uma lista contendo as cadeias, resíduos (representados por um código de três letras seguidas por um número) e átomos.

Cadeia: A       Residuo: THR-2  Atomo: N
Cadeia: A       Residuo: THR-2  Atomo: CA
Cadeia: A       Residuo: THR-2  Atomo: C
Cadeia: A       Residuo: THR-2  Atomo: O
Cadeia: A       Residuo: THR-2  Atomo: CB
Cadeia: A       Residuo: THR-2  Atomo: OG1
Cadeia: A       Residuo: THR-2  Atomo: CG2

Agora vamos tentar entender o que foi feito no script:

(i) Inicialmente declaramos o módulo Bio::Structure::IO, e que uma nova estrutura, obtida no “arquivo5.txt”, seria armazenada em um objeto na variável $pdb.
(ii) A seguir aplicamos o método next_structure à variável $pdb para obter a estrutura completa da proteína. Ob-serve que com a estrutura podemos ter acesso a todos os elementos de uma proteína, como cadeias, resíduos e átomos, entretanto teremos que realizar três laços de repetição para obtê-los, uma vez que átomos estão presentes em resíduos e resíduos estão presentes em cadeias.
(iii) Utilizamos o método get_chain para obter todas as ca-deias e as percorremos com o comando foreach. Den-tro desse laço, obtemos o id da cadeia e aplicamos um novo laço para percorrer todos os resíduos.
(iv) O método get_residues, que recebe como argumento o objeto com informações de uma cadeia, permite que todos os resíduos dessa cadeia sejam analisados. Den-tro do laço de repetição que recebe cada resíduo, inse-rimos um comando para receber o id do resíduo atual e executamos um novo laço para conhecer todos os átomos.
(v) O último laço de repetição chama o método get_atoms e recebe o objeto de um resíduo. Nesse laço, obtemos o id do átomo e, por fim, imprimimos cadeia, resíduo e átomo atuais separados por uma tabulação.

Extraindo a estrutura primária

Como visto anteriormente ao imprimir o id de um resíduo, BioPerl retorna o resíduo em um código de três letras seguido da numeração do resíduo separada por um hífen. Entretanto, em alguns momentos podemos precisar da estrutura primária de uma proteína. No exemplo a seguir, vamos extrair a sequência da proteína 1BGA, a qual cada resíduo será representado por um código de uma letra, e a imprimir em formato FASTA.

use Bio::Structure::IO;

# Sub-rotina que converte de 3 letras para 1
sub converte_uma_letra{

	my $aa = lc $_[0];
	$aa = substr($aa,0,3);
	my %ONECODE =
    ('ala' => 'A', 'asx' => 'B', 'cys' => 'C', 'asp' => 'D',
     'glu' => 'E', 'phe' => 'F', 'gly' => 'G', 'his' => 'H',
     'ile' => 'I', 'lys' => 'K', 'leu' => 'L', 'met' => 'M',
     'asn' => 'N', 'pro' => 'P', 'gln' => 'Q', 'arg' => 'R',
     'ser' => 'S', 'thr' => 'T', 'val' => 'V', 'trp' => 'W',
     'xaa' => 'X', 'tyr' => 'Y', 'glx' => 'Z', 'ter' => '*',
     'sec' => 'U', 'pyl' => 'O', 'xle' => 'J'
     );
	return $ONECODE{$aa};

}

# Abre o arquivo PDB
my $pdb = Bio::Structure::IO->new(
-file => 'arquivo5.txt',
-format => 'PDB'
);

my $estrutura = $pdb->next_structure;

foreach my $cadeia ($estrutura->get_chains) {

    my $cadeia_id = $cadeia->id;
    print ">cadeia_$cadeia_id\n"; # imprime o cabeçalho

    foreach my $residuo ($estrutura->get_residues($cadeia)) {
    	my $residuo_id = $residuo->id;
    	my $uma_letra = converte_uma_letra($residuo_id);
    	print $uma_letra;
    }

    print "\n";

}

Observe que para realizar a conversão, criamos uma sub-rotina chamada converte_uma_letra. Essa sub-rotina contém uma hash chamada %ONECODE, que contém os códigos de três letras como chaves e os códigos de uma letra como valores (retiramos essa hash do método BEGIN do módulo Bio::SeqUtils). Nossa sub-rotina ainda retira os três primeiros caracteres da string enviada e os converte em minúsculo. Por fim, ela retorna o código de uma letra, armazenado na chave idêntica a string enviada na chamada da função.

Ao executar o script você obterá o seguinte resultado:

>cadeia_A
TIFQFPQDFMWGTATAAYQIEGAYQEDGRGLSIWDTFAHTPGKVFNGDNG
NVACDSYHRYEEDIRLMKELGIRTYRFSVSWPRIFPNGDGEVNQEGLDYY
HRVVDLLNDNGIEPFCTLYHWDLPQALQDAGGWGNRRTIQAFVQFAETMF
REFHGKIQHWLTFNEPWCIAFLSNMLGVHAPGLTNLQTAIDVGHHLLVAH
GLSVRRFRELGTSGQIGIAPNVSWAVPYSTSEEDKAACARTISLHSDWFL
QPIYQGSYPQFLVDWFAEQGATVPIQDGDMDIIGEPIDMIGINYYSMSVN
RFNPEAGFLQSEEINMGLPVTDIGWPVESRGLYEVLHYLQKYGNIDIYIT
ENGACINDEVVNGKVQDDRRISYMQQHLVQVHRTIHDGLHVKGYMAWSLL
DNFEWAEGYNMRFGMIHVDFRTQVRTPKESYYWYRNVVSNNWLETRR
[...]

Obtendo coordenadas de átomos

O módulo Bio::Structure ainda permite a obtenção das coordenadas de átomos de um arquivo PDB. Como exemplo, vamos extrair as coordenadas de átomos de todos os resíduos.

use Bio::Structure::IO;

my $pdb = Bio::Structure::IO->new(
-file => 'arquivo5.txt',
-format => 'PDB'
);

my $estrutura = $pdb->next_structure;

foreach my $cadeia ($estrutura->get_chains) {

   my $cadeia_id = $cadeia->id;

   foreach my $residuo ($estrutura->get_residues($cadeia)) {

      my $residuo_id = $residuo->id;

      foreach my $atomo ($estrutura->get_atoms($residuo)){

      	my $atomo_id = $atomo->id;
      	my @atomo_xyz = $atomo->xyz;      	
      	print " | Residuo: ".$residuo_id;
      	print " | x = ".$atomo_xyz[0];
      	print " | y = ".$atomo_xyz[1];
      	print " | z = ".$atomo_xyz[2];
      	print " | Atomo: ".$atomo_id."\n";

      }

   }

}

O método xyz retorna as coordenadas tridimensionais de um átomo como um array. Podemos obter as posições individualmente chamando os métodos x, y ou z.

| Residuo: THR-2 | x = 61.990 | y = 84.851 | z = 70.908 | Atomo: N
 | Residuo: THR-2 | x = 62.828 | y = 85.531 | z = 69.934 | Atomo: CA
 | Residuo: THR-2 | x = 62.799 | y = 85.087 | z = 68.476 | Atomo: C
 | Residuo: THR-2 | x = 62.825 | y = 83.895 | z = 68.164 | Atomo: O
 | Residuo: THR-2 | x = 64.279 | y = 85.578 | z = 70.437 | Atomo: CB
 | Residuo: THR-2 | x = 64.266 | y = 85.699 | z = 71.855 | Atomo: OG1
 | Residuo: THR-2 | x = 65.017 | y = 86.785 | z = 69.894 | Atomo: CG2

Podemos ainda utilizar as coordenadas do carbono alfa para representar a posição de um resíduo. Para isso é necessário validar a variável que armazena o id do átomo. Carbonos alfa são representados pelos caracteres “CA”.

Medindo a distância entre dois átomos

Medir a distância entre átomos pode ser importante para diversas tarefas em Bioinformática Estrutural, como por exemplo, o cálculo de contatos. Para isso, precisaremos extrair as coordenadas geográficas do átomo no espaço (X, Y e Z) e calcular a distância euclidiana entre eles.

A seguir, aprenderemos a calcular a distância entre carbonos alfa de dois diferentes resíduos. A distância entre dois átomos é dada em ångström (Å). Um ångström equivale a dez elevado a menos dez metros, ou seja, 1 Å = 0,0000000001 m.

Enquanto Python fornece um método simples para cálculo, em Perl devemos implementar manualmente o cálculo. Primeiro vamos nos lembrar da fórmula para calcular a distância euclidiana entre dois pontos em um espaço tridimensional:

d=√((x1-x2)^2+(y1-y2)^2+(z1-z2)^2 )

A distância entre dois pontos é igual a raiz quadrada da soma da diferença das posições x, y e z dos dois pontos. Aprendemos nos primeiros capítulos que para elevar um número ao quadrado devemos utilizar “**2”. Entretanto para calcular a raiz quadrada devemos utilizar a função sqrt.

No script abaixo, primeiramente vamos extrair as posições x, y e z de cada um dos dois átomos (declarados no começo do script). A seguir, vamos calcular a distância euclidiana entre eles.

use Bio::Structure::IO;

use strict;

my %atomo1 = (
"cadeia" => "A", 
residuo => 'THR-2', 
atomo => 'CA'
);

my %atomo2 = (
"cadeia" => "A", 
residuo => 'ILE-3', 
atomo => 'CA'
);

my @atomo1_xyz;
my @atomo2_xyz;

my $pdb = Bio::Structure::IO->new(
-file => 'arquivo5.txt',
-format => 'PDB'
);

my $estrutura = $pdb->next_structure;

foreach my $cadeia ($estrutura->get_chains) {

   my $cadeia_id = $cadeia->id;

   foreach my $residuo ($estrutura->get_residues($cadeia)) {

      my $residuo_id = $residuo->id;

      foreach my $atomo ($estrutura->get_atoms($residuo)){

      	my $atomo_id = $atomo->id;
      	# Comparacoes
      	if(($cadeia_id eq $atomo1{cadeia})and
($residuo_id eq $atomo1{residuo})and
($atomo_id eq 'CA')){
      		@atomo1_xyz = $atomo->xyz; 	
      	}
      	elsif(($cadeia_id eq $atomo2{cadeia})and
($residuo_id eq $atomo2{residuo})and
($atomo_id eq 'CA')){
      		@atomo2_xyz = $atomo->xyz; 
      	}

      }

   }

}

my $distancia = sqrt( 
($atomo2_xyz[0] - $atomo1_xyz[0])**2 + 
($atomo2_xyz[1] - $atomo1_xyz[1])**2 + 
($atomo2_xyz[2] - $atomo1_xyz[2])**2 
);

print $distancia;
#3.80040958318968

Como exercício tente calcular a distância de todos os átomos para todos os átomos e salve o resultado em um arquivo de texto.

Quer aprender mais? Conheça nossos cursos profissionalizantes à partir de R$19,99:

Nota do autor
Prefácio

Capítulo 1
Introdução ao Perl

Capítulo 2
Comandos condicionais

Capítulo 3
Strings

Capítulo 4
Arrays

Capítulo 5
Laços de repetição

Capítulo 6
Manipulando arquivos

Capítulo 7
Sub-rotinas

Capítulo 8
“O guia de sobrevivência para expressões regulares em Perl”

Capítulo 9
Introdução ao BioPerl

Capítulo 10
Sequências

Capítulo 11
BLAST

Capítulo 12
Estruturas de proteínas

Capítulo 13
Hierarquia do BioPerl

Epílogo
Referências bibliográficas
Sobre os autores

Por favor, nos cite:

MARIANO, DIEGO CÉSAR BATISTA; de MELO-MINARDI, R. C. . Introdução à Programação para Bioinformática com Perl. 1. ed. North Charleston, SC (EUA): CreateSpace Independent Publishing Platform, 2016. v. 2. 200p .

Por Diego Mariano

Doutor em Bioinformática pela Universidade Federal de Minas Gerais com atuação na área de ciência de dados e aprendizado de máquina aplicados ao aperfeiçoamento de enzimas usadas na produção de biocombustíveis. Mestre em Bioinformática, também pela UFMG, atuando na área de desenvolvimento de sistemas Web para montagem de genomas. Atualmente realiza estágio pós-doutoral no Departamento de Ciência da Computação da UFMG com foco em desenvolvimento de sistemas Web para Bioinformática, análise exploratória e visualização de dados. Tem conhecimentos nas linguagens: PHP, JavaScript, Python, R, Perl, HTML, CSS e SQL.