Voltar ao catálogo
Season 20 18 Episódios 1h 10m 2026

Biopython Fundamentals

v1.87 — Edição de 2026. Um guia abrangente de 18 episódios sobre a utilização do Biopython (v1.87 - 2026) para análise de sequências, parsing de formatos de dados biológicos, execução de BLAST, manipulação de estruturas 3D, árvores filogenéticas e muito mais.

Computação Científica Bioinformática
Biopython Fundamentals
A Reproduzir
Click play to start
0:00
0:00
1
Introdução ao Biopython e ao Objeto Seq
Descubra a base do Biopython: o objeto Seq. Exploramos como os objetos de sequência diferem das strings padrão do Python e aprendemos a realizar operações biológicas como o reverso complementar e a tradução.
3m 44s
2
Dados de Sequência Ricos: O Objeto SeqRecord
Aprenda a envolver sequências em metadados ricos utilizando o objeto SeqRecord. Abordamos como identificadores, nomes, descrições e anotações de dicionário são armazenados juntamente com a sequência em bruto.
4m 42s
3
Ler e Escrever Ficheiros com o SeqIO
Domine as conversões de ficheiros de sequências e o processamento em lote com o Bio.SeqIO. Este episódio explica a diferença entre ler ficheiros de registo único e fazer o parsing de conjuntos de dados de múltiplos registos.
3m 47s
4
Extrair Genes com o SeqFeature
Mergulhe no complexo mundo das features de sequências. Explicamos como o Biopython representa coordenadas de genes, cadeias (strands) e localizações imprecisas (fuzzy) utilizando o objeto SeqFeature.
3m 41s
5
Alinhamento de Sequências Par a Par
Aprenda a comparar duas sequências diretamente utilizando o módulo Bio.Align. Discutimos o PairwiseAligner, a pontuação de substituição e as penalizações por lacunas (gaps) para alinhamentos globais e locais.
3m 53s
6
Manipulação de Alinhamentos Múltiplos de Sequências
Transite de alinhamentos par a par para alinhamentos múltiplos de sequências. Este episódio aborda o parsing de ficheiros de alinhamento com o AlignIO e o tratamento de alinhamentos como arrays 2D para extrair colunas específicas.
4m 02s
7
Consultar Bases de Dados do NCBI Programaticamente
Automatize as suas pesquisas de literatura e sequências. Descubra como consultar as bases de dados do NCBI utilizando o Entrez.esearch e recuperar IDs exatos sem utilizar um navegador web.
4m 12s
8
Executar o BLAST através da Internet
Desencadeie pesquisas remotas no BLAST diretamente a partir do Python. Aprenda a utilizar o qblast para enviar sequências para os servidores do NCBI e guardar em segurança os resultados XML em bruto.
3m 17s
9
Parsing Nativo: Desempacotar o XML do BLAST
Dê sentido aos complexos outputs do BLAST. Este episódio guia-o através do parsing de ficheiros XML do BLAST em objetos nativos do Python para extrair alinhamentos, High-scoring Segment Pairs (HSPs) e E-values.
3m 42s
10
Navegar em Estruturas 3D com o Bio.PDB
Entre nas três dimensões. Exploramos o módulo PDB, fazendo o parsing de estruturas macromoleculares e compreendendo a arquitetura Structure-Model-Chain-Residue-Atom (SMCRA).
3m 57s
11
Medir a Geometria de Proteínas
Calcule relações espaciais em proteínas. Este episódio aborda o cálculo de distâncias interatómicas e a utilização do NeighborSearch para encontrar átomos dentro de um raio específico.
4m 03s
12
Árvores Filogenéticas em Python
Faça o parsing, manipule e desenhe árvores evolutivas com o Bio.Phylo. Abordamos a leitura de ficheiros Newick, a travessia de árvores e o isolamento de clados específicos.
3m 29s
13
Análise de Motivos de Sequência
Descubra padrões ocultos no ADN. Descubra como criar motivos de sequência, construir Position-Weight Matrices (PWMs) e rastrear sequências-alvo para locais de ligação de fatores de transcrição.
4m 10s
14
Integração com Swiss-Prot e ExPASy
Aceda ao padrão de ouro das bases de dados de proteínas. Detalhamos como obter registos através do Bio.ExPASy e fazer o parsing de ficheiros flat densos do Swiss-Prot para extrair metadados de proteínas curados.
3m 34s
15
Visualizar Genomas com o GenomeDiagram
Transforme ficheiros GenBank em bruto em imagens com qualidade de publicação. Aprenda como o GenomeDiagram constrói mapas de genomas circulares e lineares sobrepondo faixas e setas de features.
3m 57s
16
Genética Populacional com o Bio.PopGen
Analise a variação genética entre populações. Este episódio introduz o Bio.PopGen para fazer o parsing de ficheiros Genepop e extrair facilmente frequências alélicas e métricas de heterozigocidade.
4m 00s
17
Vias Bioquímicas com o KEGG
Ligue os pontos metabólicos. Aprenda a fazer o parsing de registos de enzimas e vias do KEGG para rastrear reações bioquímicas e estruturas de compostos químicos.
4m 05s
18
Análise de Clusters para Expressão Génica
Agrupe genes pelo seu comportamento. Neste episódio final, abordamos o módulo Bio.Cluster, aplicando K-means e clustering hierárquico a dados de expressão de microarrays.
4m 19s

Episódios

1

Introdução ao Biopython e ao Objeto Seq

3m 44s

Descubra a base do Biopython: o objeto Seq. Exploramos como os objetos de sequência diferem das strings padrão do Python e aprendemos a realizar operações biológicas como o reverso complementar e a tradução.

Download
Olá, daqui fala o Alex da DEV STORIES DOT EU. Fundamentos de Biopython, episódio 1 de 18. Tratar uma sequência de DNA como uma string de texto normal funciona bem até precisares da sua cadeia oposta. A simples manipulação de strings em Python deixa de funcionar quando percebes que a transcrição biológica não se resume a substituir letras, mas envolve direcionalidade e códigos genéticos distintos. É exatamente por isso que usamos a Introdução ao Biopython e o objeto Seq. Na sua essência, uma sequência biológica é uma string de letras que representa moléculas como DNA, RNA ou proteínas. No Biopython, a estrutura de dados central é o objeto Seq. Ele encapsula o comportamento normal de uma string em Python, mas adiciona um contexto biológico diretamente aos dados. Como se comporta como uma string normal, podes fazer tudo o que normalmente fazes com texto. Podes verificar o comprimento de uma sequência. Podes contar quantas vezes um padrão específico aparece. Podes fazer slice para extrair um pedaço menor. Quando fazes slice de um objeto Seq, o resultado não é uma string de texto normal. É um novo objeto Seq. Isto garante que nunca removas acidentalmente os métodos biológicos quando fazes o parse de uma sequência em fragmentos menores. Esta é a parte que importa. As strings normais não entendem biologia. O DNA é de cadeia dupla e as sequências são lidas numa direção específica. Se tiveres uma sequência de DNA codificante e precisares da cadeia oposta, uma simples inversão de texto é biologicamente incorreta. Tens de inverter a ordem das letras e trocar cada base pelo seu par estrutural. O objeto Seq lida com isto através de um único método reverse complement, devolvendo uma cadeia oposta biologicamente precisa. Além da estrutura, o objeto Seq lida diretamente com o dogma central da biologia molecular. Considera uma pequena sequência de DNA codificante. Para converter isto em RNA mensageiro, chamas o método transcribe na tua sequência. Nos bastidores, isto lida com as substituições específicas de letras, substituindo a timina por uracilo, e devolve-te uma sequência de RNA. Se começares com RNA e precisares do equivalente em DNA, um método back transcribe reverte esse processo. Assim que a tua sequência estiver pronta, geralmente queres a proteína resultante. Chamas o método translate. Isto agrupa automaticamente as letras da sequência em tripletos, avalia-os como codões e devolve um novo objeto Seq que contém a sequência de aminoácidos. A biologia raramente é uniforme, e o código genético standard não se aplica em todo o lado. Organismos como certas bactérias, ou organelos como as mitocôndrias de vertebrados, leem os codões de maneira diferente. O método translate tem isto em conta através de tabelas de tradução. Em vez de escreveres lógica personalizada para uma sequência mitocondrial, simplesmente passas o argumento translation table para o método. Podes fornecer o número da tabela oficial do NCBI, como a tabela dois para mitocôndrias de vertebrados, ou o nome da tabela como texto. O objeto Seq recalcula os aminoácidos usando as regras específicas desse organismo. O verdadeiro poder do objeto Seq é que te impede de escrever funções de text parsing frágeis e propensas a erros para processos biológicos estabelecidos. Se quiseres apoiar o programa, podes procurar por DevStoriesEU no Patreon. É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
2

Dados de Sequência Ricos: O Objeto SeqRecord

4m 42s

Aprenda a envolver sequências em metadados ricos utilizando o objeto SeqRecord. Abordamos como identificadores, nomes, descrições e anotações de dicionário são armazenados juntamente com a sequência em bruto.

