• Nenhum resultado encontrado

ESTUDO DA FERRAMENTA SOAPDENOVO-TRANS PARA MONTAGEM DE FRAGMENTOS EM BIOINFORMÁTICA

N/A
N/A
Protected

Academic year: 2021

Share "ESTUDO DA FERRAMENTA SOAPDENOVO-TRANS PARA MONTAGEM DE FRAGMENTOS EM BIOINFORMÁTICA"

Copied!
8
0
0

Texto

(1)

ESTUDO DA FERRAMENTA SOAPDENOVO-TRANS PARA

MONTAGEM DE FRAGMENTOS EM BIOINFORMÁTICA

Aluna: Tatiana de Oliveira Magdalena Orientador: Sérgio Lifschitz

Introdução

A bioinformática é uma área da ciência que se utiliza de técnicas da informática para resolução de problemas em biologia, como por exemplo, gerar e gerenciar dados biológicos

[1]. Neste contexto encontra-se o sequenciamento genético e a montagem de fragmentos

sequenciados. Trata-se de um processo que determina a ordem dos nucleotídeos em um genoma, podendo-se utilizar para isto diversos algoritmos computacionais e suas implementações disponíveis publicamente.

Este trabalho é parte de uma colaboração de pesquisa realizada com o Instituto de Bioquímica Médica da Universidade Federal do Rio de Janeiro (UFRJ). Dentre outras atividades, eles estudam o genoma da cana-de-açúcar e um grupo de alunos de doutorado e mestrado do laboratório BioBD do Departamento de Informática da PUC-Rio vem atuando no apoio e suporte das execuções de programas e demais softwares especializados. Este genoma da cana-de-açúcar apresenta um desafio considerável, uma vez que é muito maior que o genoma humano. Entre outras consequências, requer muita memória para sua montagem.

Dentre os programas comumente utilizados para montagem temos o SOAPdenovo-Trans [2], utilizado para montagem de transcriptomas, objeto de estudo desta pesquisa em particular. Foi identificado que este programa implementa um algoritmo com um consumo excessivo de memória, o que na maioria das vezes impossibilita sua execução em máquinas ditas convencionais. Nesta pesquisa foi feito um estudo detalhado do código-fonte utilizado nesta implementação particular de SOAPdenovo-Trans disponibilizada em código aberto.

Objetivos

Estudar em detalhes o código computacional utilizado no montador de transcriptoma SOAPdenovo-Trans, identificando as etapas de maior consumo de memória e analisando os prováveis motivos para isso. Documentar este código, identificando as funcionalidades de cada etapa e como as partes do código interagem.

Método de montagem no estilo de novo

Primeiramente, foi feito um estudo sobre o sequenciamento genético e a montagem do genoma de forma geral. Com as ferramentas atuais, não é possível ler uma sequência de DNA ou de RNA completa do início ao fim: o que se faz é a leitura de fragmentos deste DNA ou RNA, através de máquinas de sequenciamento automático, ou sequenciadores. Porém, ao fazer esta leitura, não é possível identificar a priori a que parte do DNA ou RNA este fragmento pertence, nem ao menos se dois fragmentos pertencem a uma mesma molécula de DNA ou RNA ou não. Este método de sequenciamento, em que se junta um grande número de pequenas sequências para criar uma representação do cromossoma original é chamado de

shotgun.

A montagem pode ser feita com um genoma de referência quando este está disponível. Porém essa referência nem sempre está disponível, principalmente para genomas grandes e poliploides [3], como é o caso do genoma da cana-de-açúcar. Para essas situações, há a opção

(2)

do método de montagem estilo de novo. Muitos dos algoritmos utilizados com este método se utilizam de um grafo para auxiliar a montagem, chamado de grafo de De Bruijn.

O grafo de De Bruijn é um grafo direcionado que representa sobreposições entre sequências de símbolos. Um ponto importante consiste no fato de que, para montar este grafo, é necessário quebrar as sequências lidas em sequências de DNA menores, chamadas de K-mers, onde "K" é o tamanho estabelecido para a quebra, o que já indica um aumento considerável de dados a serem manipulados [4]. Uma sequência lida com N > K bases nitrogenadas resultaria em ((N - K) + 1)*K bases nitrogenadas. A partir dos K-mers obtidos, mapeia-se sobreposições de comprimento (K - 1) entre esses K-mers. Cada K-mer é então um nó do grafo conectado por arestas se há esta sobreposição de (K - 1) bases nitrogenadas.

O SOAPdenovo-trans é um algoritmo de montagem de transcriptomas do tipo de novo baseado em grafo de De Bruijn, derivado de seu algoritmo de montagem de genomas SOAPdenovo2 [3].

Testes realizados para rodagem do algoritmo do SOAPdenovo-trans

