(<-)

[BioPythonTutorial/Introduction]

BioPythonTutorial

[BioPythonTutorial/CookBook]

(->)

Chap.2 Quick Start - Biopython으로 무엇을 할 수 있는가?

2. Quick Start - Biopython으로 무엇을 할 수 있는가

여기서는 Biopython을 쉽게 시작할 수 있도록 Biopython이 어떤 일을 할 수 있고 어떻게 사용하는지 제시할 것이다. 대부분의 예제들을 실행해 보기 위해서는 python을 어느정도는 사용할 수 있어야한며, 여러분의 컴퓨터에 Biopython이 설치되어 있어야한다. python에 대해 더 자세히 알고 싶다면 파이썬 공식 사이트에서 문서를 참고하길 바란다. http://www.python.org/doc

컴퓨터를 사용하는 대부분의 생물학적 일들이 인터넷상의 데이타베이스 연결을 필요로 하므로 예제를 실행하기 위해서는 인터넷이 연결되어 있어야한다.

자.. 그럼 Biopython을 시작해보자.

2.1 Biopython이 제공하는 기능 Overview

Biopython은 생물학자들이 컴퓨터를 사용해서 관심이 있는 일들을 할 때 필요한 라이브러리(함수)들을 모아 놓은 것이다. 즉, Biopython을 사용하기 위해서는 최소한의 프로그래밍 경험(물론 파이썬)이나 프로그래밍을 배우는데 관심이 있어야 한다. Biopython을 사용하면 특정 파일 포맷을 파싱하는데 고생하는 일 없이 실제로 해결해야 할 문제에 집중할 수 있도록 도와 줄 것이다. (현재 존재하지 않는 파서라면 직접 만들어서 Biopython에 공헌하길 바란다.) Biopython을 사용해서 좀 더 즐겁게 일을 하길 바란다.

한가지 언급할 것은 Biopython을 사용해서 한가지 일을 하는데 여러가지 방법이 있을 수 있다. 간혹 이것이 혼란을 야기시킬 수 있지만, 함수들을 좀 더 유연하게 제어할 수 있는 장점이 있다. 이 튜토리얼을 통해 일반적이고 쉬운 사용법을 제시해 줄 것이며, 더 다양하고 자세한 사용법을 익히고 싶으면 Cookbook([BioPythonTutorial/CookBook])이나 Advanced 섹션을 참고하길 바란다.

2.2 서열 조작하기

bioinformatics에서 가장 많이 사용하는 대상은 (당연히) 시퀀스이다. 제일 먼저 Biopython을 사용해서 시퀀스를 다뤄보려고 한다. 기본적으로 생각할 수 있는 'AGTACACTGGT'라는 시퀀스에서 이 시퀀스가 DNA시퀀스인지 단백질 시퀀스인지(Alanines, Glycines, Cysteins, Threonines가 많은 단백질이다.), 어떤 종에서 나온 것인지, 등등 문자열 자체에는 필요한 정보가 부족하다. 그래서 충분한 정보를 담고 있으면서 가볍고 사용하기 편리한 시퀀스가 필요하다.

Biopython에서 시퀀스 클래스는 복잡한 정보를 담고 있으면서 일반적인 파이썬 스트링 객체처럼 사용하기도 편리하다. 시퀀스 클래스는 'Seq'로 표현되며 Bio/Seq.py파일에 정의되어 있다. 자 그럼 시퀀스 클래스를 더 알아보자.

Biopython의 Seq 객체는 두가지 중요한 속성(attribute)을 가지고 있다. :

1. data -- 시퀀스 데이타를 담고 있다.

2. alphabet -- 데이타를 이루고 있는 문자열의 의미를 담고 있다.