Download
Olá, daqui fala o Alex da DEV STORIES DOT EU. Fundamentos de Biopython, episódio 2 de 18. Uma string de dez mil letras de DNA é tecnicamente uma sequência, mas analiticamente, é inútil. Sem saberes a espécie de origem, o tipo de molécula ou a qualidade da leitura, tens apenas texto bruto. Associar esses metadados cruciais à sequência bruta é a função dos Rich Sequence Data: o objeto SeqRecord. O SeqRecord é um container. Ele pega numa sequência básica e envolve-a com os identificadores e a informação descritiva necessária para a usares realmente num pipeline de bioinformática. Cada SeqRecord depende de alguns atributos centrais. O primeiro é o ponto seq, que guarda os próprios dados da sequência em si. À volta disso, tens três atributos de string standard. O ponto id contém o identificador principal, tipicamente um número de acesso de uma base de dados pública. O ponto name guarda um nome comum mais curto ou um identificador de clone. O ponto description contém texto legível por humanos que explica o que a sequência realmente representa. Às vezes, três atributos de string não chegam. Quando precisas de guardar metadados complexos ou custom, usas o atributo ponto annotations. Isto é um dicionário standard de Python. Ele lida com metadados ao nível do record. Podes guardar qualquer coisa aqui. Se quiseres monitorizar como uma sequência foi verificada, simplesmente adicionas uma nova key chamada evidence ao dicionário e defines o seu valor como experimental. Aqui está o ponto chave. Nem todos os metadados se aplicam à sequência inteira como um todo. Às vezes precisas de dados atribuídos a cada letra individual. É isto que o ponto letter annotations faz. É outro dicionário, mas vem com uma regra estrita. Qualquer list, array ou string que atribuas como valor neste dicionário tem de ter exatamente o mesmo comprimento que a própria sequência. O use case clássico é guardar os Phred quality scores de uma máquina de sequenciação. Se a tua sequência de DNA dummy tiver exatamente vinte letras de comprimento, podes atribuir uma list de vinte inteiros ao dicionário ponto letter annotations debaixo da key phred quality. Se tentares atribuir dezanove ou vinte e um inteiros, o Biopython vai imediatamente lançar um erro. Podes facilmente construir um SeqRecord do zero. Primeiro, defines um objeto sequence. A seguir, passas essa sequence para o construtor do SeqRecord. Podes passar o identificador, o nome e a descrição logo aí como argumentos. Assim que o objeto existir, podes aceder aos seus dicionários para injetar manualmente as tuas strings de evidence customizadas ou as tuas lists de quality scores por letra. Na prática, raramente constróis isto inteiramente à mão. Normalmente obténs isto através do parsing de ficheiros, e o Biopython lida com diferentes formatos de ficheiro ao mapear os dados para os atributos do SeqRecord de formas específicas. Considera um ficheiro FASTA standard. O FASTA é um formato muito básico. Quando o Biopython o lê, ele agarra na primeira palavra a seguir ao símbolo de maior na linha de cabeçalho e atribui-a ao atributo ponto id. O atributo ponto name recebe simplesmente o mesmo valor exato que o identificador. O resto da linha de cabeçalho é despejado diretamente no atributo ponto description. Como o FASTA não tem metadados estruturados, o dicionário ponto annotations fica completamente vazio. Os ficheiros GenBank oferecem um contraste forte. Eles contêm dados ricos e estruturados. Ao fazer parsing do GenBank, o Biopython atribui o locus e o número da versão ao ponto id. O nome do locus vai para o atributo ponto name. A linha de definição mapeia para o ponto description. Crucialmente, o Biopython preenche ativamente o dicionário ponto annotations. Ele extrai os detalhes da taxonomia, o tipo de molécula, a divisão do ficheiro de dados e a list de referências publicadas, colocando tudo de forma organizada no dicionário debaixo de keys standard. A sequence diz-te o código biológico subjacente, mas o objeto SeqRecord é o que, em última análise, dá o contexto a esse código. Obrigado por passares uns minutos comigo. Até à próxima, fica bem.
3

Ler e Escrever Ficheiros com o SeqIO

3m 47s

Domine as conversões de ficheiros de sequências e o processamento em lote com o Bio.SeqIO. Este episódio explica a diferença entre ler ficheiros de registo único e fazer o parsing de conjuntos de dados de múltiplos registos.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. Fundamentos de Biopython, episódio 3 de 18. O teu pipeline de bioinformática crasha a meio da execução. Verificas os logs e percebes que um script downstream esperava um ficheiro FASTA, mas a ferramenta upstream passou-lhe um ficheiro GenBank. Agora tens de reescrever um parser do zero só para extrair os dados da sequência. Ou, podes usar o Bio dot SeqIO. O SeqIO é o módulo standard do Biopython para input e output de sequências. Ele trata do parsing de vários formatos de ficheiros biológicos para que não tenhas de escrever regular expressions customizadas ou funções de manipulação de strings. Forneces o file path e a format string, e o SeqIO trata da estrutura subjacente do ficheiro. Ao ler ficheiros, o SeqIO dá-te duas funções distintas, e escolher a errada é uma fonte comum de bugs. A primeira é a read. Usas a função read quando tens a certeza absoluta de que o teu ficheiro contém exatamente um sequence record. Passas-lhe o file path e o formato, como fasta, e ela devolve um único objeto sequence record. Se o ficheiro estiver vazio, ou se contiver dois ou mais records, a função read lança imediatamente uma exception e para o teu script. Serve estritamente para um mapeamento one-to-one. Mais frequentemente, lidas com ficheiros que contêm muitas sequências. Para isso, usas a função parse. Ao contrário da read, a parse não carrega tudo para a memória de uma só vez. Em vez disso, devolve um iterator. Esta é a parte que interessa. Um iterator faz yield de um sequence record de cada vez, o que mantém o teu memory footprint baixo, mesmo que estejas a processar datasets genómicos massivos de vários gigabytes. Considera um cenário específico. Tens um ficheiro GenBank com dados de várias espécies de orquídeas. Queres extrair estes records, mas só te interessam sequências com mais de cem pares de bases. Além disso, a próxima ferramenta no teu pipeline requer o formato fasta, e não GenBank. Podes tratar da leitura, filtragem e conversão de formato de forma sequencial. Primeiro, crias uma lista vazia para guardar as tuas sequências filtradas. A seguir, configuras um loop usando a função parse, apontando-a para o teu ficheiro GenBank de orquídeas e especificando genbank como a format string de input. Dentro do loop, a função parse entrega-te um objeto sequence record em cada iteração. Verificas o comprimento da sequência associada a esse record. Se o comprimento for maior que cem, fazes append do record à tua lista. Se for menor, simplesmente ignoras e passas para a próxima iteração. Agora tens uma lista de records válidos e filtrados em memória. Para os guardar, usas a função write. A função write requer três parâmetros: a sequência de records que queres guardar, o file path de output e a format string de output. Passas a tua lista de records de orquídeas filtrados, especificas um novo nome de ficheiro e forneces fasta como a format string. É só isto. O SeqIO extrai automaticamente os identificadores e sequências relevantes dos teus records GenBank e formata-os corretamente como texto fasta. Não precisas de construir manualmente as linhas de cabeçalho nem de formatar os blocos de sequência. Ao juntar a parse com a write, traduzes entre formatos de ficheiros sem esforço. O takeaway mais útil aqui é que o SeqIO atua como uma ponte standard. Ao forçar todos os formatos de ficheiro para uma estrutura universal de sequence record durante o passo de parse, ele desacopla completamente o formato que lês do formato que acabas por escrever. É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
4

Extrair Genes com o SeqFeature

3m 41s

Mergulhe no complexo mundo das features de sequências. Explicamos como o Biopython representa coordenadas de genes, cadeias (strands) e localizações imprecisas (fuzzy) utilizando o objeto SeqFeature.