No website do SOAP [2] há um link que disponibiliza o código fonte do projeto, escrito em linguagem de programação C, além de algumas explicações básicas de como utilizar o programa.

Ao verificar o código e o conteúdo do site, foi possível notar que as informações para que o código seja utilizado e compreendido não são tão claras. Além de o código fonte não estar documentado, as instruções para rodar o programa não estão completas. Apesar disso, um dado importante obtido do site é o de que o programa possui quatro etapas: "pregraph", "contig", "map", e "scaffold", sendo que é informado neste mesmo site que aquela que apresenta um maior consumo de memória é a primeira, consistindo da parte em que as sequências lidas presentes nos arquivos de entrada são armazenadas em forma de grafo.

Foram feitos testes de execução com diferentes quantidades de arquivos de sequências do RNA da cana-de-açúcar, além de diferentes configurações de execução, sendo possível notar que todas as vezes em que o programa abortava sua execução era por falta de memória RAM, rodando a etapa de "pregraph". Como é possível rodar separadamente as etapas do SOAPdenovo-Trans, optou-se por fazer a análise e documentação apenas desta primeira.

Análise do algoritmo do SOAPdenovo-trans

A análise do código-fonte foi feita para a execução na versão SOAPdenovo-Trans-31mer, que aceita valores ímpares de K-mer de 13 a 31, considerando-se arquivos de entrada no formato fastq com single-reads. Espera-se que seja possível extrapolar esta análise para os demais casos.

Foi possível identificar que a etapa de “pregraph” utiliza de E/S assíncrona para a leitura dos arquivos através da biblioteca aio.h, além de se utilizar de linhas de execução (threads) para que a montagem do grafo possa ser dividida entre as sequências lidas e executadas concorrencialmente. Para armazenar os K-mers gerados, é utilizada uma função de hash conhecida como CRC32 (32-bit Cyclic Redundancy Check).

Para a E/S assíncrona, é utilizada a interface POSIX asynchronous I/O do Linux, que permite que a aplicação inicie uma ou mais operações de entrada/saída que são executadas em background, ou seja, permite que outro processo continue antes que sua transmissão termine. Esta habilidade de iniciar transferências últimas ao mesmo tempo se dá através de uma estrutura chamada bloco de controle (aiocb - AIO I/O Control Block), para que seja possível identificar quando a transferência completa. Esta interface em geral visa uma melhoria de desempenho, não interferindo no uso de memória.

A utilização de threads ocorre como uma forma de o processo dividir a si mesmo em duas ou mais tarefas que podem ser executadas concorrencialmente. No caso do modo

(3)

“pregraph”, as funções que dividem a sequência em K-mers, acrescentam os valores de hash na estrutura de hash, entre outras, são divididas em threads.

O método CRC, originalmente utilizado para identificação de erros em transmissões de sinais, gera um valor de checagem que é fixo para cada entrada. Seu algoritmo básico consiste, de forma geral, em procurar, em loop, um valor de 32 bits em uma tabela pré-definida, baseado no próximo byte do dado de entrada e os 8 bits menos significativos do valor prévio de CRC.

Foram feitas anotações no código fonte do SOAPdenovo-Trans referentes ao que é feito em cada passo do "pregraph", gerando com isso uma documentação em HTML com o uso da ferramenta Doxygen, sendo disponibilizado no website SourceFourge, sob um projeto nomeado SOAPdenovo-Trans-Analysis, podendo ser acessado através do link

https://sourceforge.net/projects/soapdenovo-trans-analysis/files/.

Além disso, contruiu-se um diagrama de sequências desta etapa, utilizando-se da ferramenta Visual Paradigm 12.1. Como a linguagem de programação utilizada é C, que não é orientada a objetos, algumas convenções foram necessárias para tornar possível o uso de UML v2.0. Arquivos .c são representados por classes, enquanto que as mensagens são as funções que estão sendo chamadas. Este diagrama pode ser visto na figura 1 a seguir.

(4)

Figura 1- Diagrama de sequência do modo "pregraph", arquivo de entrada do tipo fastq e execução como 31mer.

(5)

Exemplo com dois reads pequenos

A fim de ilustrar como o algoritmo se comporta no início de sua execução, irei exemplificar o que ocorre no modo de “pregraph” com dois reads bem pequenos, analisando as estruturas que são formadas, permitindo extrapolar para arquivos com reads completos. As sequências de bases nitrogenadas que foram utilizadas para os reads do exemplo estão representadas na figura 2.

Será utilizado 5 para o tamanho de K-mer (ou seja, 5-mer), com tamanho máximo de leitura de reads em 7. A simulação será feita considerando o arquivo de entrada do tipo fastq, com leituras do tipo single-paired e apenas um thread, o que equivaleria à seguinte linha de comando para execução do programa:

