Índice
O ClinVar é um dos bancos de dados do Centro Nacional de Informação Biotecnológica dos EUA (NCBI na sigla em inglês). Ele é um grande arquivo de interpretações do impacto clínico de variantes genéticas humanas, daí o seu nome.
Qualquer organização -laboratórios, hospitais, institutos de pesquisa, etc.- pode enviar informações ao ClinVar após um cadastramento simples. O propósito deste banco de dados é agregar evidências científicas de qualquer variante genética envolvida em qualquer condição clínica humana.
Atualmente, mais de 2.400 organizações já contribuíram com mais de 2 milhões e 600 mil registros ao ClinVar. Coletivamente, eles representam mais de 1 milhão e 600 mil variantes distintas já observadas no genoma de alguém ao redor do mundo!
Qualquer pessoa pode fazer buscas no ClinVar por meio do site, usando siglas de genes, coordenadas genômicas, expressões HGVS, fenótipos e mais.
O site funciona muito bem para buscas simples, mas alguém que esteja pensando em realizar buscas mais complexas ou em maior volume pode sentir limitações. Outros bancos de dados do NCBI podem ser pesquisados com o utilitário de linha de comando Entrez Direct (EDirect), entretanto, o ClinVar infelizmente ainda não suporta o EDirect.
No entanto, a equipe do ClinVar oferece outras formas de acesso e uso de seus dados. Uma dessas formas é a disponibilização dos dados completos em um formato XML que é depositado no servidor FTP do ClinVar. O arquivo XML completo do ClinVar é atualizado semanalmente, e todo lançamento (release) que acontece na primeira quinta-feira de cada mês é arquivado.
Trabalhando com o arquivo XML do ClinVar
A versão 1.5.0 do módulo pandas do Python possui um método capaz de converter dados armazenados em arquivos XML para os característicos data frames. Essa função é a `read_xml()`.
Desde setembro de 2022, essa função foi atualizada com o argumento `iterparse`. A documentação da função explica que esse argumento é uma maneira eficiente de manejar arquivos XML grandes.
Eu escrevi um pequeno script para extrair dados do arquivo do XML. Antes de falar sobre ele, vou explicar como obter o arquivo XML do ClinVar.
Baixando o arquivo XML completo do ClinVar
Você pode baixar os arquivos XML comprimidos (extensão `.gz`) mais recentes a partir dos links a seguir:
Esses links são convenientes pois eles não mudam, apenas o arquivo é atualizado. Eles sempre vão apontar para as versões mais recentes. Ou seja, independentemente de quando você estiver lendo este artigo, estes links estão atualizados!
A seguir, um exemplo de linha de comando. Vá para uma pasta conveniente em seu servidor e execute os comandos abaixo:
wget https://ftp.ncbi.nlm.nih.gov/pub/clinvar/xml/ClinVarFullRelease_00-latest.xml.gz
gunzip ClinVarFullRelease_00-latest.xml.gz
Observe que eu baixei a versão mensal. Se você quiser checar a integridade dos arquivos após baixá-los, compare a checksum com as fornecidas pelo ClinVar:
Lançamento semanal (arquivo MD5)
Lançamento mensal (arquivo MD5)
Instalando módulos
Agora vamos instalar os módulos necessários. Como mencionado acima, precisamos da versão 1.5.0 ou superior do pandas. Além disso, precisamos também do módulo `lxml` ou do `ElementTree`.
Nesse tutorial, vou instalar apenas o lxml (a opção padrão da função que vamos utilizar). No exemplo abaixo, mostro como instalá-los em um ambiente virtual miniconda:
conda activate env_name
conda install -c conda-forge pandas=1.5.0 lxml
Em que `env_name` representa o nome de algum ambiente criado para esse tutorial. Recomendo a criação de um novo ambiente para não bagunçar seus ambientes existentes.
Executando o script
Mais um aviso antes de explicar o script passo-a-passo: para esse tutorial, usei uma instância EC2 na nuvem AWS com 90 GB de RAM. Eu não testei o script em máquinas menos poderosas pois o arquivo XML é bem pesado.
Mesmo que você não consiga trabalhar com o arquivo do ClinVar, fica a dica da função do `read_xml()` para trabalhar com outros arquivos XML.
Primeiro, vamos importar o pandas:
import pandas as pd
Em seguida, crio um objeto chamado `xml_file_path` para armazenar o caminho do diretório onde baixei o arquivo XML. Aqui estou assumindo que ele está na mesma pasta onde salvei o script:
xml_file_path = "ClinVarFullRelease_00-latest.xml"
Depois disso, eu crio um objeto chamado `iterparse_dict` que é um dicionário do Python contendo um mapeamento dos nós/atributos do XML que contêm as informações que eu desejo explorar no arquivo do ClinVar:
iterparse_dict = {
"ClinVarAssertion": [
"ID",
"SubmissionName",
"localKey",
"submittedAssembly",
"submitter",
"submitterDate",
"Acc",
"RecordStatus",
"OrgID",
"DateCreated",
"DateUpdated",
"Version",
"DateLastEvaluated",
"Description",
"ReviewStatus",
"Comment"
]
}
A chave do dicionário (a string “ClinVarAssertion”) representa o nó do XML que estou interessado. Fiz umas explorações prévias no arquivo e percebi que ele continha várias informações que eu queria obter, como por exemplo:
- o par variante/fenótipo (“localKey”),
- a organização que fez a submissão (“submitter”),
- o genoma de referência usado pela organização para gerar a interpretação (“submittedAssembly”, normalmente uma das builds GRCh37 ou GRCh38),
- a significância clínica da variante no contexto do fenótipo (“Description”).
Já o valor associado a essa chave é uma lista do Python. Os elementos dessa lista são nós filhos, atributos do nó pai ou, ainda, atributos dos nós filhos. Todos esses termos são característicos do formato XML.
Para facilitar, podemos considerar todos eles como “campos” de informação. É importante reforçar que outros nós presentes no XML podem conter dados diferentes. Os campos escolhidos são específicos do “ClinVarAssertion”.
Em seguida, simplesmente introduzo esse dicionário como valor para o argumento `iterparse` da função `read_xml()`. O output da função será um data frame do pandas, o qual armazeno num objeto chamado `df`:
df = pd.read_xml(xml_file_path, iterparse=iterparse_dict)
Depois de algum tempo, a função termina sua execução e então consigo visualizar o data frame:
Na imagem podemos ver o número de linhas (registros submetidos ao ClinVar) e o número de colunas esperado de acordo com o nosso dicionário – cada campo nomeado na lista virou uma coluna com informações referentes a cada registro.
Com o data frame instanciado, podemos filtrar os dados de acordo com nossos objetivos. Por exemplo, poderíamos buscar todas as interpretações associadas com uma variante específica, selecionarmos apenas variantes patogênicas associadas a alguma condição genética, todas as variantes enviadas por determinado laboratório, e assim por diante.
Depois de trabalharmos com o data frame, podemos salvá-lo em disco convertendo-o em um objeto “pickle”:
df.to_pickle("clinvar.pkl")
Caso queiramos restaurá-lo ao estado original, fazemos o seguinte:
df = pd.read_pickle("clinvar.pkl")
Mas lembre-se: jamais carregue objetos “pickle” de fontes desconhecidas. Carregar um “pickle” malicioso pode levar a execução remota de código.
Conclusão
Pronto, agora você conhece uma função para lidar com arquivos XML e convertê-los em data frame por meio de uma versão recente do pandas no Python. Basta apenas conhecer um pouco da estrutura de nós e atributos do arquivo XML para processá-lo com a função `read_xml()` e o argumento `iterparse`. Usei como exemplo o XML do banco de dados ClinVar.