Download
Olá, daqui fala o Alex da DEV STORIES DOT EU. Fundamentos de Biopython, episódio 4 de 18. Estás a fazer o slicing manual de uma string de sequência para extrair um gene na reverse strand. Calculas as coordenadas, invertes a string, complementas as bases e corres o teu script. Metade das vezes, acabas com um off-by-one error ou com dados sem sentido. Tentar fazer esta matemática de sequências à mão é uma armadilha clássica. Em vez disso, deves deixar o parser fazer o trabalho, extraindo os genes com o SeqFeature. Um objeto SeqFeature descreve uma região ou ponto de referência específico numa parent sequence. Quando fazes o parse de um rich file format, o Biopython preenche o teu sequence record com uma lista destes objetos feature. Cada feature tem três atributos principais que vais usar constantemente. O primeiro é o atributo type. Isto é simplesmente uma string que te diz o que a feature representa, como gene, CDS ou mRNA. O segundo é o atributo qualifiers. Isto é um dictionary que contém todos os metadados associados a essa feature específica. Se precisares do nome do gene, da locus tag, ou de uma nota sobre o produto de tradução, vais buscá-los ao dictionary qualifiers. O terceiro, e mais importante, é o atributo location. Este dita exatamente onde a feature vive matematicamente na parent sequence. E apresenta-se em duas formas principais. Um SimpleLocation lida com pedaços contínuos e ininterruptos de sequência. Contém uma posição de start exata, uma posição de end exata, e a strand. A strand é representada como um integer. É um para a forward strand, e menos um para a reverse strand. A biologia muitas vezes resiste a ser simples. Os genes com splicing em eucariotas são divididos em múltiplos exões ao longo do genoma. Para lidar com isto, o atributo location será, em vez disso, um CompoundLocation. Um CompoundLocation é essencialmente uma collection de SimpleLocations unidos. Agrupa essas coordenadas fragmentadas de exões e trata-as como uma única unidade lógica. Aqui está o ponto chave. Não precisas de olhar para estas coordenadas de location e escrever a tua própria slice notation em Python para extrair os dados da sequência do parent record. Usas o método extract associado à própria feature. Para o usares, pegas no teu objeto SeqFeature, chamas o método extract, e passas a parent sequence completa como argument. A feature olha para os seus próprios dados de location e faz o trabalho pesado por ti. Se a feature for um SimpleLocation na forward strand, faz o slice da sequência exatamente como esperarias. Se a feature estiver na reverse strand, o extract lida automaticamente com o slice, gera o reverse complement dessa sequência, e devolve o resultado biologicamente preciso. Não tens de inverter strings nem de te lembrar de complementar as bases. Faz ainda mais trabalho por ti quando lidas com um CompoundLocation. Se chamares o extract num gene com splicing, o Biopython vai à parent sequence, extrai cada exão individual com base nos seus respetivos SimpleLocations, faz o reverse complement automático se o gene estiver na minus strand, e junta-os todos na ordem correta. Devolve-te um pedaço de sequência contínuo e limpo, pronto para downstream translation ou análise. Confiar no método extract elimina a matemática manual de indexes que causa erros de dados silenciosos em pipelines de bioinformática. Gostava de tirar um momento para te agradecer por ouvires — ajuda-nos imenso. Tem um excelente dia!
5

Alinhamento de Sequências Par a Par

3m 53s

Aprenda a comparar duas sequências diretamente utilizando o módulo Bio.Align. Discutimos o PairwiseAligner, a pontuação de substituição e as penalizações por lacunas (gaps) para alinhamentos globais e locais.

Download
Olá, daqui é o Alex do DEV STORIES DOT EU. Fundamentos de Biopython, episódio 5 de 18. Os algoritmos clássicos de alinhamento por programação dinâmica são notoriamente lentos quando escritos em Python puro. Se tentares processar milhares de pares de sequências, o teu script vai ficar bloqueado durante horas. O Biopython resolve isto recorrendo a C para o trabalho pesado, dando-te uma performance de milissegundos. Este episódio é sobre Pairwise Sequence Alignment usando o objeto PairwiseAligner. Para comparar exatamente duas sequências, instancias um PairwiseAligner. Este único objeto atua como o motor de configuração para todo o processo. Por default, faz um global alignment, o que significa que força um match de ponta a ponta entre as duas sequências. Se quiseres apenas encontrar a subsequência com o melhor match escondida algures dentro de uma string maior, mudas o atributo aligner mode de global para local. O aligner precisa de regras para decidir o que constitui um bom match. Defines estas regras diretamente como atributos no objeto aligner. Atribuis um número positivo ao atributo match score, e um número negativo ao atributo mismatch score. Mas as sequências biológicas também sofrem mutações através da inserção ou deleção de blocos inteiros de letras, o que cria gaps no alinhamento. Aqui está a ideia principal. A biologia favorece fortemente uma única deleção longa em vez de várias deleções pequenas e dispersas. Para modelar esta realidade física, configuras duas gap penalties separadas. Atribuis um valor negativo grande ao open gap score para penalizar a criação de um novo gap. A seguir, atribuis um valor negativo muito menor ao extend gap score. Este desequilíbrio matemático força o aligner a agrupar os gaps sempre que possível. Assim que o teu aligner estiver configurado, chamas o seu método align e passas as tuas duas sequências. O método não retorna apenas uma única string ou um número final. Retorna um iterator de objetos de alinhamento. Vários caminhos através de uma matriz de programação dinâmica podem produzir exatamente o mesmo score mais alto. O aligner dá-te acesso a todos estes alinhamentos matematicamente ótimos. Como retorna um iterator, avalia de forma lazy. Apenas calcula o próximo caminho ótimo quando o pedes, o que protege o teu sistema de sobrecargas de memória se sequências altamente repetitivas gerarem milhares de alinhamentos igualmente válidos. Considera um exemplo concreto usando duas sequências curtas de DNA. A sequência um é A C C G T. A sequência dois é A C G, o que significa que lhe falta o segundo C e o T final. Primeiro, crias o objeto aligner. Defines o match score para dois, e o mismatch score para menos um. Defines o open gap score para menos cinco, e o extend gap score para menos um. A seguir, passas ambas as sequências para o método align. Quando fazes um loop sobre o iterator retornado e fazes print dos resultados, o Biopython formata automaticamente o output. Ele empilha as sequências visualmente, desenhando linhas verticais entre as bases que fazem match e traços onde falta uma letra. Vais ver exatamente como o aligner posicionou os caracteres de gap na segunda sequência para alinhar as letras que fazem match, maximizando o score total com base na severa open gap penalty que definiste. Lembra-te que configurar um aligner é essencialmente fazer o tuning de um modelo matemático; o output só terá significado biológico se os teus match, mismatch e gap scores refletirem com precisão a relação evolutiva específica entre as tuas sequências de input. É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
6

Manipulação de Alinhamentos Múltiplos de Sequências

4m 02s

Transite de alinhamentos par a par para alinhamentos múltiplos de sequências. Este episódio aborda o parsing de ficheiros de alinhamento com o AlignIO e o tratamento de alinhamentos como arrays 2D para extrair colunas específicas.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. Fundamentos de Biopython, episódio 6 de 18. Abres um ficheiro de alinhamento num editor de texto e ele parece perfeitamente estruturado, como uma grelha simples. Mas tenta fazer o parse apenas da terceira posição em cinquenta espécies diferentes, e de repente dás por ti a escrever nested loops e a controlar índices de strings. Lidar com Multiple Sequence Alignments não tem de ser assim tão frustrante. Para trazeres um alinhamento para o teu código, usas o módulo Bio AlignIO. Assumindo que o teu ficheiro de alinhamento já está gerado, recorres à função read. Passas a esta função o caminho do ficheiro e uma string com o nome do formato, como phylip ou stockholm. A função read processa o ficheiro de texto e devolve-te um objeto MultipleSeqAlignment. Aqui está o ponto chave. O objeto MultipleSeqAlignment comporta-se exatamente como um array bidimensional. Se já trabalhaste com uma matriz NumPy, a lógica é idêntica. As linhas nesta grelha são as tuas sequências individuais, normalmente a representar diferentes organismos ou genes. As colunas são as posições específicas de nucleótidos ou aminoácidos alinhadas em todas essas sequências. Como atua como um array 2D, usas a sintaxe standard de slicing de Python para manipular ambas as dimensões em simultâneo. Se só precisares de apanhar uma sequência específica, fazes o slice das linhas. Aceder ao index zero do teu alinhamento devolve a primeira sequência do ficheiro. Esta linha é devolvida como um objeto SeqRecord standard, completo com o ID da sequência, a descrição e os próprios dados da sequência biológica. Também podes fazer um loop diretamente sobre o objeto de alinhamento, e ele vai entregar-te cada SeqRecord linha a linha. Isto trata das sequências. Agora as colunas, que é onde a lógica 2D realmente te poupa tempo. Supõe que carregaste um alinhamento stockholm e queres isolar uma região inicial altamente conservada. Só te interessam as primeiras dez posições em todas as espécies. Em vez de iterares por cinquenta sequências e fazeres o slice de cinquenta strings individuais, aplicas um slice 2D diretamente ao objeto de alinhamento. Pedes todas as linhas usando uns únicos dois pontos para a primeira dimensão, seguidos de uma vírgula, e depois o slice zero a dez para a segunda dimensão. A sintaxe é simplesmente abrir parênteses retos, dois pontos, vírgula, dois pontos, dez, fechar parênteses retos. Esta única operação devolve um objeto MultipleSeqAlignment totalmente novo, a conter apenas essas primeiras dez colunas para cada sequência. Todos os IDs de sequência e metadados originais são preservados automaticamente na nova grelha mais pequena. Há uma ligeira diferença de comportamento dependendo da largura do teu slice. Quando fazes o slice de um range de colunas, o Biopython mantém a estrutura de grelha e devolve um objeto de alinhamento. Mas se extraíres exatamente uma única coluna — digamos, todas as linhas no index de coluna cinco — o objeto devolve uma única string de plain text a conter apenas esses caracteres de cima para baixo. Esta string de texto torna excecionalmente fácil calcular scores de conservação ou identificar polimorfismos de nucleótido único num local específico, sem fazer o unpack de quaisquer objetos. Podes combinar estes slices de linhas e colunas para extrair qualquer sub-bloco de que precises. Podes pedir as linhas dois a cinco, e as colunas cinquenta a sessenta, a isolar um domínio específico para um subconjunto de espécies. Trata os teus alinhamentos como matrizes, deixa o objeto MultipleSeqAlignment lidar com o tracking de strings, e o teu código de extração de dados vai encolher para quase nada. Ficamos por aqui neste episódio. Até à próxima!
7