./SOAPdenovo-Trans-31mer pregraph -p 1 -s cf -K 13 -o outputGraph Além disso, o arquivo de configuração teria a seguinte configuração:

max_rd_len = 15 [LIB] avg_ins = 30 q = readPEQ.fq

Ao executar o programa com essas configurações, o código passaria da função main para a call_pregraph, onde serão armazenadas em variáveis as opões da linha de comando, através da função initenv. Posteriormente, a função prlRead2HashTable executa a construção de uma tabela hash que armazena os dados do grafo.

Na função prlRead2HashTable, ao executar a função que abre os arquivos que serão utilizados (openNextFile), a variável curr_type é definida com o valor 6, valor este que se debe ao fato de o arquivo dos reads serem do tipo fastq.

A partir de então, seriam chamadas funções para leitura dos arquivos em modo AIO. Prossegue-se então ao armazenamento do que é lido nos arquivos fastq. A linha de identificação do próximo read (primeira linha de cada read, iniciada por '@') é armazenada na variável next_name, sem o '@', enquando que cada sequência lida é armazenada em uma posição do array seqBuffer, no qual cada elemento é um ponteiro para um array em que cada elemento possui um byte. Essa sequência, porém, é armazenada com uma codificação que está representada na tabela 1.

Base Codificação Codificação Binária

A 0 0000 0000

C 1 0000 0001

T/U 2 0000 0010

G 3 0000 0011

Tabela 1- Codificação das bases nitrogenadas para utilização do hash. Figura 2- Read 1 e Read 2

(6)

A variável read_c funciona como índice para estruturas que armazenam dados dos

reads e dos K-mers. Cada índice destes armazena dados referentes a um mesmo read, ou seja,

o valor de read_c indica a quantidade de reads lidos –1. Inicialmente, read_c = 0, para que os primeiros dados sejam incluídos no primeiro índice de cada estrutura.

Após a execução da função readSeqInLib, tem-se armazenados os dados como nas figuras 3 e 4, ou seja, a partir do Read 1, armazena-se as bases codificadas em seqBuffer[0], além de seu tamanho em lenBuffer[0], e a partir do Read 2, faz-se o mesmo porém em seqBuffer[1] e lenBuffer[1]. A estrutura indexArray indica a quantidade acumulada de K-mers possíveis desde o primeiro read (sem contabilizar os K-K-mers possíveis do read referente ao read_c). Nesta função, os reads do arquivo aberto são lidos um a um, armazenando conforme descrito anteriormente, até que a quantidade de sequências lidas alcance o valor de leitura máximo (variável maxReadNum). Esta variável divide o valor do tamanho do buffer, fixo em 100MB, pelo número de K-mers possíveis em um read.

Ao atingir este valor de 100MB/(número de mers possíveis), a quantidade de K-mers possíveis nas sequências lidas até então é acumulada na variável kmerCounter[0]. Para este exemplo, então, ter-se-á kmerCounter[0] = 6. Neste momento, há o envio de sinal 2 para o thread, que começará a fazer o corte da sequência em seus diferentes 5-mers, através da função chopKmer4Read.

O primeiro read a ser analisado será o Read 1 (ACTGGAC), e posteriormente o Read 2 (GCATAGT). Para cada 5-mer, utiliza-se a função de hash CRC32, e pega-se apenas os 3 bytes menos significativos do valor gerado por ela. O valor de hash de cada um desses 5-mer é armazenado em hashBanBuffer, podendo ser visto na figura 5 em forma hexadecimal. O próprio 5-mer é armazenado em kmerBuffer, no índice referente à ordem em que o K-mer foi lido, utilizando-se dos dois bytes menos significativos da codificação binária das bases, como pode ser visto na figura 6. Essas duas variáveis, hashBanBuffer e kmerBuffer, possuem tamanho fixo de 100M * 8 bytes, ou seja, possuem 100M posições para cada K-mer, uma vez que um K-mer na execução na versão 31mer possui 8 bytes.

Um ponto importante ao armazenar o K-mer é que nem sempre ele é armazenado como aparece na sequência lida. Citarei como exemplo o primeiro 5-mer do Read 2. Primeiramente, são analisadas duas versões do K-mer: uma, temporariamente armazenada na variável word, é o 5-mer do jeito que foi lido da sequência (...11 0100 1000 = GCATA), enquanto que outra, temporariamente armazenada na variável bal_word, representa o nó complementar de word (...10 0010 1101 = TATGC). Este nó complementar é obtido trocando-se a base por sua base complementar, ou seja, A por T/U, C por G, T/U por A e G por C, e posteriormente invertendo a ordem dessas bases. A escolha de qual versão será utilizada para obtenção do valor de hash e posterior utilização no grafo será pela análise do valor desses 5-mers é feita analisando o valor numérico de cada uma: a que apresenta menor valor é utilizada. No exemplo, como 0010 0010 1101 < 0011 0100 1000, o nó complementar será usado. Ao armazenar os dados deste 5-mer em suas respectivas variáveis (hashBanBuffer, kmerBuffer, prevcBuffer, nextcBuffer), não é feita nenhuma indicação se o nó utilizado foi o complementar ou não, não tendo sido possível verificar no presente trabalho o porquê desta utilização. Os 5-mer que se utilizaram do nó complementar estão com um marcador vermelho para identificá-los nas figuras 5, 6 e 7.