alphabet 객체로 인해 시퀀스 객체는 일반적인 스트링보다 의미를 가진다. 사용 가능한 alphabet은 Bio/Alphabet 모듈에 정의되어 있다. 여기서는 DNA, RNA, 단백질을 다루기위해 IUPAC alphabet을 사용할 것이다. (http://www.chem.qmw.ac.uk/iupac)

Bio/Alphabet/IUPAC.py 는 DNA, RNA, 단백질에 대한 정의를 제공해주며 확장이 가능하다. 예를 들어, 단백질에서 기본적인 IUPACProten 클래스도 있지만 'Asx'(asparagine, aspartic acid), 'Sec'(selenocystein), 'Glx'(glutanime) 같은 추가적인 요소들도 지원하는 ExtendedIUPACProtein도 있다. DNA에서는 IUPACUnambiguousDNA, IUPACAmbiguousDNA, ExtendedIUPACDNA에서 선택할 수 있다.

alphabet을 통해서 데이타 객체가 담고 있는 정보의 종류를 알 수 있고 데이타 타입도 점검할 수 있다.

이제 시퀀스 클래스를 사용하는 방법을 알아보자.

우선 우리가 가지고 있는 정보를 시퀀스 객체로 만들자. 여기서는 unambiougous DNA 객체를 사용한다.

>>> from Bio.Alphabet import IUPAC
>>> my_alpha = IUPAC.unambiguous_dna
>>> from Bio.Seq import Seq
>>> my_seq = Seq('GATCGATGGGCCTATATAGGATCGAAAATCGC', my_alpha)
>>> print my_seq
Seq('GATCGATGGGCCTATATAGGATCGAAAATCGC', IUPACUnambiguousDNA())

시퀀스 객체는 일반적인 파이썬 스트링 객체처럼 사용할 수 있다. 부분 시퀀스를 구해보자.

>>> my_seq[4:12]
Seq('GATGGGCC', IUPACUnambiguousDNA())

파이썬 스트링의 '슬라이스'가 이해가 되지 않는다면 파이썬 튜토리얼을 참고하길 바란다. 슬라이스를 통해 시퀀스를 담고 있는 데이타만 스라이스되는 것에 주목하자. alphabet 정보는 남아 있다.

시퀀스 객체를 스트링처럼 사용하는 다른 방법들이다.

>>> len(my_seq)
32
>>> new_seq = my_seq[0:5]
>>> print new_seq
Seq('GATCG', IUPACUnambiguousDNA())
>>> my_seq + new_seq
Seq('GATCGATGGGCCTATATAGGATCGAAAATCGCGATCG', IUPACUnambiguousDNA())
>>> my_seq[5]
'A'
>>> my_seq == new_seq
0

여기서도 alphabet 정보는 계속 남아 있다. alphabet 정보는 혹시라도 생길 실수(DNA정보와 단백질 정보를 더하는)를 막아준다.

>>> protein_seq = Seq('EVRNAK', IUPAC.protein)
>>> dna_seq = Seq('ACGT', IUPAC.unambiguous_dna)
>>> protein_seq + dna_seq
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/local/lib/python1.6/site-packages/Bio/Seq.py", line 42, in __add__
    raise TypeError, ("incompatable alphabets", str(self.alphabet),
TypeError: ('incompatable alphabets', 'IUPACProtein()', 'IUPACUnambiguousDNA()')

만약 스트링 정보만을 쓰길 원한다면 추출하기는 쉽다.

>>> my_seq.tostring()
'GATCGATGGGCCTATATAGGATCGAAAATCGC'

대부분의 생물학적 도구에서 여러분의 데이타가 바뀌는 것을 원하지 않기에 기본적으로 시퀀스 객체는 변형이 불가능하다.

>>> my_seq[5] = 'G'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'Seq' instance has no attribute '__setitem__'

하지만 변형이 가능한 시퀀스로 바꿀 수 있다.

>>> mutable_seq = my_seq.tomutable()
>>> print mutable_seq
MutableSeq('GATCGATGGGCCTATATAGGATCGAAAATCGC', IUPACUnambiguousDNA())
>>> mutable_seq[5] = 'T'
>>> print mutable_seq
MutableSeq('GATCGTTGGGCCTATATAGGATCGAAAATCGC', IUPACUnambiguousDNA())
>>> mutable_seq.remove('T')
>>> print mutable_seq
MutableSeq('GACGTTGGGCCTATATAGGATCGAAAATCGC', IUPACUnambiguousDNA())
>>> mutable_seq.reverse()
>>> print mutable_seq
MutableSeq('CGCTAAAAGCTAGGATATATCCGGGTTGCAG', IUPACUnambiguousDNA())

이제 시퀀스 객체에 대한 감각은 대충 익혔을 것이다. 다음엔 이 시퀀스 객체를 사용해서 뭔가를 해보자. Bio/Tools 디렉토리에는 시퀀스 객체를 Transcribe 하고 Translate 할 수 있는 유용한 모듈이 있다. 이들 도구는 시퀀스의 alphabet을 기반으로 작동한다. 그럼 my_seq객체를 Transcribe 해보자. 기억해야 할 점은 우리는 unambiguous alphabet을 사용하므로 transcribe도 다음처럼 해야한다.

>>> from Bio.Tools import Transcribe
>>> transcriber = Transcribe.unambiguous_transcriber
>>> my_rna_seq = transcriber.transcribe(my_seq)
>>> print my_rna_seq
Seq('GAUCGAUGGGCCUAUAUAGGAUCGAAAAUCGC', IUPACUnambiguousRNA())

RNA 시퀀스가 구해졌다. RNA 시퀀스 객체도 일반적인 스트링처럼 다루기가 쉽다. RNA 시퀀스를 다시 되돌릴 수도 있다. (reverse transcribe)

>>> transcriber.back_transcribe(my_rna_seq)
Seq('GATCGATGGGCCTATATAGGATCGAAAATCGC', IUPACUnambiguousDNA())

DNA 객체를 Translate하기 위해서는 몇가지 선택이 필요하다, DNA 시퀀스에 관한 Translation 테이블을 여러개 사용할 수가 있는데, Biopython 에서 쓰이는 Translation 테이블은 ftp://ncbi.nlm.nih.gov/entrez/misc/data/gc.prt 에서 가져온 것이다. 여러가지 선택권이 있지만 여기서는 두가지(Standard Translation Table, Vertebrate Mitochondriall DNA Translation Table)를 선택해보자. 각각의 테이블은 ID 1과 2로 표시된다. 이제 우리가 원하는 테이블을 정했고, 기본적인 Translation을 할 준비가 되었다. 먼저 선택한 테이블을 사용하는 Translator가 필요하다. unambiguous DNA를 사용하므로 Translator에도 적용되어야 한다.

>>> from Bio.Tools import Translate
>>> standard_translator = Translate.unambiguous_dna_by_id[1]
>>> mito_translator = Translate.unambiguous_dna_by_id[2]

Translator를 만든 다음, 시퀀스를 Translate해보자.

>>> my_seq = Seq('GCCATTGTAATGGGCCGCTGAAAGGGTGCCCGA', IUPAC.unambiguous_dna)
>>> standard_translator.translate(my_seq)
Seq('AIVMGR*KGAR', IUPACProtein())
>>> mito_translator.translate(my_seq)
Seq('AIVMGRWKGAR', IUPACProtein())

여기서 알아둘 점은 기본적으로 정지 코돈(stop codon)을 무시한채 Translation 한다는 것이다. 만약 [ORF]를 알고 있고, 정지 코돈까지의 결과를 알고 싶다면 translation_to_stop함수를 쓰면 된다.

>>> standard_translator.translate_to_stop(my_seq)
Seq('AIVMGR', IUPACProtein())

Transcriber처럼 단백질을 DNA 시퀀스로도 Translate 가능하다.

>>> my_protein = Seq('AVMGRWKGGRAAG', IUPAC.protein)
>>> standard_translator.back_translate(my_protein)
Seq('GCTGTTATGGGTCGTTGGAAGGGTGGTCGTGCTGCTGGT', IUPACUnambiguousDNA())

여기서는 Biopython에서 시퀀스 클래스를 사용하는 기본적인 방법들을 알아봤다. Advanced 튜토리얼에서는 시퀀스 클래스에 관한 더 자세한 설명이 있다. 아직 시퀀스 클래스는 개발중이며 여러분의 참여를 환영한다. 이제 Biopython 함수들을 사용하는 감각을 익혔을 것이다. 다음엔 생물학 데이타 파일을 가지고 놀아보자..

2.3 활용예제

다음으로 가기 전에 흥미있는 예제를 하나 준비해보자. 이 튜토리얼에 생물학이 관련된 내용이 없다면 읽을 필요도 없을 것이다.

개인적으로 식물을 좋아하기에 식물에 관련된 예제를 마련하려고 한다. ( 다른 생물을 좋아하는 사람에겐 미안하다.) 우리의 온실에선 Lady Slipper Orchids를 키우고 있다. (난초, 어떤 식물인지 알고 싶다면http://www.millicentorchids.com/greenhouse/images/의 papesq01.jpg 와 http://www.millicentorchids.com/greenhouse/indexphoto.htm를

  • 참고하기 바란다.) 난초는 보기에도 이쁘지만, 진화와 계통학을 공부하는 사람에게 큰 관심 대상이기도 하다. Lady Slipper 의 진화에 대한 분자생물학적 연구를 하고 어떤 것들이 연구되고 어떤 일을 추가로 할 수 있는지를 알아보려고 한다.

DeleteMe : 위 링크가 깨져있습니다.

  • 더 읽어보면 알겠지만 Lady Slipper Orchids는 Orchidaceae family와 Cypripedioideae sub-family에 속해 있고, 5가지 genera(속)으로 이뤄져있다.(Cypripedium, Paphiopedilum, Phragmipedium, Selenipedium, Mexipedium.) 이 정도면 탐구를 시작하기엔 충분한 정보가 될 것이다. 자. Biopython이 어떻게 우리에게 도움을 줄지 살펴보자.

2.4 생물학적 FlatFile 포맷 파싱

Bioinformatics의 많은 일들이 생물학 데이타를 담고 있는 여러 파일 포맷을 다루는데 있다. 이 파일에서 생물학 데이타를 뽑아서 분석하고 다른 포맷으로 변환하여 프로그래밍 언어로 쉽게 다룰 수 있어야 한다. 하지만 데이타 포맷이 자주 바뀌고 파서에 의해 쉽게 변형될 민감한 부분을 가질 수 있기에 파일 포맷을 분석하는 일은 힘이 든다.

2.4.1 일반적인 파서 디자인

Biopython은 모든 파서간에 연동이 될 수 있도록 구조화된 파서 프레임웍을 개발하는데 목적을 두고 있다. 크게 두가지 장점이 있는데, 첫째로 재사용이 가능한 코드를 가질 수 있고(Bio/ParserSupport.py를 참고), 둘째로 유사한 프레임웍을 통해서 파서간에 유연성을 제공하고 여러분이 풀어야 할 문제를 찾기 쉽게 해주다.

모든 파서는 두가지 컴포넌트를 가지고 있다.:

  1. Scanner - 실제적으로 파일에서 유용한 정보를 추출하는 주된 일을 하는 부분이다. 유용한 정보는 이벤트(Events)로 변환된다.
  2. Consumer - consumer 는 유용한 정보를 프로그래머가 사용하기 쉽도록 ina 포맷으로 분리해 준다. 이 일은 scanner에서 생성된 이벤트를 이용한다.

즉, 파서는 이벤트 지향적으로 설계가 되었다. 일반적으로 Scanner는 파일에서 관심 대상이 되는 각각의 아이템마다 이벤트를 만든다. 예를 들어 다음과 같은 FASTA 포맷의 데이타를 가졌다고 하자. (페이지에 맞게 수정되었다.)

>gi|6273290|gb|AF191664.1|AF191664 Opuntia clavata rpl16 gene; chloroplast gene for...
TATACATTAAAGGAGGGGGATGCGGATAAATGGAAAGGCGAAAGAAAGAAAAAAATGAA
TCTAAATGATATAGGATTCCACTATGTAAGGTCTTTGAATCATATCATAAAAGACAATGTAAT
AAA...

스캐너가 위의 데이타를 지나가면서 다음과 같은 이벤트를 생성한다.

  Event Name                                                     Entry input
----------------------------------------------------------------
begin_sequence                           (as soon as we notice we've got a new >)
         title                     >gi|6273290|gb|AF191664.1|AF191664 Opuntia clavata...
    sequence                               TATACATTAAAGGAGGGGGATGCGGAT...
    sequence                              TCTAAATGATATAGGATTCCACTATGTAA...
    sequence                              AAA... (and so on -- you've got the idea!)
 end_sequence            (as soon as we reach a blank line after the sequence data)

이벤트가 생성되었다. 이 이벤트를 가지고 뭔가 흥미있는 일을 한다면 좋을 것이다. 바로 이것을 consumer가 해준다. consumer를 쓸려면 두가지 작업이 필요하다.

  1. 스캐너와 함께 스캐너에서 생성된 이벤트를 받는 consumer를 등록해야 한다.
  2. (그와 관련된 정보를 포함해서)이벤트를 이용해 작업을 한다.

더 자세한 예제를 들어보겠다.

2.4.2 당신만의 consumer 만들기

이제 파서 프레임웍을 이해 할 순서다. 우리의 친구 'lady slipper orchids(난초)'도 만나 볼 것이다. 검색을 시작하기 전에 NCBI의 뉴클레오티드 데이타베이스에서 Entrez를 통해 'Cypripedioideae(lady slipper orchids의 subfamily이다.)'와 관련된 텍스트를 검색해보자. (http://www.ncbi.nlm.nih.gov:80/entrez/query.fcgi?db=Nucleotide) 대략 94개의 검색 결과를 확인 할 수 있으며 FASTA포맷의 텍스트 파일로 저장을 하자. ( 20010913 현재 약 216개의 결과가 나온다. )

DeleteMe 원본에서는 틀린 문자열이 있어서 NCBI 링크가 작동하지 않았다.

이제 우리가 구한 정보를 파서를 이용해 정리해보자. 간단한 예로 데이타에서 개체(organism) 이름을 검색해서 서로 다른 종의 lady slipper orchids가 얼마나 있는지 알아보자.

좀 제대로 된 일을 해보려면, 약간의 수고를 들여 consumer를 작성해야 한다. 다음은 개체(organisms) 이름을 추출하는 consumer의 모습이다.

import string
from Bio.ParserSupport import AbstractConsumer

class SpeciesExtractor(AbstractConsumer):

    def __init__(self):
        self.species_list = []

    def title(self, title_info):
        title_atoms = string.split(title_info)
        new_species = title_atoms[1]

        if new_species not in self.species_list:
            self.species_list.append(new_species)

첫번째로 해야 할 일은 Consumers가 상속받을 기본 클래스인 AbstractConsumer를 불러오는 것이다. 이것은 우리가 크게 신경을 쓰지 않는 것까지도 처리해주는 유용한 클래스이다. 기본 클래스인 AbstractConsumer에서 상속받아 우리만의 consumer를 만들게 된다.

다른 파이썬 클래스처럼, 클래스의 인스턴스가 생성될 때 호출을 하게되는 init 함수를 정의했다. 초기화 과정에서 species_list 클래스 속성(attribute)을 마련했다. 이것은 파일을 파싱하면서 종(species)의 정보를 저장하게 될 것이고, 후에 우리는 여기서 정보를 추출할 것이다.

이제 'title'이라는 멋진 함수를 알아보자. 이 함수는 Scanner에서 'title' 이벤트가 생성될 때마다 호출될 것이다. 그래서 Scanner가 다음 FASTA 파일 예제의 첫 줄을 만나게 되면:

>gi|2765658|emb|Z78533.1|CIZ78533 C.irapeanum 5.8S rRNA gene and ITS1 and ITS2 DNA

이것을 제목(title)으로 인식하고, 제목 값을 title_info argument에 저장한 title 함수를 호출하게 된다.

이것으로 제목(title)을 획득했고, 여기서 우리가 원하는 정보를 추출하려고 한다. FASTA title info를 보면 문자열의 두번째 아이템이 개체의 이름임을 알 수 있다. 이것을 추출하려면 파이썬 내장 함수인 string.split을 사용해 매 스페이스마다 분리해서 title_atoms라는 리스트를 생성한다. 리스트의 두번째 요소가 종의 이름이므로 이것을 추출하면 된다. 그다음은 간단히 이 종의 이름이 기존 species_list에 존재하는지 검사해보고, 아니면 리스트에 추가하면 된다.

여기까지는 충분히 쉬웠을 것이다. 이제는 Scanner를 호출해서 실제 일을 해보자. 그러기 위해선 간단한 함수를 작성해야 한다.

from Bio import Fasta

def extract_organisms(file, num_records):
    scanner = Fasta._Scanner()
    consumer = SpeciesExtractor()

    file_to_parse = open(file, 'r')

    for fasta_record in range(num_records):
        scanner.feed(file_to_parse, consumer)

    file_to_parse.close()

    return handler.species_list

단계별로 함수를 알아보자. 처음으로 Biopython 라이브러리에서 Fasta 파서를 불러들이고 그다음 우리가 쓸 함수를 정의했다. 이 함수는 '파싱할 FASTA 포맷의 파일'과 '파일의 레코드 수', 이렇게 두개의 인수(argument)를 갖는다. 그리고 FASTA 파일을 스캐닝할 Scanner와 모든 개체(organism)을 추출할 SpeciesExtractor consumer를 생성한다.

파싱할 파일을 열고 정보를 추출할 준비가 되었다. Biopython으 모든 파서는 파일 핸들을 입력값으로 받는다. 즉, 여러분은 어떤 종류든지 파일 타입 의 객체를 파서로 보낼 수가 있다. 예를 들어, url 라이브러리는 외부 URL에 있는 문서를 마치 로컬에 있는 파일처럼 작업할 수 있게 하는데, 이것을 이용해 인터넷 어딘가에 있는 문서를 파서로 보낼 수가 있다.

이제 열린 파일을 가졌고, 파싱할 차례다. 파서의 작업 방식은 여러분이 파싱을 원하는 파일 내의 아이템을 위해 feed 함수를 호출하고, 이것을 파일 타입의 객체로 파서에 보내고, consumer를 호출하는 식이다. 그러므로 우리는 모든 레코드에 대해 루프(loop)를 돌려 스캔을 하고, consumer로 넘긴다. 마침내 모든 것이 끝나면, 우리는 모든 정보를 담고 있는 species_list를 consumer의 속성으로 갖게 된다.

휴~, 모든 작업이 끝났다. 파일을 파싱하는 일은 쉬운 일이다. :)

all_species = extract_organisms("ls_orchid.fasta", 94)
print "number of species:", len(all_species)
print 'species names:', all_species

Running this all as one big program (the program is available as fasta_consumer.py in the Doc/examples directory) give us the information we desire:


[chapmanb@taxus examples]# python fasta_consumer.py
number of species: 92
species names: ['C.irapeanum', 'C.californicum', 'C.fasciculatum', 
'C.margaritaceum', 'C.lichiangense', 'C.yatabeanum', 'C.guttatum',
...

2.4.3 보다 더 쉽게 하기

마지막 세션에서 특별한 consumer를 작성하기 위한 핵심 사항을 모두 설명했다. 자신의 consumer를 작성할 수 있다는 유연성은 정말 멋진 것이지만, 많은 애플리케이션에서는 필요 이상의 것이다. 간단한 애플리케이션 작성을 위해 Biopython에선 모든 기능의 파서처럼 행동하는 유용한 클래스를 제공한다. 이 클래스는 대충 간단한 애플리케이션을 만들려는 여러분이 찾는 것이다. 우리가 이 파서를 이용하는데 있어서 생기는 하나의 큰 문제는 화일에 저장되어 있는 elements의 갯수를 미리 알고 있어야 하는 것이다. 이 것을 이용해 단순히 화일을 우리가 무엇인가를 찾기위해 모든 application을 파서하는 것은 비현실적인 일이다. 이런 문제를 다루기 위해서 우리는 FASTA화일에 대해서 Iterator interface를 이용할 수 있다. 이 interface는 당신이 consumer와 scanner에 대해서 고려하지 않아도 한번에 jazz나 행군을 하는 것과 같이 화일을 record에 저장하게 해준다. 그러나, 이 방법은 당신이 원하는 정보를 뽑아낼 수 있게 해주는 object를 Iterator로 return하는 것이 필요하다. 이런 문제를 다루기 위해서, 많은 Biopython parsers로 아주 유용한 class가 쓰여졌다. - 그것은 RecordParser로써 화일의 내용을 python class로 파서한다. 예를들어, FASTA 화일인 경우 Record Class의 object는 title과 sequence로 구성되어 있다. Iterator과 Record interface를 사용하여 앞서 말한 내용을 좀더 깊게 공부해 보자. -FASTA 화일에서 모근 종에대한 unique list를 뽑아보자. 먼저 우리는 parser와 iterator를 설정해 줄 필요가 있다.

>>> from Bio import Fasta
>>> parser = Fasta.RecordParser()
>>> file = open("ls_orchid.fasta")
>>> iterator = Fasta.Iterator(file, parser)

처음, 우리는 parser를 만들었다. = RecordParser는 FASTA entry를 파서하여 그 내용을 record class안에 넣을 수 있게 한다. 그리고 우리는 화일을 열고, iterator를 만들었다. 이제 파싱을 시작할 준비가 다 끝났다. 다른 iterator과 parser같이, 우리는 next() 함수를 불러서 object를 검색해야된다. 파싱을 할 남아있는 sequence가 없으면 next()는 None을 return하고 그것을 이용해서 파싱을 멈출시간을 알 수 있다. 첫번째 record를 얻기 위해:

>>> cur_record = iterator.next()

이제 record object를 보면 우리가 쉽게 얻을 수 있는 sequence와 title을 가지고 있는것을 알 수 있다.

>>> dir(cur_record)
['_colwidth', 'sequence', 'title']
>>> print cur_record.title
gi|2765658|emb|Z78533.1|CIZ78533 C.irapeanum 5.8S rRNA gene and ITS1 and ITS2 DN
>>> print cur_record.sequence
CGTAACAAGGTTTCCGTAGGTGAACCTGCGGAAGGATCATTGATGAGACCGTGGAATAAACGATCGAGTGAATCCGGA
...

내 생각에 가장 중요한 것은 얼마나 쉽게 FASTA record를 얻느냐하는 것이다.

>>> print cur_record
>gi|2765658|emb|Z78533.1|CIZ78533 C.irapeanum 5.8S rRNA gene and ITS1 and ITS2 DNA
CGTAACAAGGTTTCCGTAGGTGAACCTGCGGAAGGATCATTGATGAGACCGTGGAATAAA
CGATCGAGTGAATCCGGAGGACCGGTGTACTCAGCTCACCGGGGGCATTGCTCCCGTGGT
GACCCTGATTTGTTGTTGGGCCGCCTCGGGAGCGTCCATGGCGGGTTTGAACCTCTAGCC
CGGCGCAGTTTGGGCGCCAAGCCATATGAAAGCATCACCGGCGAATGGCATTGTCTTCCC
CAAAACCCGGAGCGGCGGCGTGCTGTCGCGTGCCCAATGAATTTTGATGACTCTCGCAAA
CGGGAATCTTGGCTCTTTGCATCGGATGGAAGGACGCAGCGAAATGCGATAAGTGGTGTG
AATTGCAAGATCCCGTGAACCATCGAGTCTTTTGAACGCAAGTTGCGCCCGAGGCCATCA
GGCTAAGGGCACGCCTGCTTGGGCGTCGCGCTTCGTCTCTCTCCTGCCAATGCTTGCCCG
GCATACAGCCAGGCCGGCGTGGTGCGGATGTGAAAGATTGGCCCCTTGTGCCTAGGTGCG
GCGGGTCCAAGAGCTGGTGTTTTGATGGCCCGGAACCCGGCAAGAGGTGGACGGATGCTG
GCAGCAGCTGCCGTGCGAATCCCCCATGTTGTCGTGCTTGTCGGACAGGCAGGAGAACCC
TTCCGAACCCCAATGGAGGGCGGTTGACCGCCATTCGGATGTGACCCCAGGTCAGGCGGG
GGCACCCGCTGAGTTTACGC

이제까지의 모든것을 이용하여 다음같은 extract_organisms이란 함수를 만들 수 있다.

def extract_organisms(file_to_parse):

   parser = Fasta.RecordParser()
   file = open(file_to_parse, 'r')
   iterator = Fasta.Iterator(file, parser)

   all_species = []

   while 1:
      cur_record = iterator.next()


      if cur_record is None:
         break

      # extract the info from the title
      title_atoms = string.split(cur_record.title)
      new_species = title_atoms[1]

      # append the new species to the list if it isn't there
      if new_species not in all_species:
         all_species.append(new_species)

return all_species

이 함수를 실행하면 이전에 봤던 것과 똑같은 결과를 얻을 수 있다. 이런 interface를 이용하든지 이전에 설명한 사용자의 필요에 의해, 사용자가 더 편하게 느낄 수 있는 방법(your own consumer)을 쓰든지 선택하든지 마찬가지 결과를 얻는다. Perl만이 일을 하는데 한가지 이상의 방법을 쓰는 것은 아니다!

2.4.4 사전형태로의 FASTA 화일

난초(orcid)의 fasta file을 가지고 할 우리의 마지막일은 실제 데이타베이스와 같이 어떻게 index하고 access하는지 보여주는 일이다. 이것은 큰 화일 안에서 한 element를 빠르게 접근 해야할때 아주 유용하다. 자료를 찾기 쉽게 하기위해 GenBank accession number를 가지고 우리의 자료를 index해보자. 이를 하기 위해서 우리는 먼저 FASTA record로 부터 accession number를 되돌려주는 간단한 함수를 작성해야된다. (이 Record class에 대해서는 이전에 얘기하였다.)

import string

def get_accession_num(fasta_record):
        title_atoms = string.split(fasta_record.title)

        # all of the accession number information is stuck in the first element
        # and separated by '|'s
        accession_atoms = string.split(title_atoms[0], '|')

        # the accession numbet is the 4th element
        gb_name = accession_atoms[3]

        # strip the version info before returning
        return gb_name[:-2]

이제 이 화일에서 index를 만들 필요가있다.?? 화일을 색인하는 일반적인 형식은:

index_file( file_to_index, index_file_to_create, function_to_get_index_key )

가장 중요한 변수는 function_to_get_index_key이다. 기본적으로 이것은 키로사용되는 element를 얻을수 있는 함수를 가르킨다.

2.4.5 나는 파싱을 사랑한다! 여기서 멈추지 말라

바이오파이선은 많은 파서를 가지고 있고 그 각각은 시퀀스포맷에 대한 자신만의 역할을 한다. 특정한 파서에 대한 정보를 얻을수 있는 가장좋은 장소와 파서를 가지고 할 수 있는 멋진일들은 이 튜토리얼의 Cookbook 섹션에 적혀있다. 만약 정보를 찾지 못한다면, 중복되는 일에서 구출할 수 있도록 cookbook entry에 제출하여라. (당신이 해결한 바로 그 방법을!)

2.5 생물학 데이타베이스에 연결하기

당신이 바이오인포메틱스에서 해야될 가장 기본적인 일중의 하나가 바로 생물학 데이타베이스에서 정보를 뽑아내는 일이다. 이런 데이타 베이스에서 메뉴얼대로 정보에 접근한다면 그것을 좀 지루한 일이 될 것이다. 특히 당신이 해야될 반복적인 일이 많다면 더욱 그렇다. Biopython은 당신의 시간과 에너지를 절약하기 위해 pyhon script가 가능한 on-line 데이타베이스를 만드는 것을 시도한다. 현재 Biopython을 다음 데이타베이스에서 정보를 뽑아 낼 수 있는 코드를 가지고 있다.

ExPASy - http://www.expasy.ch/ Cookbook의 섹션3.2에서 좀더 자세한 정보를 얻을 수 있다.
Entrez from NCBI - http://www.ncbi.nlm.nih.gov/Entrez
PubMed from NCBI - http://www.ncbi.nlm.nih.gov/PubMed/. CookBook의 섹션3.3에서 이것을 이용할 수 있는 예제 코드를 볼 수 있다.
SCOP - http://scop.mrc-lmb.cam.ac.uk/scop

그 코드들은 이런 페이지에서 CGI-script와 상호작용할수 있는 쉽게 쓰여질 수 있는 파이선 코드들로 이루어진 모듈들이다. 그러므로 당신은 쉽게 특정 형식에 맞게 결과를 얻을 수 있다. 어떤 경우는 그 결과가 파이선 파서와 완전 호환되어 더욱 정보를 뽑아내기 쉬울 수도 있다.

여기에 remote [Entrez] query에 대한 예제를 보인다. 더욱 자세한 정보는 20페이지부터 Cookbook을 보기바란다.

2.6 다음에 할일

BioPythonTutorial/QuickStart (last edited 2011-08-03 11:00:50 by localhost)

web biohackers.net