Consultar Bases de Dados do NCBI Programaticamente

4m 12s

Automatize as suas pesquisas de literatura e sequências. Descubra como consultar as bases de dados do NCBI utilizando o Entrez.esearch e recuperar IDs exatos sem utilizar um navegador web.

Download
Olá, daqui é o Alex do DEV STORIES DOT EU. Fundamentos de Biopython, episódio 7 de 18. Precisas de fazer download de dez mil registos de sequências. Se escreveres um web scraper standard para aceder ao site do NCBI, o teu endereço IP será bloqueado antes de terminares os primeiros cem. O National Center for Biotechnology Information proíbe explicitamente o scraping automatizado. Para extrair dados de forma legal e fiável, precisas de consultar as bases de dados do NCBI de forma programática usando o Bio ponto Entrez. Antes de fazeres quaisquer network requests, tens de seguir as guidelines da API do NCBI. Primeiro, tens de lhes dizer quem és. Fazes isso definindo a variável Entrez ponto email com o teu endereço de email real. Se o teu script ficar fora de controlo e sobrecarregar os servidores deles, eles vão usar este email para te contactar antes de cortarem permanentemente o teu acesso. Segundo, tens de respeitar os rate limits deles. O NCBI restringe utilizadores não autenticados a três requests por segundo. O Biopython lida com isto automaticamente, forçando um delay em background. No entanto, se tentares lançar múltiplos scripts em paralelo para contornar este delay, o NCBI vai detetar o abuso e banir o teu IP. Cumpre as regras. O workflow para extrair dados do Entrez geralmente requer um processo de duas etapas: encontrar os identificadores únicos e, em seguida, fazer o download dos ficheiros propriamente ditos. Começas por pesquisar com a função Entrez ponto esearch. Supõe que queres encontrar o gene matK em orquídeas. Chamas o esearch e passas-lhe o nome da base de dados, que é nucleotide, juntamente com o teu termo de pesquisa, como orchid organism AND matK gene. Esta função de pesquisa não devolve dados de sequência biológica. Devolve uma HTTP response que atua como um ficheiro de texto aberto contendo um documento XML. Aqui está o ponto chave. Não precisas de escrever um XML parser customizado nem de extrair strings manualmente. Pegas nesse file handle de rede e passas diretamente para a função Entrez ponto read. Isto faz o parse do XML e traduz para um dicionário de Python standard. Dentro desse dicionário, simplesmente procuras a key chamada IdList. Isto dá-te uma lista em Python contendo os identificadores GenBank exatos que correspondem à tua query de orquídea. Assim que tiveres essa lista de identificadores, passas para a segunda etapa: fazer o download dos registos completos. Para isto, usas a função Entrez ponto efetch. Passas-lhe o mesmo nome de base de dados nucleotide, juntamente com um identificador dos teus resultados de pesquisa. Também precisas de especificar o formato dos dados que queres de volta. Para obteres um ficheiro de texto GenBank standard, defines o argumento retrieval type como gb e o argumento retrieval mode como text. Tal como a função de pesquisa, o efetch devolve uma network stream, não uma raw string. Como esta stream imita um ficheiro local, não precisas de guardar os dados descarregados no teu disco rígido primeiro. Podes passar o network handle diretamente para o SeqIO ponto read, especificar que o formato é genbank, e ele faz imediatamente o parse da stream para um objeto SeqRecord do Biopython. Agora tens a sequência e todas as suas anotações biológicas carregadas em memória. Quando terminares, fecha o handle para libertar recursos de rede. O hábito mais importante ao consultar o NCBI é tratar as tuas API responses como file streams em vez de text strings. Passar essas streams diretamente para o Entrez ponto read ou SeqIO ponto read evita memory overhead desnecessário e mantém as tuas automation pipelines perfeitamente limpas. Se achas estes episódios úteis, podes apoiar o programa procurando por DevStoriesEU no Patreon. Obrigado por ouvirem, happy coding a todos!
8

Executar o BLAST através da Internet

3m 17s

Desencadeie pesquisas remotas no BLAST diretamente a partir do Python. Aprenda a utilizar o qblast para enviar sequências para os servidores do NCBI e guardar em segurança os resultados XML em bruto.

Download
Olá, daqui é o Alex do DEV STORIES DOT EU. Fundamentos de Biopython, episódio 8 de 18. Ficares a olhar para uma página web a fazer auto-refresh enquanto uma sequência alinha contra uma base de dados global é um péssimo uso da tua tarde. Automatizar essa pesquisa em background significa que podes fazer algo útil enquanto o Python fica à espera. Hoje vamos falar sobre correr o BLAST pela internet usando o Biopython. A função de que precisas chama-se qblast, localizada no módulo Bio dot Blast dot NCBIWWW. Funciona como um wrapper para a API BLAST do NCBI, permitindo-te submeter queries diretamente do teu script, exatamente como farias através do portal web deles. Para disparar uma pesquisa, o qblast requer três argumentos obrigatórios. O primeiro é o programa BLAST que queres correr. Por exemplo, se estiveres a comparar uma sequência de nucleótidos contra uma base de dados de nucleótidos, passas a string blastn. Se estiveres a trabalhar com proteínas, passas blastp. O segundo argumento é a base de dados específica contra a qual estás a pesquisar. A escolha mais comum para nucleótidos é a string nt, que significa base de dados de nucleótidos não redundante. Se estivesses a pesquisar proteínas, usarias nr. O terceiro argumento é a própria query da sequência. O Biopython torna este input altamente flexível. Podes fornecer uma plain string da sequência raw, uma multi-line string formatada como um registo FASTA, um objecto SeqRecord do Biopython, ou um identificador exato de sequência, como um accession number do NCBI. Se quiseres correr uma pesquisa básica, chamas o qblast, dás-lhe o blastn como teu programa, nt como tua base de dados, e a tua string FASTA como query. O Python vai pausar a execução aqui enquanto negocia com os servidores do NCBI, à espera o tempo que for preciso até que o alinhamento remoto termine. Quando o servidor remoto terminar o job, o qblast retorna um file-like object com os teus resultados. Internamente, a função pede estes resultados em formato XML por default. Deves garantir que continua assim, porque XML é o formato standard de que o Biopython depende para downstream processing. Aqui está a dica principal. Não passes imediatamente este web handle retornado para uma função de parsing. Correr uma pesquisa BLAST remota é computacionalmente pesado para os servidores do NCBI e consome muito tempo para ti. Se fizeres o parsing da data stream em tempo real diretamente do web handle e o teu script encontrar um erro algumas linhas abaixo, esses dados da sequência perdem-se da memória. Para corrigires o teu código e tentares de novo, terias de correr exatamente a mesma pesquisa remota do zero, a desperdiçar a largura de banda deles e o teu tempo. O workflow correto é guardar permanentemente o raw output imediatamente. No momento em que o qblast retorna o web handle, usa as operações standard de ficheiros do Python para abrir um novo ficheiro local em write mode. Lê tudo do web handle, escreve diretamente no teu novo ficheiro XML local, e depois fecha o web handle. Agora tens uma cópia segura e estática da tua pesquisa BLAST guardada no teu disco rígido. Podes abrir esse ficheiro XML local amanhã, para a semana, ou cinquenta vezes seguidas enquanto fazes debug da tua aplicação, sem nunca fazeres ping à API do NCBI uma segunda vez. Desacopla sempre a tua network retrieval do teu processamento de dados, escrevendo as web responses no disco primeiro. É tudo por este episódio. Obrigado por ouvires, e continua a programar!
9

Parsing Nativo: Desempacotar o XML do BLAST

3m 42s