Nesta função de chopKmer4Read também são armazenados a base seguinte e a anterior ao K-mer lido, informação necessária para montar o grafo. No caso de ser o primeiro K-mer, é armazenado o byte 0000 0100 na estrutura que armazena a base anterior (prevcBuffer), codificando um caractere inválido, já que não existe. O mesmo ocorre no caso do último K-mer, quando armazenada a base seguinte, em nextcBuffer. No caso de o K-mer

(7)

ser o nó complementar, o próximo ou anterior serão obtidos levando em consideração a ordem inversa da sequência de bases complementares.

Ao final da etapa de “chopKmer4Read”, as estruturas preenchidas com os dados obtidos dos reads de entrada podem ser vistas nas figuras de 3 a 7.

Read 1 Read 2

Read 1 Read 2

Figura 3- Representação do Read 1 preechido em seqBuffer[0] e do Read 2 em seqBuffer[1].

Figura 4- Representação do preenchimento de lenBuffer e indexArray.

Figura 5- Representação do preenchimento com os valores obtidos da função hash.

(8)

Read 1 Read 2

Read 1 Read 2

Conclusões

O estudo teórico possibilitou uma maior compreensão da metodologia utilizada no sequenciamento genético de forma geral, e de forma mais precisa em métodos de montagem

de novo, podendo aplicar esse conhecimento para a documentação do modo de pré-grafo do

código do SOAPdenovo-Trans.

Foi possível analisar o início da etapa de “pregraph” para a execução 31mer. Com as etapas analisadas não é possível chegar a uma conclusão sobre o motivo da falta de memória ao executar o programa. A explicação do que é feito nesta etapa do código pode ser utilizada como ponto de partida em trabalhos futuros que visem implementar melhorias de gerenciamento de memória deste programa.

Referências

1 - ARAÚJO, N.D.; FARIAS, R.P.; PEREIRA, P.B.; FIGUEIREDO, F.M.; MORAIS, A.M.B.; SALDANHA, L.C.; GABRIEL, J.E. A era da bioinformática: seu potencial e suas implicações para as ciências da saúde. Revista Estudos de Biologia, v. 30, n. 70/71/72, p. 143-148, 2008.

2 - BEIJING GENOMICS INSTITUTE. SOAPdenovo-Trans. Disponível em:

<http://soap.genomics.org.cn/SOAPdenovo-Trans.html>. Acesso em 30 de jun. de 2015.

http://sourceforge.net/projects/soapdenovotrans/files/SOAPdenovo-Trans/src/

3 - XIE, Y et al. SOAPdenovo-Trans: de novo transcriptome assembly with short RNA-Seq reads. 2014. Bioinformatics 30 1660–1666.

4 - KUMAR, Sanjiv. De-novo transcriptome assembly and annotation. Disponível em:

<http://bioinformatictools.blogspot.com.br/2013_11_01_archive.html>. Acesso em 30 de jun. de 2015.

Figura 7- Representação do preenchimento de prevcBuffer com a base anterior ao respectivo K-mer, e de nextcBuffer com a base posterior ao respesctivo K-mer

Referências

Documentos relacionados

Nessa situação temos claramente a relação de tecnovívio apresentado por Dubatti (2012) operando, visto que nessa experiência ambos os atores tra- çam um diálogo que não se dá

Portanto, mesmo percebendo a presença da música em diferentes situações no ambiente de educação infantil, percebe-se que as atividades relacionadas ao fazer musical ainda são

Avaliação do impacto do processo de envelhecimento sobre a capacidade funcional de adultos mais velhos fisicamente ativos.. ConScientiae

O objetivo do curso foi oportunizar aos participantes, um contato direto com as plantas nativas do Cerrado para identificação de espécies com potencial

No código abaixo, foi atribuída a string “power” à variável do tipo string my_probe, que será usada como sonda para busca na string atribuída à variável my_string.. O

da quem praticasse tais assaltos às igrejas e mosteiros ou outros bens da Igreja, 29 medida que foi igualmente ineficaz, como decorre das deliberações tomadas por D. João I, quan-

• The definition of the concept of the project’s area of indirect influence should consider the area affected by changes in economic, social and environmental dynamics induced

6 Num regime monárquico e de desigualdade social, sem partidos políticos, uma carta outor- gada pelo rei nada tinha realmente com o povo, considerado como o conjunto de