Dê sentido aos complexos outputs do BLAST. Este episódio guia-o através do parsing de ficheiros XML do BLAST em objetos nativos do Python para extrair alinhamentos, High-scoring Segment Pairs (HSPs) e E-values.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. Fundamentos de Biopython, episódio 9 de 18. Escrever expressões regulares para fazer scrape de ficheiros de output em plain-text é um rito de passagem na bioinformática. É também um anti-pattern. No momento em que uma ferramenta de pesquisa atualiza a sua formatação visual, o teu script quebra. Para teres garantias estruturais, precisas de te basear em dados estruturados. Este episódio cobre Parsing Nativo: Fazer Unpack de XML do BLAST. O Biopython lida com isto usando o módulo NCBIXML dentro do package Bio dot Blast. Em vez de guardares os resultados da tua pesquisa como um bloco de texto legível por humanos, guardas tudo como um ficheiro XML. Quando abres este ficheiro e passas o handle para a função parse no módulo NCBIXML, ele não carrega um blob de texto enorme para a memória. Em vez disso, devolve um iterator. Este iterator faz yield de objetos estruturados um de cada vez, mantendo o teu memory footprint baixo, mesmo que a tua pesquisa tenha devolvido quantidades massivas de dados. Para usares isto de forma eficiente, tens de entender a hierarquia de três níveis que o Biopython usa para modelar os resultados. O nível superior é o BLAST Record. Um record corresponde exatamente a uma sequência que submeteste como query. Se submeteste uma única sequência, o iterator faz yield de um record. Se submeteste cinquenta sequências, faz yield de cinquenta records. Dentro de cada BLAST Record, vais encontrar uma lista de Alignments. Um alignment representa um único hit na base de dados. Diz-te que uma sequência específica na base de dados fez match com a tua query, juntamente com metadados sobre essa entrada na base de dados. Dentro de cada Alignment está o terceiro nível: High-scoring Segment Pairs, universalmente conhecidos como HSPs. Esta é a parte que importa. Um alignment simplesmente indica que duas sequências estão relacionadas. O HSP contém a prova matemática e estrutural dessa relação. Um único alignment pode conter múltiplos HSPs se as sequências partilharem múltiplas regiões distintas de similaridade separadas por gaps não alinhados. Extrair os dados significa escrever três loops aninhados. Primeiro, iteras sobre os records no XML após o parse. Segundo, iteras sobre os alignments dentro de cada record. Terceiro, iteras sobre os HSPs dentro de cada alignment. Assim que estiveres dentro desse loop mais interno, tens acesso aos dados reais do match. É aqui que aplicas os teus filtros estatísticos. O filtro mais comum é o e-value, que representa o número de hits de qualidade semelhante que esperarias ver por acaso. Acedes a isto através do atributo expect no objeto HSP. Escreves uma verificação condicional: se o HSP dot expect for menor que o teu threshold, digamos zero vírgula zero quatro, processas o match. Se for maior, o match é demasiado fraco e ignoras. Para os hits que passam no teu filtro, o objeto HSP guarda as strings de alignment exatas. O atributo query contém a tua sequência de input com quaisquer gaps introduzidos pelo algoritmo. O atributo sbjct contém a sequência da base de dados que fez match. O atributo match situa-se concetualmente entre eles, contendo a representação do alignment, mapeando os matches exatos, substituições positivas ou gaps. A verdadeira vantagem aqui é a estabilidade. Ao deixares o módulo NCBIXML fazer unpack do ficheiro, deixas de depender de text scraping frágil e começas a interagir com objetos de dados definidos que mapeiam perfeitamente para a realidade biológica de records, alignments e segment pairs. Obrigado por ouvirem, happy coding a todos!
10

Navegar em Estruturas 3D com o Bio.PDB

3m 57s

Entre nas três dimensões. Exploramos o módulo PDB, fazendo o parsing de estruturas macromoleculares e compreendendo a arquitetura Structure-Model-Chain-Residue-Atom (SMCRA).

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. Fundamentos de Biopython, episódio 10 de 18. As proteínas são frequentemente armazenadas como uma string plana e unidimensional de letras, mas funcionam numa realidade tridimensional complexa. Mapear uma sequência 1D para um espaço de coordenadas 3D requer uma hierarquia estrita e previsível. Navegar por estruturas 3D com o Bio.PDB fornece exatamente esse mapa. Quando descarregas um ficheiro do Protein Data Bank, ele vem como um bloco de texto enorme. Historicamente, este era o formato ponto pdb. Hoje, o standard é o formato ponto cif. Escreveres o teu próprio código para ler estes blocos de texto linha a linha é um exercício de gestão de edge cases. O Bio.PDB resolve isto convertendo o texto numa árvore orientada a objetos. Para fazeres isto, usas o PDBParser ou o MMCIFParser. Crias uma instância do parser, chamas o seu método get structure, dás um nome arbitrário à tua structure e passas o caminho do ficheiro. O que recebes de volta é um objeto Structure. Este objeto Structure segue uma arquitetura de dados rigorosa conhecida como SMCRA. Isso significa Structure, Model, Chain, Residue, Atom. Cada ficheiro 3D processado pelo parser do Biopython é organizado nestes cinco níveis aninhados. O nível root é a Structure. Uma Structure contém um ou mais Models. Se a proteína foi resolvida usando cristalografia de raios X, geralmente há apenas um model. Se foi resolvida usando RMN, pode haver dezenas de models a representar diferentes flutuações estruturais. Normalmente, pegas apenas no primeiro, que está localizado no index zero. Dentro de um Model, tens Chains. Muitas proteínas são complexos formados por múltiplas chains polipeptídicas a interagir entre si. Estas são tipicamente rotuladas com uma única letra maiúscula, como chain A e chain B. Dentro de uma Chain, encontras Residues. Estes são os aminoácidos individuais que compõem a sequência. Este nível também contém ligandos e moléculas de água ligados a essa chain específica. Finalmente, dentro de um Residue, tens Atoms. Aqui está a ideia principal. Podes navegar por toda esta árvore usando iteração simples ou acesso estilo dicionário. Se escreveres um for loop sobre uma chain, ele faz yield de residues. Se iterares sobre um residue, ele faz yield de atoms. Se souberes exatamente o que estás a procurar, podes fazer drill down direto sem usar um loop. Se precisares das coordenadas espaciais do carbono alfa no centésimo residue da chain A, basta empilhares os teus lookups. Pegas no teu objeto Structure, pedes o model zero, depois a chain A, depois o residue cem e, por fim, o atom chamado CA. Considera um cenário prático: extrair as coordenadas 3D de todos os atoms num único residue específico. Primeiro, inicializas o teu parser e carregas o ficheiro para uma variável. A seguir, isolas o residue alvo. Crias uma variável e atribuis-lhe o resultado do lookup pelo model zero, chain A e residue cinquenta na tua structure. Agora, escreves um for loop standard. Para cada atom no residue alvo, pedes as suas coordenadas. O Biopython retorna isto como um array NumPy a representar as posições exatas X, Y e Z no espaço. Fazes print do nome do atom e do seu array de coordenadas. Em apenas algumas linhas de código, fizeste bypass a milhares de linhas de raw text e extraíste os dados espaciais exatos de que precisas. A hierarquia SMCRA garante que cada atom em cada ficheiro de structure seja encontrado usando exatamente a mesma lógica. É tudo por agora. Até à próxima!
11

Medir a Geometria de Proteínas

4m 03s

Calcule relações espaciais em proteínas. Este episódio aborda o cálculo de distâncias interatómicas e a utilização do NeighborSearch para encontrar átomos dentro de um raio específico.

Download
Olá, daqui é o Alex do DEV STORIES DOT EU. Fundamentos de Biopython, episódio 11 de 18. Se escreveres um nested loop ingénuo para calcular a distância entre cada átomo de uma proteína e cada átomo de um ligando, o teu script vai bloquear. A indexação espacial resolve isto instantaneamente, e é isso que vamos abordar hoje em Medir a Geometria de Proteínas. A operação geométrica mais fundamental no Bio dot PDB é encontrar a distância entre dois pontos no espaço tridimensional. O Biopython faz override do operador de subtração standard para objetos Atom. Se pegares num objeto Atom e subtraíres um segundo objeto Atom, o resultado é um float que representa a distância euclidiana entre eles. A unidade é sempre Angstroms. Não precisas de extrair as coordenadas, elevá-las ao quadrado ou calcular a raiz quadrada tu mesmo. Basta subtraíres um átomo do outro e tens a tua distância exata. Este truque de subtração é perfeito para verificar uma interação específica e conhecida, como uma única ligação de hidrogénio suspeita. Mas falha quando precisas de explorar uma proximidade desconhecida. Supõe que tens um ligando de molécula pequena ligado a um grande recetor, e precisas de identificar todos os resíduos da proteína dentro de um raio de cinco Angstroms desse ligando. Uma proteína típica contém milhares de átomos. Verificar cada átomo do ligando contra cada átomo da proteína é computacionalmente muito pesado. A time complexity cresce geometricamente, e o teu script para completamente. Para resolver isto, o Bio dot PDB fornece o módulo Neighbor Search. Em vez de comparar pares um a um, o Neighbor Search constrói um spatial index. Internamente, constrói uma KD-tree que mapeia onde tudo está no espaço tridimensional, permitindo proximity queries extremamente rápidas. Constróis um objeto Neighbor Search passando-lhe uma flat list de todos os átomos contra os quais queres fazer a query. Normalmente, extrais cada átomo da tua estrutura alvo, fazes cast desse generator para uma list standard, e passas isso ao constructor do Neighbor Search. Este passo de inicialização demora uma fração de segundo, mas faz todo o trabalho computacional pesado de organizar os dados espaciais à partida. Assim que o index estiver construído, podes fazer-lhe queries. O método de search principal requer dois argumentos: uma coordenada alvo e um raio em Angstroms. Quando corres o search, ele percorre rapidamente a spatial tree e retorna apenas as entidades localizadas dentro dessa fronteira esférica. Aqui está o ponto chave. O search não retorna apenas átomos. Como o Bio dot PDB se baseia na arquitetura SMCRA, o Neighbor Search compreende a hierarquia estrutural. Podes passar um parâmetro level opcional à tua search query. Se especificares a letra R para resíduo, o index vai olhar para todos os átomos dentro do teu raio de cinco Angstroms, determinar a que parent residues esses átomos pertencem, e retornar uma list limpa de objetos Residue únicos. Fazes bypass ao nível do átomo nos teus resultados por completo. Para mapear o nosso binding pocket do ligando, segues um flow simples. Primeiro, inicializa o Neighbor Search com todos os átomos na cadeia da proteína. Segundo, itera apenas pelos átomos do teu ligando. Para cada átomo do ligando, chama o método search com um raio de cinco Angstroms e pede o level de resíduo. Finalmente, recolhe esses resíduos retornados para um set de Python para removeres automaticamente quaisquer duplicados. Acabaste de mapear o binding site em milissegundos. Se precisares de encontrar clashes internos dentro de uma única cadeia dobrada, o Neighbor Search também inclui um método search all. Basta forneceres um raio, e ele retorna todos os pares de átomos em toda a estrutura que estão mais próximos do que essa distância especificada, evitando completamente o problema do nested loop. Tratar os teus dados moleculares como um index geográfico pesquisável em vez de uma nested list transforma o teu código de lento e estrutural para rápido e espacial. É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
12

Árvores Filogenéticas em Python

3m 29s

Faça o parsing, manipule e desenhe árvores evolutivas com o Bio.Phylo. Abordamos a leitura de ficheiros Newick, a travessia de árvores e o isolamento de clados específicos.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. Fundamentos de Biopython, episódio 12 de 18. Se já olhaste para um ficheiro Newick raw, sabes que é apenas um pesadelo denso e aninhado de parênteses e vírgulas. Escreveres o teu próprio string parser para descobrir que espécie está relacionada com qual é um exercício miserável. O que precisas é de uma forma de carregar esse texto diretamente para uma estrutura de dados navegável. É exatamente isso que o Bio dot Phylo oferece para Árvores Filogenéticas em Python. O Bio dot Phylo lida com o parsing, manipulação e desenho de árvores evolutivas. O ponto de entrada principal é a função read. Passas-lhe um file path e uma format string, como newick ou phyloxml. A função read consome esse ficheiro e devolve um único objeto tree. Se o teu ficheiro contiver várias árvores, usas a função parse em vez disso para obteres uma sequência iterable de árvores. Assim que carregas o ficheiro, trabalhas com dois componentes distintos: o objeto Tree e o objeto Clade. O objeto Tree representa a estrutura inteira como um todo. Ele guarda metadata global, como o nome da árvore e se ela é rooted ou unrooted. Mas os dados de branching reais não vivem diretamente no objeto Tree. Vivem em objetos Clade. Um Clade representa um node específico e todos os descendentes que fazem branch a partir dele. O objeto Tree tem um atributo root, que é simplesmente o Clade inicial para toda a hierarquia. Cada branch a partir dessa root é outro Clade, que contém os seus próprios sub-clades, em cascata até às pontas. Navegar por esta hierarquia é onde o módulo brilha. Não escreves loops recursivos manualmente. Para pesquisar a estrutura, chamas o método find clades na tua árvore. Este método pesquisa por todos os branches aninhados e devolve um iterable de clades que correspondem às propriedades que especificares. Podes pesquisar por nome, por branch length, ou até mesmo por uma função de avaliação custom. Se apenas te importas com as extremidades absolutas dos branches, que representam as espécies vivas atuais, usas o método get terminals. Isto devolve imediatamente uma flat list dos leaf clades. Também podes calcular métricas estruturais instantaneamente. Chamar o método total branch length na árvore soma os comprimentos de cada branch em toda a estrutura, dando-te a distância evolutiva total. Considera um cenário em que carregas uma enorme árvore evolutiva de mamíferos. Queres isolar apenas o branch que contém os primatas para correr uma análise localizada. Chamas o find clades e procuras pelo target name Primates. Isto devolve o objeto Clade específico que representa o ancestral comum de todos os primatas. Como um Clade contém naturalmente todos os seus descendentes, tens agora uma subtree completa e isolada. Podes passar esse clade de primatas para outras funções de análise exatamente como farias com uma tree completa. Às vezes, só precisas de olhar para a estrutura para verificar se a tua extração funcionou. O Bio dot Phylo inclui uma função draw ascii. Passas a tua tree ou o teu clade isolado para esta função, e ela faz print de uma representação em plain text diretamente no teu terminal. Não é feita para publicação, mas dá-te feedback visual imediato sobre a topologia sem exigir que configures plotting libraries externas. Aqui está o key insight. Traduzir parênteses aninhados para objetos nativos significa que a topologia se torna numa API, permitindo-te fazer slice de históricos evolutivos com method calls standard. Se achaste este episódio útil e queres apoiar o programa, podes procurar por DevStoriesEU no Patreon. É tudo por este episódio. Obrigado por ouvires, e continua a programar!
13

Análise de Motivos de Sequência

4m 10s

Descubra padrões ocultos no ADN. Descubra como criar motivos de sequência, construir Position-Weight Matrices (PWMs) e rastrear sequências-alvo para locais de ligação de fatores de transcrição.

Download
Olá, daqui fala o Alex da DEV STORIES DOT EU. Fundamentos do Biopython, episódio 13 de 18. Se tentares encontrar um binding site de um fator de transcrição usando um string match estrito, vais perder a grande maioria dos sinais biológicos reais. Os binding sites de DNA oscilam, e as proteínas toleram variações em posições específicas da sequência. Para os encontrares de forma fiável, tens de parar de procurar strings fixas e começar a procurar perfis de probabilidade, que é exatamente o que a análise de sequence motifs te permite fazer. No Biopython, lidas com isto usando o módulo motifs. Começas com um conjunto conhecido de sequências alinhadas que representam o teu binding site. Vamos usar a clássica TATA box como exemplo. Podes ter algumas sequências curtas conhecidas, como T A T A A A, T A T A A T e T A T A A C. Defines estas sequências como objetos Seq standard e passas tudo como uma única list para a função create no módulo motifs. O Biopython pega nesta list de instâncias e empacota-as num único objeto motif. O resultado imediato da criação deste objeto motif é uma count matrix. Em cada posição ao longo do comprimento da tua sequência, o Biopython contabiliza o total de ocorrências de A, C, G e T. Se olhares para a primeira posição dos nossos exemplos de TATA box, a contagem para T é três, e a contagem para as outras três letras é zero. Esta matriz é a base literal de toda a análise downstream, mas as raw counts têm uma limitação matemática severa. Se um nucleótido nunca aparecer numa determinada posição na tua pequena amostra de referência, a sua probabilidade torna-se num zero absoluto. Mais tarde, quando multiplicares as probabilidades para calcular o score de uma sequência, um único zero anula o score inteiro. Para corrigir esta vulnerabilidade, convertes a count matrix numa Position-Weight Matrix, ou PWM. A ideia principal é esta. Geras a PWM aplicando pseudocounts. Um pseudocount adiciona uma pequena fração de baseline a cada nucleótido possível em cada posição. Isto reconhece matematicamente que, só porque ainda não viste uma citosina na posição dois, não significa que uma substituição aí seja biologicamente impossível. Ao suavizar os zeros, a Position-Weight Matrix transforma as tuas raw counts em distribuições de probabilidade robustas. Probabilidades por si só ainda são difíceis de usar para sequence scanning. Precisas de saber se um trecho de DNA faz um match melhor com o teu motif do que com uma background sequence aleatória. Resolves isto convertendo a tua PWM numa Position-Specific Scoring Matrix, ou PSSM. A PSSM calcula scores de log-odds com base numa distribuição de nucleótidos de background. Compara a probabilidade de uma letra aparecer por fazer parte do teu motif com a probabilidade de aparecer puramente por acaso. Um score positivo significa que a sequência se parece ativamente com o teu motif. Um score negativo significa que se parece com background noise. Assim que tiveres a tua PSSM, podes procurar por binding sites não anotados numa longa target sequence. Chamas o método calculate na PSSM e passas a tua target sequence de DNA. Este método efetivamente desliza o teu motif por todo o target, calculando o score de cada janela possível desse comprimento. Retorna um array de scores numéricos que representam o valor de log-odds em cada posição da sequência. Iteras sobre estes scores e procuras por valores que ultrapassem um threshold estrito definido. Se o score for alto o suficiente, provavelmente encontraste uma TATA box funcional. Um string match estrito exige perfeição, mas os sistemas biológicos operam com base em probabilidades, e a transição de raw counts para scoring matrices captura esta realidade. É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
14

Integração com Swiss-Prot e ExPASy

3m 34s

Aceda ao padrão de ouro das bases de dados de proteínas. Detalhamos como obter registos através do Bio.ExPASy e fazer o parsing de ficheiros flat densos do Swiss-Prot para extrair metadados de proteínas curados.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. Fundamentos de Biopython, episódio 14 de 18. O GenBank é ótimo quando estás a trabalhar com ácidos nucleicos. Mas quando precisas de dados especializados e revistos manualmente sobre uma proteína — como os seus sítios ativos exatos ou onde atravessa a membrana celular — as bases de dados de sequências standard ficam aquém. Precisas de uma base de dados de proteínas especializada, e isso leva-nos à integração do Swiss-Prot com o ExPASy. O Swiss-Prot é uma base de dados de sequências de proteínas de alta qualidade, anotada manualmente. O ExPASy é o portal do servidor que fornece acesso à mesma. O Biopython liga estas duas partes. Usa o módulo ExPASy para fazer o download dos dados pela internet, e o módulo SwissProt para fazer o parse para um object estruturado. Primeiro, precisas de extrair o raw record da internet. Fazes isso usando o módulo ExPASy, especificamente uma function chamada get_sprot_raw. Passas-lhe um accession ID do Swiss-Prot. Por exemplo, se quiseres o record da subunidade alfa da hemoglobina humana, passas o seu accession ID, que é P69905. Chamar a get_sprot_raw com este ID abre uma ligação de rede ao servidor e devolve um handle para os dados em raw text. Assim que tiveres esse handle de raw text, passas o mesmo para o módulo SwissProt. Chamas a function read e passas o teu handle. Isto faz o parse do flat file e devolve um record object do Swiss-Prot. Aqui está o ponto chave. Este record object não é apenas uma sequence string. É um container profundamente estruturado de metadados especializados. Como o Swiss-Prot é curado manualmente, os fields neste object são excecionalmente ricos. Podes aceder ao attribute organism para confirmar exatamente a que espécie a proteína pertence. Podes verificar o attribute sequence_length para obter a contagem de aminoácidos instantaneamente, sem precisares de medir a sequence string tu mesmo. A parte mais valiosa do record é o attribute features. Esta é uma nested list que contém os domínios estruturais e funcionais conhecidos da proteína. Quando iteras por estas features, vais encontrar anotações específicas. Vais ver features a detalhar as coordenadas exatas de aminoácidos para sítios ativos, regiões de ligação a metais ou domínios transmembranares. Em vez de correres um algoritmo de previsão, estás a ler coordenadas definitivas, confirmadas em laboratório, diretamente de uma base de dados curada. Na prática, o teu code flow é mais ou menos assim. Chamas a function get_sprot_raw do ExPASy com o teu accession ID. Pegas no handle resultante e passas o mesmo para a function read do SwissProt. Isto dá-te o teu record object. A partir daí, podes ler o organism, verificar o sequence_length, ou fazer um loop pela features list para extrair os sítios funcionais. Lembra-te sempre de fechar o network handle assim que terminares de ler os dados, para libertar recursos do sistema. Quando estás a construir pipelines que dependem da função biológica em vez de apenas da similaridade de sequência, usar o Swiss-Prot garante que estás a basear a tua lógica em dados verificados e curados por humanos. É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
15

Visualizar Genomas com o GenomeDiagram

3m 57s

Transforme ficheiros GenBank em bruto em imagens com qualidade de publicação. Aprenda como o GenomeDiagram constrói mapas de genomas circulares e lineares sobrepondo faixas e setas de features.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. Fundamentos de Biopython, episódio 15 de 18. Quando submetes um artigo a descrever um plasmídeo bacteriano recém-sequenciado, os revisores raramente querem ler uma tabela em plain text com as coordenadas dos genes. Eles esperam um mapa circular colorido e com anotações claras, que torne a estrutura genómica óbvia à primeira vista. Visualizar genomas com o GenomeDiagram é a forma de gerares esses mapas diretamente a partir dos teus dados de sequenciação. Antes de começares a desenhar, tens de garantir que a library externa ReportLab está instalada. O GenomeDiagram depende inteiramente do ReportLab nos bastidores para calcular a geometria e renderizar as imagens finais. Sem ele, o export gráfico vai falhar. A arquitetura do GenomeDiagram é estritamente hierárquica. Constróis a tua visualização ao aninhar objetos de cima para baixo. No topo absoluto está o objeto Diagram. Esta é a tua tela em branco. Dentro do Diagram, adicionas uma ou mais Tracks. Uma Track representa uma área de plot específica. Num mapa linear, uma Track é uma linha horizontal. Num mapa circular de plasmídeo, uma Track é um único anel concêntrico. Dentro de uma Track, adicionas FeatureSets. Um FeatureSet é um agrupamento lógico de dados de sequência. Podes usar um FeatureSet para sequências codificadoras e um FeatureSet diferente para regiões reguladoras, exatamente no mesmo anel. Finalmente, dentro dos FeatureSets, colocas as features de sequência individuais. Aqui está o ponto-chave. Não tens de calcular manualmente ângulos ou coordenadas de píxeis para posicionar os teus genes. O GenomeDiagram lê a posição de start, a posição de stop e a orientação da strand nativamente a partir de objetos feature standard do Biopython. Para pôr isto em prática, supõe que tens um record GenBank com o parse feito para um pequeno plasmídeo. Primeiro, inicializas um Diagram vazio. A seguir, crias uma nova Track lá dentro, e um novo FeatureSet dentro dessa Track. Depois, iteras sobre as features no teu record GenBank com o parse feito. Verificas se o tipo de feature atual é uma CDS, ou seja, uma sequência codificadora. Quando encontras uma CDS, passas essa CDS para o teu FeatureSet para a adicionares à visualização. Nesta etapa, atribuis o styling visual. Podes configurar a feature para fazer o render como uma seta, que aponta automaticamente no sentido horário ou anti-horário, com base na strand do gene. Também podes atribuir cores distintas aqui. Um truque comum é usar um simples contador de loop para alternar entre duas cores, para que genes adjacentes não se misturem visualmente num bloco gigante. Assim que a tua hierarquia estiver totalmente preenchida com dados, dás a instrução ao Diagram para se desenhar. Chamas o método draw e defines o formato como circular. Podes definir as dimensões da página, a cor de fundo e o scaling da Track. Depois de o desenho ser construído em memória, basta chamares o método write, passando um nome de ficheiro terminado em PDF ou PNG. O ReportLab calcula instantaneamente os comprimentos de arco corretos, posiciona as setas coloridas ao longo da Track circular e exporta um ficheiro pronto para publicação. A principal vantagem desta estrutura em camadas é a reprodutibilidade. Como as regras de layout estão estritamente separadas do parse da tua sequência raw, podes escrever um único script para aplicar um styling uniforme a toda uma base de dados de plasmídeos sem nunca tocares numa ferramenta de design gráfico. Obrigado por ouvires. Até à próxima!
16

Genética Populacional com o Bio.PopGen

4m 00s

Analise a variação genética entre populações. Este episódio introduz o Bio.PopGen para fazer o parsing de ficheiros Genepop e extrair facilmente frequências alélicas e métricas de heterozigocidade.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. Fundamentos de Biopython, episódio 16 de 18. Tens dados brutos de genótipos de campo e precisas de métricas estatísticas, mas preencher essa lacuna significa escrever mais um script personalizado para fazer o parse de ficheiros de texto. Converter esses dados de campo num formato pronto para análise é aborrecido, a não ser que uses um parser construído exatamente para o formato standard Genepop. É aí que entra o Population Genetics com o Bio.PopGen. O Genepop é um pacote de software e um formato de ficheiro standard usado para calcular métricas como o equilíbrio de Hardy-Weinberg, estatísticas F e desequilíbrio de ligação. O seu formato de input baseado em texto, geralmente guardado como um ficheiro ponto gen, é rígido. Depende de quebras de linha estritas, keywords específicas e códigos inteiros colados para os alelos. Escreveres a tua própria lógica para extrair frequências de alelos em múltiplos loci e populações é propenso a erros off-by-one. O módulo Bio.PopGen evita isto completamente, lendo o formato Genepop diretamente para um objeto Python estruturado. Pega num cenário concreto. Estás a estudar duas populações isoladas de peixes. Tipificaste cada peixe em três loci de microssatélites. Os teus dados brutos estão num ficheiro ponto gen standard. O topo do ficheiro tem um título, seguido pelos nomes dos teus três marcadores em linhas separadas. A seguir vem a keyword Pop, que marca o início da primeira população de peixes. Abaixo disso, cada linha representa um peixe, mostrando um identifier seguido pelos seus alelos nos três loci. Depois do último peixe desse grupo, aparece outra keyword Pop, a marcar o início da segunda população. Para processar isto, importas o módulo GenePop do Bio.PopGen. Abres o teu ficheiro de texto e passas o file handle aberto para a função GenePop ponto read. Esta função processa o texto e devolve um único objeto Record. Esta é a parte que interessa. O objeto Record reflete a hierarquia biológica do teu estudo. Se verificares o atributo loci list no Record, ele devolve uma sequence simples com os nomes dos teus três marcadores microssatélites. Isto confirma que o parser leu o header com sucesso. Depois, podes olhar para o atributo populations. Este atributo guarda uma list onde cada elemento representa uma população inteira do teu ficheiro. Como tens duas keywords Pop no teu ficheiro, esta list contém exatamente dois elementos. Se olhares de perto para uma dessas populações, encontras uma list dos indivíduos que ela contém. Cada indivíduo é guardado como um par do seu identifier em string e uma list dos seus genótipos. Para um organismo diploide, é feito o parse de um genótipo num único locus como um par de alelos. O ficheiro de texto Genepop muitas vezes guarda estes alelos como uma única string combinada de dígitos, como zero um zero dois. O parser divide isto automaticamente em alelos distintos, representando zero um e zero dois como entidades separadas. Não tens de escrever lógica de string slicing para separar os alelos maternos e paternos. Com o parse do ficheiro feito, tens acesso imediato aos nomes dos marcadores, contagens de populações e dados individuais de alelos. Podes iterar pelas populações para contar frequências de alelos específicos, ou passar o objeto Record diretamente para rotinas do Biopython que interagem com o software Genepop. Podes acionar cálculos de heterozigosidade esperada ou medir a diferenciação genética entre os teus dois grupos isolados. O valor do parser Bio.PopGen não é apenas ler um ficheiro de texto, mas transformar uma list plana de strings numa hierarquia biológica estrita de loci, populações e indivíduos que os algoritmos estatísticos exigem. É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
17

Vias Bioquímicas com o KEGG

4m 05s

Ligue os pontos metabólicos. Aprenda a fazer o parsing de registos de enzimas e vias do KEGG para rastrear reações bioquímicas e estruturas de compostos químicos.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. Fundamentos de Biopython, episódio 17 de 18. Sequenciaste um gene e encontraste uma variante. Conhecer a sequência raramente é suficiente. Para perceberes o verdadeiro dano biológico, precisas de saber exatamente quais as redes metabólicas que a enzima resultante perturba. Biochemical Pathways com o KEGG dá-te exatamente esse mapa. A Kyoto Encyclopedia of Genes and Genomes mantém extensas bases de dados que detalham sistemas biológicos, compostos e reações. Eles distribuem estes dados como flat files de plain text standard. Estes ficheiros usam uma estrutura específica onde uma keyword fica na margem esquerda, e os dados associados ficam na direita. O problema é que os valores dos dados, como longas listas de sinónimos ou nomes complexos de pathways, frequentemente fazem wrap de forma imprevisível por várias linhas. Escrever manipulação de strings customizada para lidar com esse wrapping é frágil. O módulo Bio dot KEGG existe para lidar com as peculiaridades de formatação e traduzir esses ficheiros de texto diretamente em objetos Python previsíveis. Para extraíres dados moleculares básicos, usas a função Compound dot parse dentro do módulo KEGG. Passas-lhe um file handle aberto a apontar para um ficheiro de texto de compostos do KEGG. Em vez de carregar um enorme database dump para a memória de uma só vez, o parser devolve um iterator. Cada vez que avanças o iterator, ele faz yield de um único objeto Python que representa um composto. A partir deste objeto, podes aceder ao atributo entry para obteres o identificador único, que normalmente se parece com um C maiúsculo seguido de números. Como os compostos frequentemente têm vários nomes comuns na literatura, o atributo name devolve uma lista de strings com todos os sinónimos reconhecidos. Também tens acesso direto à estrutura molecular exata através do atributo formula. Os compostos são apenas os materiais estáticos no teu sistema. As enzimas são o que realmente impulsiona as reações. Para as analisares, mudas para a função Enzyme dot parse, passando-lhe um flat file de enzimas do KEGG. Tal como o parser de compostos, faz yield de objetos discretos um a um. Verificas o atributo entry para obteres o número EC standard, e o atributo name para a designação da enzima. Esta é a parte que importa. Uma enzima não opera no vácuo, e o objeto enzima reflete isso através do seu atributo pathway. O parser lê o bloco de texto multi-line que detalha as interações da enzima e estrutura-o numa lista limpa. Cada item dessa lista é um tuple que contém dois pedaços de dados. O primeiro item no tuple é o identificador da pathway do KEGG, e o segundo é o nome human-readable dessa pathway metabólica. Podes fazer um script de um processo de mapeamento completo em apenas alguns passos. Primeiro, abres o teu ficheiro de dados da enzima descarregado e passas o mesmo para a função Enzyme dot parse. Crias um loop para percorrer os records devolvidos. Quando encontrares um record onde o atributo entry corresponda ao número EC da tua enzima mutada, agarras no seu atributo pathway. Podes então iterar sobre essa lista de tuples, extraindo os nomes das pathways para veres imediatamente se a mutação afeta a glicólise, o ciclo do citrato, ou algo completamente diferente. O verdadeiro poder dos parsers do KEGG não é apenas ler texto, mas converter componentes biológicos isolados em coordenadas de rede interligadas, permitindo-te rastrear uma variante genética localizada até uma falha metabólica sistémica. Se achas estes episódios úteis e queres apoiar o programa, podes procurar por DevStoriesEU no Patreon. É tudo por este episódio. Obrigado por ouvires, e continua a programar!
18

Análise de Clusters para Expressão Génica

4m 19s

Agrupe genes pelo seu comportamento. Neste episódio final, abordamos o módulo Bio.Cluster, aplicando K-means e clustering hierárquico a dados de expressão de microarrays.

Download
Olá, daqui fala o Alex da DEV STORIES DOT EU. Fundamentos de Biopython, episódio 18 de 18. Acabaste de correr uma experiência de RNA-seq e agora estás a olhar para uma matriz de expressão com dez mil linhas. Encontrar significado nesses raw data é impossível até agrupares esses genes num pequeno grupo de respostas biológicas distintas. É exatamente isso que a análise de clusters para expressão génica faz, usando o módulo Bio dot Cluster. Quando analisas dados de microarray ou RNA-seq, estás a monitorizar a atividade dos genes em diferentes condições. Imagina um cenário concreto. Tens dados de expressão para mil genes medidos em quatro time points de choque térmico. Queres identificar que genes se comportam de forma semelhante. Talvez cinquenta deles tenham um pico na hora dois e caiam na hora quatro. Genes com padrões semelhantes de up e down regulation partilham frequentemente pathways biológicos ou mecanismos reguladores. Encontrar estes grupos manualmente ao longo de milhares de linhas é para esquecer. O módulo Bio dot Cluster contém um core em C desenhado especificamente para processar este tipo de dados de matriz com eficiência. O teu primeiro passo é importar os dados para o Biopython. Em vez de escreveres lógica de parsing custom, passas o teu ficheiro de texto separado por tabs para a função read do módulo. Isto devolve um objeto Record especializado. Este objeto guarda a tua matriz de expressão numérica, mas também regista os identificadores dos teus genes e os nomes das tuas condições experimentais. Com os dados carregados, aplicas um algoritmo de clustering. A abordagem mais comum é o K-means, executado usando a função kcluster. O K-means divide os teus itens num número predeterminado de grupos, representados pela variável k. Passas a matriz de dados e o teu valor de k escolhido para a função kcluster. A função devolve então um array que atribui cada gene a um cluster ID específico, juntamente com um valor de erro que mede o quão compactos esses clusters estão. Como o algoritmo começa com atribuições aleatórias, normalmente corres o mesmo várias vezes e guardas a iteração que produz o menor erro. Aqui está o insight principal. O algoritmo agrupa os genes com base numa métrica de distância, e tens de escolher essa métrica cuidadosamente. Se usares a distância euclidiana standard, o algoritmo agrupa genes que têm níveis de expressão absolutos semelhantes. Mas se quiseres agrupar genes pela forma da sua curva de expressão ao longo do tempo, independentemente da sua baseline inicial, tens de instruir a função kcluster a usar uma métrica de distância baseada em correlação. O K-means obriga-te a estimar o número de clusters à partida. Se não sabes quantas respostas distintas existem nos teus dados de choque térmico, podes usar hierarchical clustering em alternativa, através da função treecluster. Em vez de forçar os genes a encaixarem-se em buckets planos, a treecluster constrói uma hierarquia. Ela encontra os dois genes com os padrões de expressão mais idênticos e liga-os. A seguir, encontra o próximo gene ou par mais próximo e liga-os, construindo uma estrutura de árvore ramificada chamada dendrograma. Assim que a árvore ligar todos os mil genes, podes observar a estrutura geral dos dados e cortar os ramos a qualquer nível que faça sentido biologicamente. Como este é o episódio final da nossa série Fundamentos de Biopython, recomendo vivamente que abras a documentação oficial do Biopython e experimentes estas funções de clustering num dataset real. Também podes visitar devstories dot eu para sugerir tópicos que queiras ver abordados em futuras séries. O objetivo final de correr estes algoritmos não é apenas organizar números em buckets, mas descobrir a lógica biológica partilhada que força esses genes a ativarem-se em conjunto. Ficamos por aqui neste episódio. Obrigado por ouvires, e continua a desenvolver!